Click here to Skip to main content
13,198,322 members (54,627 online)
Click here to Skip to main content
Add your own
alternative version

Stats

166.2K views
295 bookmarked
Posted 23 Aug 2015

Top 15 Underutilized Features of .NET

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

Introduction

I have been keen on the elegance and beauty of the C# language since I wrote my first lines of C# code. I read different articles and books about it, always when I have free time. Here I am going to share with you dozens of my favorite underutilized features of C# (oft-forgotten/interesting/arcane/hidden).

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 features of the framework in the comments. I will include them in the future second 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 hidden feature of .NET

Contents

1. ObsoleteAttribute
2. Setting a default value for C# Auto-implemented properties via DefaultValueAttribute
3. DebuggerBrowsableAttribute
4. ?? Operator
5. Curry and Partial methods
6. WeakReference
7. Lazy
8. BigInteger
9. __arglist __reftype __makeref __refvalue
10. Environment.NewLine
11. ExceptionDispatchInfo
12. Environment.FailFast
13. Debug.Assert, Debug.WriteIf and Debug.Indent
14. Parallel.For and Parallel.Foreach
15. IsInfinity

Underutilized Features of .NET

1. ObsoleteAttribute

ObsoleteAttribute applies to all program elements except assemblies, modules, parameters, and return values. Marking an element as obsolete informs users that the element will be removed in future versions of the product.
Message property contains a string that will be displayed when the attribute assignee is used. It is recommended a workaround to be provided in this description.
IsError– If set to true the compiler will indicate an error if the attribute target is used in the code.

public static class ObsoleteExample
{
    // Mark OrderDetailTotal As Obsolete.
    [ObsoleteAttribute("This property (DepricatedOrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)]
    public static decimal OrderDetailTotal
    {
        get
        {
            return 12m;
        }
    }

    public static decimal InvoiceTotal
    {
        get
        {
            return 25m;
        }
    }

    // Mark CalculateOrderDetailTotal As Obsolete.
    [ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)]
    public static decimal CalculateOrderDetailTotal()
    {
        return 0m;
    }

    public static decimal CalculateInvoiceTotal()
    {
        return 1m;
    }
}

If we use the above class in our code, an error, and a warning are going to be displayed.

Console.WriteLine(ObsoleteExample.OrderDetailTotal);
Console.WriteLine();
Console.WriteLine(ObsoleteExample.CalculateOrderDetailTotal());
 

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

2. Setting a default value for C# Auto-implemented properties via DefaultValueAttribute

DefaultValueAttribute specifies the default value for a property. You can create a DefaultValueAttribute with any value. A member’s default value is typically its initial value.
The attribute won’t cause a member to be automatically initialized with the specified value. Hence, you must set the initial value in your code.

public class DefaultValueAttributeTest
{
    public DefaultValueAttributeTest()
    {
        // Use the DefaultValue propety of each property to actually set it, via reflection.
        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this))
        {
            DefaultValueAttribute attr = (DefaultValueAttribute)prop.Attributes[typeof(DefaultValueAttribute)];
            if (attr != null)
            {
                prop.SetValue(this, attr.Value);
            }
        }
    }

    [DefaultValue(25)]
    public int Age { get; set; }

    [DefaultValue("Anton")]
    public string FirstName { get; set; }

    [DefaultValue("Angelov")]
    public string LastName { get; set; }

    public override string ToString()
    {
        return string.Format("{0} {1} is {2}.", this.FirstName, this.LastName, this.Age);
    }
}

The auto-implemented properties are initialized in the constructor of the class via reflection. The code iterates through all properties of the class and set them their default value if the DefaultValueAttribute is present.

Official documentationhttps://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

3. DebuggerBrowsableAttribute

Determines if and how a member is displayed in the debugger variable windows.

public static class DebuggerBrowsableTest
{
    private static string squirrelFirstNameName;
    private static string squirrelLastNameName;

    // The following DebuggerBrowsableAttribute prevents the property following it 
    // from appearing in the debug window for the class.
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public static string SquirrelFirstNameName 
    {
        get
        {
            return squirrelFirstNameName;
        }
        set
        {
            squirrelFirstNameName = value;
        }
    }

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

If you use the sample class in your code and try to step through it via the debugger (F11), you will notice that the code is just executing.

DebuggerBrowsableTest.SquirrelFirstNameName = "Hammy";
DebuggerBrowsableTest.SquirrelLastNameName = "Ammy";

Official documentationhttps://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerbrowsableattribute.aspx

4. ?? Operator

One of my favorite “underutilized features of C#” is the ?? operator. I’m using it heavily in my code.

In the next part of the series, 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.

The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand. A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type.

int? x = null;
int y = x ?? -1;
Console.WriteLine("y now equals -1 because x was null => {0}", y);
int i = DefaultValueOperatorTest.GetNullableInt() ?? default(int);
Console.WriteLine("i equals now 0 because GetNullableInt() returned null => {0}", i);
string s = DefaultValueOperatorTest.GetStringValue();
Console.WriteLine("Returns 'Unspecified' because s is null => {0}", s ?? "Unspecified");

Official documentationhttps://msdn.microsoft.com/en-us/library/ms173224(v=vs.80).aspx

5. Curry and Partial methods

Curry– In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument.

In order to be implemented via C#, the power of the extension methods is used.

public static class CurryMethodExtensions
{
    public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f)
    {
        return a => b => c => f(a, b, c);
    }
}

The curry extension method usage is a little bit overwhelming at first.

Func<int, int, int, int> addNumbers = (x, y, z) => x + y + z;
var f1 = addNumbers.Curry();
Func<int, Func<int, int>> f2 = f1(3);
Func<int, int> f3 = f2(4);
Console.WriteLine(f3(5));

The types returned by the different methods can be exchanged with the var keyword.

Official documentationhttps://en.wikipedia.org/wiki/Currying#/Contrast_with_partial_function_application

Partial – in computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity.

public static class CurryMethodExtensions
{
    public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b)
    {
        return c => f(a, b, c);
    }
}

The partial extension method usage is more straightforward than the curry one.

Func<int, int, int, int> sumNumbers = (x, y, z) => x + y + z;
Func<int, int> f4 = sumNumbers.Partial(3, 4);
Console.WriteLine(f4(5));

Again the types of the delegates can be declared with the var keyword.

Official documentation– https://en.wikipedia.org/wiki/Partial_application

6. WeakReference

A weak reference allows the garbage collector to collect an object while still allowing an application to access the object. If you need the object, you can still obtain a strong reference to it and prevent it from being collected.

WeakReferenceTest hugeObject = new WeakReferenceTest();
hugeObject.SharkFirstName = "Sharky";
WeakReference w = new WeakReference(hugeObject);
hugeObject = null;
GC.Collect();
Console.WriteLine((w.Target as WeakReferenceTest).SharkFirstName);

If the garbage collector is not called explicitly, there will be significant chance the weak reference to be still assigned.

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

7. Lazy<T>

Use lazy initialization to defer the creation of a large or resource-intensive object, or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program.

public abstract class ThreadSafeLazyBaseSingleton<T>
    where T : new()
{
    private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
    
    public static T Instance
    {
        get
        {
            return lazy.Value;
        }
    }
}

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

8. BigInteger

The BigInteger type is an immutable type that represents an arbitrarily large integer whose value, in theory, has no upper or lower bounds. This type differs from the other integral types in the .NET Framework, which have a range indicated by their MinValue and MaxValue properties.
Note: Because the BigInteger type is immutable and because it has no upper or lower bounds, an OutOfMemoryException can be thrown for any operation that causes a BigInteger value to grow too large.

string positiveString = "91389681247993671255432112000000";
string negativeString = "-90315837410896312071002088037140000";
BigInteger posBigInt = 0;
BigInteger negBigInt = 0;

posBigInt = BigInteger.Parse(positiveString);
Console.WriteLine(posBigInt);
negBigInt = BigInteger.Parse(negativeString);
Console.WriteLine(negBigInt);

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

9. Undocumented C# Keywords __arglist __reftype __makeref __refvalue

I’m not sure that these can be treated as underutilized features of C# because they are undocumented, and you should be careful with them. Probably there isn’t a documentation for a reason. Maybe they are not adequately tested. However, they are colored by the Visual Studio editor and recognized as official keywords.

You can create a typed reference from a variable by using the __makeref keyword. The original type of the variable represented by the typed reference can be extracted using the __reftype keyword. Lastly, the value can be obtained from the TypedReference using the __refvalue keyword. The __arglist has similar behavior to the keyword params- you can access parameters lists.

int i = 21;
TypedReference tr = __makeref(i);
Type t = __reftype(tr);
Console.WriteLine(t.ToString());
int rv = __refvalue( tr,int);
Console.WriteLine(rv);
ArglistTest.DisplayNumbersOnConsole(__arglist(1, 2, 3, 5, 6));

In order to be able to use __arglist you need the ArglistTest class.

public static class ArglistTest
{
    public static void DisplayNumbersOnConsole(__arglist)
    {
        ArgIterator ai = new ArgIterator(__arglist);
        while (ai.GetRemainingCount() > 0)
        {
            TypedReference tr = ai.GetNextArg();
            Console.WriteLine(TypedReference.ToObject(tr));
        }
    }
}

Remarks the ArgIterator object enumerates the argument list starting from the first optional argument, this constructor is provided specifically for use with the C/C++ programming language.

Referencehttp://www.nullskull.com/articles/20030114.asp and  http://community.bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx

10. Environment.NewLine

Gets the newline string defined for this environment.

Console.WriteLine("NewLine: {0}  first line{0}  second line{0}  third line", Environment.NewLine);

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

11. ExceptionDispatchInfo

Represents an exception whose state is captured at a certain point in code. You can use the ExceptionDispatchInfo.Throw method, which can be found in the System.Runtime.ExceptionServices namespace. This method can be used to throw an exception and preserve the original stack trace.

ExceptionDispatchInfo possibleException = null;

try
{
    int.Parse("a");
}
catch (FormatException ex)
{
    possibleException = ExceptionDispatchInfo.Capture(ex);
}

if (possibleException != null)
{
    possibleException.Throw();
}

The caught exception can be thrown again in another method or even in another thread.

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

12. Environment.FailFast()

If you want to exit your program without calling any finally blocks or finalizers use FailFast.

string s = Console.ReadLine();
try
{
    int i = int.Parse(s);
    if (i == 42) Environment.FailFast("Special number entered");
}
finally
{
    Console.WriteLine("Program complete.");
} 

If i equals 42 the finally block won’t be executed.

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

13. Debug.Assert & Debug.WriteIf & Debug.Indent

Debug.Assert– checks for a condition; if the condition is false, outputs messages and displays a message box that shows the call stack.

Debug.Assert(1 == 0, "The numbers are not equal! Oh my god!");

If the assert fails in Debug mode, the below alert is displayed, containing the specified message.

Debug.WriteIf– writes information about the debug to the trace listeners in the Listeners collection if a condition is true.

Debug.WriteLineIf(1 == 1, "This message is going to be displayed in the Debug output! =)");

Debug.Indent/Debug.Unindent– increases the current IndentLevel by one.

Debug.WriteLine("What are ingredients to bake a cake?");
Debug.Indent();
Debug.WriteLine("1. 1 cup (2 sticks) butter, at room temperature.");
Debug.WriteLine("2 cups sugar");
Debug.WriteLine("3 cups sifted self-rising flour");
Debug.WriteLine("4 eggs");
Debug.WriteLine("1 cup milk");
Debug.WriteLine("1 teaspoon pure vanilla extract");
Debug.Unindent();
Debug.WriteLine("End of list");

If we want to display the ingredients for a cake in the Debug Output Window, we can use the code above.

Official documentation: Debug.AssertDebug.WriteIfDebug.Indent/Debug.Unindent

14. Parallel.For & Parallel.Foreach

I’m not sure if we can add these to the underutilized features of .NET list because they are heavily used in the TPL (Task Parallel Library). However, I’m listing them here because I like them a lot and utilize their power in my multithreaded applications.

Parallel.For– executes a for loop in which iterations may run in parallel.

int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;

// Use type parameter to make subtotal a long, not an int
Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
{
    subtotal += nums[j];
    return subtotal;
},
    (x) => Interlocked.Add(ref total, x)
);

Console.WriteLine("The total is {0:N0}", total);

Interlocked.Add method adds two integers and replaces the first integer with the sum, as an atomic operation.

Parallel.Foreach– executes a foreach (For Each in Visual Basic) operation in which iterations may run in parallel.

int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;

Parallel.ForEach<int, long>(nums, // source collection
                            () => 0, // method to initialize the local variable
    (j, loop, subtotal) => // method invoked by the loop on each iteration
    {
        subtotal += j; //modify local variable 
        return subtotal; // value to be passed to next iteration
    },
    // Method to be executed when each partition has completed. 
    // finalResult is the final value of subtotal for a particular partition.
(finalResult) => Interlocked.Add(ref total, finalResult));

Console.WriteLine("The total from Parallel.ForEach is {0:N0}", total);

Official documentation: Parallel.For and Parallel.Foreach

15. IsInfinity

Returns a value indicating whether the specified number evaluates to negative or positive infinity.

Console.WriteLine("IsInfinity(3.0 / 0) == {0}.", Double.IsInfinity(3.0 / 0) ? "true" : "false");

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

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 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

 
GeneralMy vote of 5 Pin
Forhad Reza25-Nov-16 6:51
memberForhad Reza25-Nov-16 6:51 
Questionvery useful Pin
vinod.jangle30-May-16 16:09
membervinod.jangle30-May-16 16:09 
Generalamazing Pin
jagadaji3-Mar-16 20:33
memberjagadaji3-Mar-16 20:33 
GeneralMy vote of 1 Pin
tbayart26-Feb-16 11:26
membertbayart26-Feb-16 11:26 
QuestionSuper Good Pin
Brandon Williams26-Feb-16 9:15
memberBrandon Williams26-Feb-16 9:15 
PraiseSuperb Article Pin
kshkrao326-Feb-16 6:45
memberkshkrao326-Feb-16 6:45 
AnswerMy vote of 5 Pin
Dev_00711-Oct-15 8:58
professionalDev_00711-Oct-15 8:58 
SuggestionDefaultValue Pin
Galatei29-Sep-15 3:50
memberGalatei29-Sep-15 3:50 
GeneralRe: DefaultValue Pin
Anton Angelov4-Oct-15 11:01
professionalAnton Angelov4-Oct-15 11:01 
GeneralRe: DefaultValue Pin
the.Kris26-Feb-16 1:41
memberthe.Kris26-Feb-16 1:41 
GeneralMy vote of 5 Pin
sreeyush sudhakaran28-Sep-15 1:29
professionalsreeyush sudhakaran28-Sep-15 1:29 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 11:27
professionalAnton Angelov4-Oct-15 11:27 
GeneralMy vote of 4 Pin
ravithejag21-Sep-15 18:02
memberravithejag21-Sep-15 18:02 
GeneralRe: My vote of 4 Pin
Anton Angelov4-Oct-15 11:29
professionalAnton Angelov4-Oct-15 11:29 
SuggestionObsoleteAttribute and serialization Pin
Jens Doose18-Sep-15 3:13
memberJens Doose18-Sep-15 3:13 
GeneralRe: ObsoleteAttribute and serialization Pin
Anton Angelov4-Oct-15 11:31
professionalAnton Angelov4-Oct-15 11:31 
GeneralMy vote of 5 Pin
Mihai MOGA16-Sep-15 7:40
professionalMihai MOGA16-Sep-15 7:40 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 11:32
professionalAnton Angelov4-Oct-15 11:32 
GeneralMy vote of 5 Pin
Mostafa A. Ali12-Sep-15 15:47
professionalMostafa A. Ali12-Sep-15 15:47 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 11:33
professionalAnton Angelov4-Oct-15 11:33 
GeneralMy vote of 5 Pin
D V L11-Sep-15 23:13
professionalD V L11-Sep-15 23:13 
QuestionNice Article Pin
Santhakumar Munuswamy @ Chennai11-Sep-15 21:48
professionalSanthakumar Munuswamy @ Chennai11-Sep-15 21:48 
AnswerRe: Nice Article Pin
Anton Angelov11-Sep-15 22:54
professionalAnton Angelov11-Sep-15 22:54 
QuestionBetter word than "Hidden" Pin
Dan Sutton11-Sep-15 13:30
memberDan Sutton11-Sep-15 13:30 
AnswerRe: Better word than "Hidden" Pin
Felipe R. Machado11-Sep-15 19:34
professionalFelipe R. Machado11-Sep-15 19:34 
GeneralRe: Better word than "Hidden" Pin
Anton Angelov11-Sep-15 22:44
professionalAnton Angelov11-Sep-15 22:44 
GeneralRe: Better word than "Hidden" Pin
Dan Sutton12-Sep-15 6:39
memberDan Sutton12-Sep-15 6:39 
AnswerRe: Better word than "Hidden" Pin
Anton Angelov11-Sep-15 22:44
professionalAnton Angelov11-Sep-15 22:44 
AnswerRe: Better word than "Hidden" Pin
Anton Angelov4-Oct-15 11:26
professionalAnton Angelov4-Oct-15 11:26 
GeneralRe: Better word than "Hidden" Pin
Dan Sutton5-Oct-15 5:30
memberDan Sutton5-Oct-15 5:30 
GeneralRe: Better word than "Hidden" Pin
Anton Angelov5-Oct-15 6:54
professionalAnton Angelov5-Oct-15 6:54 
GeneralRe: Better word than "Hidden" Pin
Dan Sutton5-Oct-15 5:29
memberDan Sutton5-Oct-15 5:29 
GeneralMy vote of 5 Pin
David A. Gray11-Sep-15 10:39
memberDavid A. Gray11-Sep-15 10:39 
GeneralRe: My vote of 5 Pin
Anton Angelov4-Oct-15 11:24
professionalAnton Angelov4-Oct-15 11:24 
Suggestion"Oft-Forgotten" Features Pin
mldisibio11-Sep-15 8:20
membermldisibio11-Sep-15 8:20 
GeneralRe: "Oft-Forgotten" Features Pin
Anton Angelov4-Oct-15 11:20
professionalAnton Angelov4-Oct-15 11:20 
General[My vote of 1] My vote of 1 Pin
Sriram Sakthivel11-Sep-15 6:51
memberSriram Sakthivel11-Sep-15 6:51 
GeneralRe: [My vote of 1] My vote of 1 Pin
Member 1055815511-Sep-15 7:03
professionalMember 1055815511-Sep-15 7:03 
GeneralRe: [My vote of 1] My vote of 1 Pin
Sriram Sakthivel11-Sep-15 7:08
memberSriram Sakthivel11-Sep-15 7:08 
GeneralRe: [My vote of 1] My vote of 1 Pin
Felipe R. Machado11-Sep-15 7:32
professionalFelipe R. Machado11-Sep-15 7:32 
GeneralRe: [My vote of 1] My vote of 1 Pin
Dan Sutton11-Sep-15 13:28
memberDan Sutton11-Sep-15 13:28 
GeneralRe: [My vote of 1] My vote of 1 Pin
Felipe R. Machado11-Sep-15 19:29
professionalFelipe R. Machado11-Sep-15 19:29 
GeneralRe: [My vote of 1] My vote of 1 Pin
Anton Angelov11-Sep-15 22:48
professionalAnton Angelov11-Sep-15 22:48 
GeneralRe: [My vote of 1] My vote of 1 Pin
Eugene Scroggins12-Sep-15 7:20
memberEugene Scroggins12-Sep-15 7:20 
GeneralGood article Pin
Elman Aliev10-Sep-15 22:49
memberElman Aliev10-Sep-15 22:49 
GeneralRe: Good article Pin
Anton Angelov11-Sep-15 22:54
professionalAnton Angelov11-Sep-15 22:54 
GeneralRe: Good article Pin
Anton Angelov11-Sep-15 22:54
professionalAnton Angelov11-Sep-15 22:54 
QuestionVote 5 Pin
Stam Boris10-Sep-15 5:24
professionalStam Boris10-Sep-15 5:24 
QuestionIts a good article but... Pin
Suvabrata Roy10-Sep-15 1:34
professionalSuvabrata Roy10-Sep-15 1:34 
GeneralMy vote of 5 Pin
Grant Winney7-Sep-15 9:31
memberGrant Winney7-Sep-15 9:31 

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.171020.1 | Last Updated 25 Feb 2016
Article Copyright 2015 by Anton Angelov
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid