Click here to Skip to main content
13,150,178 members (60,106 online)
Click here to Skip to main content
Add your own
alternative version

Stats

94.5K views
190 bookmarked
Posted 7 Sep 2015

Top 15 Underutilized Features of .NET Part 2

, 25 Feb 2016
Rate this:
Please Sign up or sign in to vote.
List of my favorite underutilized features of .NET. Contains full explanation what they are doing illustrated by C# code examples.

Introduction

In this article, I’m going to share with you even more hidden features of C# language (underutilized). If you missed the first publication you should check it- Top 15 Underutilized Features of .NET

After so many comments about the previous title of the article -  "Top 15 Hidden Features of C#", I decided to change it to the current one. Thank you all for the suggestions. My initial intent was not to mislead you. The original idea about the article came up from a Stack Overflow discussion with a similar title, so I decided not to change it because people were already familiar with the topic. But for the sake of all past and future critics I am changing the title.

You could share your most preferred but not so well known parts of .NET in the comments. I will include them in the future next part of the series. Also, you can vote in the poll that can be found at the end of the article for your most favorite “underutilized/oft-forgotten/arcane/hidden” feature of C#.

Contents

1. dynamic Keyword
2. ExpandoObject
3. Nullable<T>.GetValueOrDefault Method
4. ZipFile in .NET
5. C# Preprocessor Directives
6. StackAlloc
7. Execute VB code via C#
8. volatile  Keyword
9. global::
10. DebuggerDisplayAttribute
11. DebuggerStepThroughAttribute
12. Conditional
13. using Directive VS 2015
14. Flags Enum Attribute
15. Dynamically Compile and Execute C# Code

Underutilized Features of .NET

1. dynamic Type

The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run-time.

Note: Type dynamic behaves like type object in most circumstances. However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler. The compiler packages together information about the process, and that information is later used to evaluate the operation at run-time. As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile-time, not at run-time.

dynamic dynamicVariable;
int i = 20;
dynamicVariable = (dynamic)i;
Console.WriteLine(dynamicVariable);

string stringVariable = "Example string.";
dynamicVariable = (dynamic)stringVariable;
Console.WriteLine(dynamicVariable);

DateTime dateTimeVariable = DateTime.Today;
dynamicVariable = (dynamic)dateTimeVariable;
Console.WriteLine(dynamicVariable);

// The expression returns true unless dynamicVariable has the value null. 
if (dynamicVariable is dynamic)
{
    Console.WriteLine("d variable is dynamic");
}

// dynamic and the as operator.
dynamicVariable = i as dynamic;

// throw RuntimeBinderException if the associated object doesn't have the specified method.
// The code is still compiling successfully.
Console.WriteLine(dynamicVariable.ToNow1);

As you can see from the examples, you can assign variables from different types to a single dynamic object. You can check if a variable is of type dynamic using the ‘is’ operator. If a requested property is non-existing as on the last line of the example, a new RuntimeBinderException is thrown.

Official documentationhttps://msdn.microsoft.com/en-us/library/dd264741.aspx

2. ExpandoObject

Represents an object whose members can be dynamically added and removed at run-time. This is one of my favorite underutilized features of C#.

dynamic samplefootballLegendObject = new ExpandoObject();

samplefootballLegendObject.FirstName = "Joro";
samplefootballLegendObject.LastName = "Beckham-a";
samplefootballLegendObject.Team = "Loko Mezdra";
samplefootballLegendObject.Salary = 380.5m;
samplefootballLegendObject.AsString = new Action(
            () =>
            Console.WriteLine("{0} {1} {2} {3}",
            samplefootballLegendObject.FirstName,
            samplefootballLegendObject.LastName,
            samplefootballLegendObject.Team,
            samplefootballLegendObject.Salary)
            );

You can not only add properties to the expando objects, but you can also add methods and delegates. In the example, I have added new AsString method through a new Action.

Official documentationhttps://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v=vs.110).aspx

3. Nullable<T>.GetValueOrDefault Method

Retrieves the value of the current Nullable<T> object, or the object’s default value. It is faster than ?? operator.

There was a debate about which is faster null coalescing operator ?? or GetValueOrDefault method. As a result I did my research, you can find it here.

float? yourSingle = -1.0f;
Console.WriteLine(yourSingle.GetValueOrDefault());
yourSingle = null;
Console.WriteLine(yourSingle.GetValueOrDefault());
// assign different default value
Console.WriteLine(yourSingle.GetValueOrDefault(-2.4f));
// returns the same result as the above statement
Console.WriteLine(yourSingle ?? -2.4f);

If you don’t specify a default value as a parameter to the method, the default value of the used type is going to be used.

You can use it to create a dictionary safe Get method (return the default value if the key is not present instead of throwing an exception).

public static class DictionaryExtensions
{
    public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key)
    {
        TValue result;
        return dic.TryGetValue(key, out result) ? result : default(TValue);
    }
}

The usage is straightforward.

Dictionary<int, string> names = new Dictionary<int, string>();
names.Add(0, "Willy");
Console.WriteLine(names.GetValueOrDefault(1));

Official documentation– https://msdn.microsoft.com/en-us/library/72cec0e0(v=vs.110).aspx

4. ZipFile in .NET

Provides static methods for creating, extracting, and opening zip archives.

string startPath = Path.Combine(string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "\\Start"));
string resultPath = Path.Combine(string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "\\Result"));
Directory.CreateDirectory(startPath);
Directory.CreateDirectory(resultPath);
string zipPath = Path.Combine(string.Concat(resultPath, "\\", Guid.NewGuid().ToString(), ".zip"));
string extractPath = Path.Combine(string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "\\Extract"));
Directory.CreateDirectory(extractPath);

ZipFile.CreateFromDirectory(startPath, zipPath);

ZipFile.ExtractToDirectory(zipPath, extractPath);

Official documentation– https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile(v=vs.110).aspx

C# Preprocessor Directives

5. C# Preprocessor Directives

5.1. #warning

#warning lets you generate a level one warning from a particular location in your code.

#if LIVE
#warning A day without sunshine is like, you know, night.
#endif
 
Warning Preprocessor Directive

Official documentation– https://msdn.microsoft.com/en-us/library/963th5x3.aspx

5.2. #error

#error allows you to make an error from a particular location in your program.

#error Deprecated code in this method.
 
Error Preprocessor Directive

Official documentation– https://msdn.microsoft.com/en-us/library/x5hedts0.aspx

5.3. #line

#line lets you modify the compiler’s line number and (optionally) the file name output for errors and warnings.

#line 100 "Pandiculation"
            int i;    // CS0168 on line 101
            int j;    // CS0168 on line 102
#line default
            char c;   // CS0168 on line 288
            float f;  // CS0168 on line 289
 
Line Preprocessor Directive

Official documentation– https://msdn.microsoft.com/en-us/library/34dk387t.aspx

5.4. #region

#region enables you to specify a block of code that you can expand or collapse when using the outlining feature of the Visual Studio Code Editor.

#region Thomas Sowell Quote
Console.WriteLine("It takes considerable knowledge just to realize the extent of your own ignorance.");
#endregion
 
Region Preprocessor Directive

Official documentation– https://msdn.microsoft.com/en-us/library/9a1ybwek.aspx

6.  Stackalloc

The stackalloc keyword is used in an unsafe code context to allocate a block of memory on the stack.

The following example calculates and displays the first 20 numbers in the Fibonacci sequence. Each number is the sum of the previous two numbers. In the code, a block of memory of sufficient size to contain 20 elements of type int is allocated on the stack, not the heap. The address of the block is stored in the pointer fib. This memory is not subject to garbage collection. Therefore, it does not have to be pinned (by using fixed). The lifetime of the memory block is limited to the life of the method that defines it. You cannot free the memory before the method returns.

static unsafe void Fibonacci()
{
    const int arraySize = 20;
    int* fib = stackalloc int[arraySize];
    int* p = fib;
    *p++ = *p++ = 1;
    for (int i = 2; i < arraySize; ++i, ++p)
    {
        *p = p[-1] + p[-2];
    }
    for (int i = 0; i < arraySize; ++i)
    {
        Console.WriteLine(fib[i]);
    }
}

The sole reason to use stackalloc is performance (either for computations or interop). By using stackalloc instead of a heap allocated array, you create less GC pressure (the GC needs to run less). You don’t need to pin the arrays down, it’s faster to allocate than a heap array.

For more information about the unsafe code, see Unsafe Code and Pointers (C# Programming Guide).

To set this compiler option in the Visual Studio development environment

  1. Open the project’s Properties page.
  2. Click the Build property page.
  3. Select the Allow Unsafe Code check box.

Allow Unsafe Code

Official documentation– https://msdn.microsoft.com/en-us/library/cx9s2sy4.aspx

7. Execute VB code via C#

Generates and calls Office Visual Basic macros from a C# .NET Automation client.

I used it in the past to fetch and display data from Google Analytics in Excel.

private static string GetMacro(int macroId, int row, int endCol)
{
    StringBuilder sb = new StringBuilder();
    string range = "ActiveSheet.Range(Cells(" + row + "," + 3 +
        "), Cells(" + row + "," + (endCol + 3) + ")).Select";
    sb.AppendLine("Sub Macro" + macroId + "()");
    sb.AppendLine("On Error Resume Next");
    sb.AppendLine(range);
    sb.AppendLine("ActiveSheet.Shapes.AddChart.Select");
    sb.AppendLine("ActiveChart.ChartType = xlLine");
    sb.AppendLine("ActiveChart.SetSourceData Source:=" + range);
    sb.AppendLine("On Error GoTo 0");
    sb.AppendLine("End Sub");

    return sb.ToString();
}

private static void AddChartButton(MSExcel.Workbook workBook, MSExcel.Worksheet xlWorkSheetNew,
    MSExcel.Range currentRange, int macroId, int currentRow, int endCol, string buttonImagePath)
{
    MSExcel.Range cell = currentRange.Next;
    var width = cell.Width;
    var height = 15;
    var left = cell.Left;
    var top = Math.Max(cell.Top + cell.Height - height, 0);
    MSExcel.Shape button = xlWorkSheetNew.Shapes.AddPicture(@buttonImagePath, MsoTriState.msoFalse,
        MsoTriState.msoCTrue, left, top, width, height);

    VBIDE.VBComponent module = workBook.VBProject.VBComponents.Add(VBIDE.vbext_ComponentType.vbext_ct_StdModule);
    module.CodeModule.AddFromString(GetMacro(macroId, currentRow, endCol));
    button.OnAction = "Macro" + macroId;

}

Official documentation– https://support.microsoft.com/en-us/kb/306683

Volatile keyword

8. volatile

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.

volatile bool shouldPartyContinue = true;

public static unsafe void Main(string[] args)
{
    Program firstDimension = new Program();
    Thread secondDimension = new Thread(firstDimension.StartPartyInAnotherDimension);
    secondDimension.Start(firstDimension);
    Thread.Sleep(5000);
    firstDimension.shouldPartyContinue = false;
    Console.WriteLine("Party Grand Finish");
}

private void StartPartyInAnotherDimension(object input)
{
    Program currentDimensionInput = (Program)input;
    Console.WriteLine("let the party begin");
    while (currentDimensionInput.shouldPartyContinue)
    {
    }
    Console.WriteLine("Party ends :(");
}

If the variable shouldPartyContinue is not marked as volatile, the program will never finish if it is executed in Release.

Official documentation– https://msdn.microsoft.com/en-us/library/x13ttww7.aspx

9. global::

The ability to access a member of the global namespace is useful when the member might be hidden by another entity of the same name. This is one of my favored underutilized features of .NET.

public static unsafe void Main(string[] args)
{
    global::System.Console.WriteLine("Wine is constant proof that God loves us and loves to see us happy. -Benjamin Franklin");
}

public class System { }

// Define a constant called 'Console' to cause more problems.
const int Console = 7;
const int number = 66;

Official documentation– https://msdn.microsoft.com/en-us/library/c3ay4x3d(VS.80).aspx

10. DebuggerDisplayAttribute

Determines how a class or field is displayed in the debugger variable windows.

[DebuggerDisplay("{DebuggerDisplay}")]
public class DebuggerDisplayTest
{
    private string squirrelFirstNameName;
    private string squirrelLastNameName;

    public string SquirrelFirstNameName 
    {
        get
        {
            return squirrelFirstNameName;
        }
        set
        {
            squirrelFirstNameName = value;
        }
    }

    [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
    public string SquirrelLastNameName
    {
        get
        {
            return squirrelLastNameName;
        }
        set
        {
            squirrelLastNameName = value;
        }
    }

    public int Age { get; set; }

    private string DebuggerDisplay
    {
        get { return string.Format("{0} de {1}", SquirrelFirstNameName, SquirrelLastNameName); }
    }
}

In the above example, the method DebuggerDisplay will be used to calculate the value that is going to be presented in the Debugger window.

Debugger Display Attribute Method

Also, you can use different C# expressions directly in the attribute.

[DebuggerDisplay("Age {Age > 0 ? Age : 5}")]
public class DebuggerDisplayTest
{
    private string squirrelFirstNameName;
    private string squirrelLastNameName;

    public string SquirrelFirstNameName 
    {
        get
        {
            return squirrelFirstNameName;
        }
        set
        {
            squirrelFirstNameName = value;
        }
    }

    [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
    public string SquirrelLastNameName
    {
        get
        {
            return squirrelLastNameName;
        }
        set
        {
            squirrelLastNameName = value;
        }
    }

    public int Age { get; set; }

    private string DebuggerDisplay
    {
        get { return string.Format("{0} de {1}", SquirrelFirstNameName, SquirrelLastNameName); }
    }
}

If the age property is larger than zero, the actual age is going to be displayed otherwise five is used.

Official documentation– https://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerdisplayattribute.aspx

DebuggerStepThroughAttribute

11. DebuggerStepThroughAttribute

Instructs the debugger to step through the code instead of stepping into the code.

[DebuggerStepThroughAttribute]
public class DebuggerDisplayTest
{
    private string squirrelFirstNameName;
    private string squirrelLastNameName;

    public string SquirrelFirstNameName 
    {
        get
        {
            return squirrelFirstNameName;
        }
        set
        {
            squirrelFirstNameName = value;
        }
    }

    [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
    public string SquirrelLastNameName
    {
        get
        {
            return squirrelLastNameName;
        }
        set
        {
            squirrelLastNameName = value;
        }
    }

    public int Age { get; set; }

    private string DebuggerDisplay
    {
        get { return string.Format("{0} de {1}", SquirrelFirstNameName, SquirrelLastNameName); }
    }
}

Official documentation– https://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerstepthroughattribute.aspx

12. Conditional

It makes the execution of a method dependent on a preprocessing identifier. The Conditional attribute is an alias for ConditionalAttribute, and can be applied to a method or an attribute class.

public static unsafe void Main(string[] args)
{
    StartBugsParty();
}

[Conditional("LIVE")]
public static void StartBugsParty()
{
    Console.WriteLine("Let the bugs free. Start the Party.");
}

In order the above code to be executed #define LIVE should be added at the beginning of the C# file.

Official documentation– https://msdn.microsoft.com/en-us/library/4xssyw96.aspx

13. using Directive VS 2015

You can access static members of a type without having to qualify the access to the type name.

First add the following using clauses.

using static System.Math;
using static System.Console;

WriteLine(Sqrt(42563));

A using-alias directive cannot have an open generic type on the right-hand side. For example, you cannot create a using alias for a List<T>, but you can create one for a List<int>.

using IntList = System.Collections.Generic.List<int>;

IntList intList = new IntList();
intList.Add(1);
intList.Add(2);
intList.Add(3);
intList.ForEach(x => WriteLine(x));

Personally I believe that the last feature makes the code a little bit unreadable, so I suggest you to think twice before use it.

Official documentation– https://msdn.microsoft.com/en-us/library/sf0df423.aspx

14. Flags Enum Attribute

Flags enumerations are used for masking bit fields and doing bitwise comparisons. They are the correct design to use when multiple enumeration values can be specified at the same time.

[Flags]
public enum Minions
{
    Stuart = 1,
    Kevin = 2,
    Bob = 4,
    Dave = 8
}
 
Minions Flags Attribute

It is also important to note that Flags does not automatically make the enum values powers of two. If you omit the numeric values, the enum will not work as one might expect in bitwise operations because by default the values start with 0 and increment.

var minionsNames = (Minions.Bob | Minions.Dave).ToString();
// Displays 'Bob, Dave'
Console.WriteLine(minionsNames);

var allowedMinionsToParticipate = Minions.Dave | Minions.Kevin | Minions.Stuart;
// To retrieve the distinct values in you property one can do this
Console.WriteLine(allowedMinionsToParticipate);
if ((allowedMinionsToParticipate & Minions.Dave) == Minions.Dave)
{
    Console.WriteLine("Dave is allowed to be a party animal!");
}

// In .NET 4 and later
if (allowedMinionsToParticipate.HasFlag(Minions.Bob))
{
    Console.WriteLine("Bob is allowed to be a party animal!");
}
else
{
    Console.WriteLine("No more tequila for Bob. :(");
}

When you retrieve the value, you are bitwise AND’ing the values.

Note: You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set.

Official documentation– https://msdn.microsoft.com/en-us/library/ms229062.aspx

15. Dynamically Compile and Execute C# Code

15.1. CodeDOM

The CodeDOM provides types that represent many common types of source code elements. You can design a program that builds a source code model using CodeDOM elements to assemble an object graph. This object graph can be rendered as source code using a CodeDOM code generator for a supported programming language. The CodeDOM can also be used to compile source code into a binary assembly.

public static void Main(string[] args)
{
    var sourceCode = @"class HelloKittyPrinter
                        {
                            public void Print()
                            {
                                System.Console.WriteLine(""Hello Hello Kitty!"");
                            }
                        }";
    var compiledAssembly = CompileSourceCodeDom(sourceCode);
    ExecuteFromAssembly(compiledAssembly);
}

private static Assembly CompileSourceCodeDom(string sourceCode)
{
    CodeDomProvider csharpCodeProvider = new CSharpCodeProvider();
    var cp = new CompilerParameters();
    cp.ReferencedAssemblies.Add("System.dll");
    cp.GenerateExecutable = false;
    CompilerResults cr = csharpCodeProvider.CompileAssemblyFromSource(cp, sourceCode);

    return cr.CompiledAssembly;
}
 

Hello Kitty Printer

15.2. Roslyn

The .NET Compiler Platform (“Roslyn”) provides open-source C# and Visual Basic compilers with rich code analysis APIs. It enables building code analysis tools with the same APIs that are used by Visual Studio.

First you need to install the NuGet package Microsoft.CodeAnalysis.

You can find the whole source code and useful examples in the project’s official GitHub page.

public static void Main(string[] args)
{
    var sourceCode = @"class HelloKittyPrinter
                        {
                            public void Print()
                            {
                                System.Console.WriteLine(""Hello Hello Kitty!"");
                            }
                        }";
    var compiledAssembly = CompileSourceRoslyn(sourceCode);

    ExecuteFromAssembly(compiledAssembly);
}

private static Assembly CompileSourceRoslyn(string sourceCode)
{
    using (var memoryStream = new MemoryStream())
    {
        string assemblyFileName = string.Concat(Guid.NewGuid().ToString(), ".dll");

        CSharpCompilation compilation = CSharpCompilation.Create(assemblyFileName,
            new[] { CSharpSyntaxTree.ParseText(sourceCode) },
            new[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
            },
            new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
            );

        compilation.Emit(memoryStream);
        Assembly assembly = Assembly.Load(memoryStream.GetBuffer());
        return assembly;
    }
}

To execute the generated code, you can use the following method.

private static void ExecuteFromAssembly(Assembly assembly)
{
    Type helloKittyPrinterType = assembly.GetType("HelloKittyPrinter");
    MethodInfo printMethod = helloKittyPrinterType.GetMethod("Print");
    object kitty = assembly.CreateInstance("HelloKittyPrinter");
    printMethod.Invoke(kitty, BindingFlags.InvokeMethod, null, null, CultureInfo.CurrentCulture);
}

Documentation– http://benohead.com/three-options-to-dynamically-execute-csharp-code/

So Far in the C# Series

1. Implement Copy Paste C# Code
2. MSBuild TCP IP Logger C# Code
3. Windows Registry Read Write C# Code
4. Change .config File at Runtime C# Code
5. Generic Properties Validator C# Code
6. Reduced AutoMapper- Auto-Map Objects 180% Faster
7. 7 New Cool Features in C# 6.0
8. Types Of Code Coverage- Examples In C#
9. MSTest Rerun Failed Tests Through MSTest.exe Wrapper Application
10. Hints For Arranging Usings in Visual Studio Efficiently
11. 19 Must-Know Visual Studio Keyboard Shortcuts – Part 1
12. 19 Must-Know Visual Studio Keyboard Shortcuts – Part 2
13. Specify Assembly References Based On Build Configuration in Visual Studio
14. Top 15 Underutilized Features of .NET
15. Top 15 Underutilized Features of .NET Part 2
16. Neat Tricks for Effortlessly Format Currency in C#
17. Assert DateTime the Right Way MSTest NUnit C# Code
18. Which Works Faster- Null Coalescing Operator or GetValueOrDefault or Conditional Operator
19. Specification-based Test Design Techniques for Enhancing Unit Tests
20. Get Property Names Using Lambda Expressions in C#
21. Top 9 Windows Event Log Tips Using C#

 

If you enjoy my publications, feel free to SUBSCRIBE
Also, hit these share buttons. Thank you!

Source Code

 

Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.

The post Top 15 Underutilized Features of .NET Part 2 appeared first on Automate The Planet.

All images are purchased from DepositPhotos.com and cannot be downloaded and used for free. License Agreement

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Anton Angelov
CEO Automate The Planet
Bulgaria Bulgaria
Anton Angelov is an IT Consultant and Quality Assurance Architect at Innovative Lab. He is passionate about automation testing and designing test harness and tools, having the best industry development practices in mind. In addition, he is an active blogger and the founder of Automate The Planet. He strives to make the site one of the leading authorities in Automation Testing by presenting compelling articles, inspiring ardent discussions amongst the community. He is also one of the most-rated-answer authors of questions about Test Automation Frameworks (WebDriver) on Stack Overflow.

You may also be interested in...

Pro

Comments and Discussions

 
PraiseGood Article Pin
Member 421952424-Dec-16 0:13
memberMember 421952424-Dec-16 0:13 
GeneralMy vote of 5 Pin
Forhad Reza25-Nov-16 7:05
memberForhad Reza25-Nov-16 7:05 
QuestionExcellent Pin
vinod.jangle10-Nov-16 7:08
membervinod.jangle10-Nov-16 7:08 
PraiseExcellent Pin
MayurDighe11-Nov-15 22:25
professionalMayurDighe11-Nov-15 22:25 
GeneralMy vote of 5 Pin
Rany19843-Nov-15 0:10
memberRany19843-Nov-15 0:10 
AnswerVery nice article Pin
Dev_00711-Oct-15 9:03
professionalDev_00711-Oct-15 9:03 
QuestionVery nice Pin
Dan Sutton5-Oct-15 5:44
memberDan Sutton5-Oct-15 5:44 
AnswerRe: Very nice Pin
Anton Angelov5-Oct-15 6:53
professionalAnton Angelov5-Oct-15 6:53 
GeneralMy vote of 5 Pin
Dmitriy Gakh30-Sep-15 4:21
memberDmitriy Gakh30-Sep-15 4:21 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 10:57
professionalAnton Angelov4-Oct-15 10:57 
GeneralMy vote of 3 Pin
CatchExAs30-Sep-15 3:52
professionalCatchExAs30-Sep-15 3:52 
GeneralRe: My vote of 3 Pin
Craig Wagner30-Sep-15 4:24
memberCraig Wagner30-Sep-15 4:24 
GeneralRe: My vote of 3 Pin
Dmitriy Gakh30-Sep-15 4:26
memberDmitriy Gakh30-Sep-15 4:26 
GeneralRe: My vote of 3 Pin
Anton Angelov4-Oct-15 10:59
professionalAnton Angelov4-Oct-15 10:59 
GeneralRe: My vote of 3 Pin
CatchExAs5-Oct-15 2:30
professionalCatchExAs5-Oct-15 2:30 
QuestionGreat information! Pin
Greg Mulvihill28-Sep-15 9:19
memberGreg Mulvihill28-Sep-15 9:19 
AnswerRe: Great information! Pin
Anton Angelov4-Oct-15 10:48
professionalAnton Angelov4-Oct-15 10:48 
GeneralMy vote of 5 Pin
Jhonathan Izquierdo21-Sep-15 5:59
memberJhonathan Izquierdo21-Sep-15 5:59 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 11:12
professionalAnton Angelov4-Oct-15 11:12 
GeneralVery Useful... Pin
R.Hari Prasath15-Sep-15 0:30
memberR.Hari Prasath15-Sep-15 0:30 
GeneralRe: Very Useful... Pin
Anton Angelov4-Oct-15 11:13
professionalAnton Angelov4-Oct-15 11:13 
GeneralMy vote of 5 Pin
David A. Gray13-Sep-15 6:31
memberDavid A. Gray13-Sep-15 6:31 
GeneralRe: My vote of 5 Pin
Anton Angelov13-Sep-15 7:27
professionalAnton Angelov13-Sep-15 7:27 
QuestionGood work Pin
Santhakumar Munuswamy @ Chennai11-Sep-15 23:18
professionalSanthakumar Munuswamy @ Chennai11-Sep-15 23:18 
AnswerRe: Good work Pin
Anton Angelov4-Oct-15 11:15
professionalAnton Angelov4-Oct-15 11:15 
GeneralMy vote of 5 Pin
danos18-Sep-15 23:26
memberdanos18-Sep-15 23:26 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:01
professionalAnton Angelov11-Sep-15 23:01 
GeneralMy vote of 5 Pin
John Underhill8-Sep-15 12:16
memberJohn Underhill8-Sep-15 12:16 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:02
professionalAnton Angelov11-Sep-15 23:02 
QuestionHidden???? Pin
Kirk Wood8-Sep-15 11:24
memberKirk Wood8-Sep-15 11:24 
AnswerRe: Hidden???? Pin
Anton Angelov11-Sep-15 23:00
professionalAnton Angelov11-Sep-15 23:00 
GeneralMy vote of 5 Pin
PVX0078-Sep-15 5:32
memberPVX0078-Sep-15 5:32 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:02
professionalAnton Angelov11-Sep-15 23:02 
QuestionWARNING: dynamic and volatile Pin
PureNsanity8-Sep-15 4:49
professionalPureNsanity8-Sep-15 4:49 
SuggestionRe: WARNING: dynamic and volatile Pin
David A. Gray13-Sep-15 6:23
memberDavid A. Gray13-Sep-15 6:23 
GeneralRe: WARNING: dynamic and volatile Pin
PureNsanity13-Sep-15 6:56
professionalPureNsanity13-Sep-15 6:56 
GeneralRe: WARNING: dynamic and volatile Pin
David A. Gray13-Sep-15 7:32
memberDavid A. Gray13-Sep-15 7:32 
GeneralRe: WARNING: dynamic and volatile Pin
PureNsanity13-Sep-15 7:41
professionalPureNsanity13-Sep-15 7:41 
GeneralRe: WARNING: dynamic and volatile Pin
David A. Gray13-Sep-15 11:34
memberDavid A. Gray13-Sep-15 11:34 
AnswerMore warning about volatile Pin
RenniePet30-Sep-15 2:30
memberRenniePet30-Sep-15 2:30 
GeneralRe: More warning about volatile Pin
Anton Angelov4-Oct-15 11:06
professionalAnton Angelov4-Oct-15 11:06 
AnswerRe: WARNING: dynamic and volatile Pin
Anton Angelov4-Oct-15 11:17
professionalAnton Angelov4-Oct-15 11:17 
GeneralMy vote of 5 Pin
DVL Patel8-Sep-15 3:03
professionalDVL Patel8-Sep-15 3:03 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:02
professionalAnton Angelov11-Sep-15 23:02 
GeneralRe: My vote of 5 Pin
D V L11-Sep-15 23:13
professionalD V L11-Sep-15 23:13 
GeneralMy vote of 5 Pin
johannesnestler7-Sep-15 22:34
memberjohannesnestler7-Sep-15 22:34 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:02
professionalAnton Angelov11-Sep-15 23:02 
GeneralMy vote of 5 Pin
Franc Morales7-Sep-15 22:32
memberFranc Morales7-Sep-15 22:32 
GeneralRe: My vote of 5 Pin
Anton Angelov11-Sep-15 23:02
professionalAnton Angelov11-Sep-15 23:02 
GeneralMy vote of 5 Pin
Emile van Gerwen7-Sep-15 21:28
memberEmile van Gerwen7-Sep-15 21:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.170924.2 | Last Updated 25 Feb 2016
Article Copyright 2015 by Anton Angelov
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid