C# Language

Topics related to C# Language:

Getting started with C# Language

C# is a multi-paradigm, C-descendant programming language from Microsoft. C# is a managed language that compiles to CIL, intermediate bytecode which can be executed on Windows, Mac OS X and Linux.

Versions 1.0, 2.0 and 5.0 were standardized by ECMA (as ECMA-334), and standardization efforts for modern C# are underway.

Verbatim Strings

To concatenate string literals, use the @ symbol at the beginning of each string.

var combinedString = @"\t means a tab" + @" and \n means a newline";

Operators

All operators are defined as static methods and they are not virtual and they are not inherited.

Operator Precedence

All operators have a particular "precedence" depending on which group the operator falls in (operators of the same group have equal precedence). Meaning some operators will be applied before others. What follows is a list of groups (containing their respective operators) ordered by precedence (highest first):

  • Primary Operators

    • a.b - Member access.
    • a?.b - Null conditional member access.
    • -> - Pointer dereferencing combined with member access.
    • f(x) - Function invocation.
    • a[x] - Indexer.
    • a?[x] - Null conditional indexer.
    • x++ - Postfix increment.
    • x-- - Postfix decrement.
    • new - Type instantiation.
    • default(T) - Returns the default initialized value of type T.
    • typeof - Returns the Type object of the operand.
    • checked - Enables numeric overflow checking.
    • unchecked - Disables numeric overflow checking.
    • delegate - Declares and returns a delegate instance.
    • sizeof - Returns the size in bytes of the type operand.
  • Unary Operators

    • +x - Returns x.
    • -x - Numeric negation.
    • !x - Logical negation.
    • ~x - Bitwise complement/declares destructors.
    • ++x - Prefix increment.
    • --x - Prefix decrement.
    • (T)x - Type casting.
    • await - Awaits a Task.
    • &x - Returns the address (pointer) of x.
    • *x - Pointer dereferencing.
  • Multiplicative Operators

    • x * y - Multiplication.
    • x / y - Division.
    • x % y - Modulus.
  • Additive Operators

    • x + y - Addition.
    • x – y - Subtraction.
  • Bitwise Shift Operators

    • x << y - Shift bits left.
    • x >> y - Shift bits right.
  • Relational/Type-testing Operators

    • x < y - Less than.
    • x > y - Greater than.
    • x <= y - Less than or equal to.
    • x >= y - Greater than or equal to.
    • is - Type compatibility.
    • as - Type conversion.
  • Equality Operators

    • x == y - Equality.
    • x != y - Not equal.
  • Logical AND Operator

    • x & y - Logical/bitwise AND.
  • Logical XOR Operator

    • x ^ y - Logical/bitwise XOR.
  • Logical OR Operator

    • x | y - Logical/bitwise OR.
  • Conditional AND Operator

    • x && y - Short-circuiting logical AND.
  • Conditional OR Operator

    • x || y - Short-circuiting logical OR.
  • Null-coalescing Operator

    • x ?? y - Returns x if it is not null; otherwise, returns y.
  • Conditional Operator

    • x ? y : z - Evaluates/returns y if x is true; otherwise, evaluates z.

Related Content

Extension Methods

Extension methods are syntactic sugar that allow static methods to be invoked on object instances as if they were a member of the type itself.

Extension methods require an explicit target object. You will need to use the this keyword to access the method from within the extended type itself.

Extensions methods must be declared static, and must live in a static class.

Which namespace?

The choice of namespace for your extension method class is a trade-off between visibility and discoverability.

The most commonly mentioned option is to have a custom namespace for your extension methods. However this will involve a communication effort so that users of your code know that the extension methods exist, and where to find them.

An alternative is to choose a namespace such that developers will discover your extension methods via Intellisense. So if you want to extend the Foo class, it is logical to put the extension methods in the same namespace as Foo.

It is important to realise that nothing prevents you using "someone else's" namespace: Thus if you want to extend IEnumerable, you can add your extension method in the System.Linq namespace.

This is not always a good idea. For example, in one specific case, you may want to extend a common type (bool IsApproxEqualTo(this double value, double other) for example), but not have that 'pollute' the whole of System. In this case it is preferable to chose a local, specific, namespace.

Finally, it is also possible to put the extension methods in no namespace at all!

A good reference question: How do you manage the namespaces of your extension methods?

Applicability

Care should be taken when creating extension methods to ensure that they are appropriate for all possible inputs and are not only relevant to specific situations. For example, it is possible to extend system classes such as string, which makes your new code available to any string. If your code needs to perform domain specific logic on a domain specific string format, an extension method would not be appropriate as its presence would confuse callers working with other strings in the system.

The following list contains basic features and properties of extension methods

  1. It must be a static method.
  2. It must be located in a static class.
  3. It uses the "this" keyword as the first parameter with a type in .NET and this method will be called by a given type instance on the client side.
  4. It also shown by VS intellisense. When we press the dot . after a type instance, then it comes in VS intellisense.
  5. An extension method should be in the same namespace as it is used or you need to import the namespace of the class by a using statement.
  6. You can give any name for the class that has an extension method but the class should be static.
  7. If you want to add new methods to a type and you don't have the source code for it, then the solution is to use and implement extension methods of that type.
  8. If you create extension methods that have the same signature methods as the type you are extending, then the extension methods will never be called.

Collection Initializers

The only requirement for an object to be initialized using this syntactic sugar is that the type implements System.Collections.IEnumerable and the Add method. Although we call it a collection initializer, the object does not have to be an collection.

String Interpolation

String interpolation is a shorthand for the string.Format() method that makes it easier to build strings with variable and expression values inside of them.

var name = "World";
var oldWay = string.Format("Hello, {0}!", name);  // returns "Hello, World"
var newWay = $"Hello, {name}!";                   // returns "Hello, World"

C# 6.0 Features

Constructors and Finalizers

C# does not actually have destructors, but rather Finalizers which use C++ style destructor syntax. Specifying a destructor overrides the Object.Finalize() method which cannot be called directly.

Unlike other languages with similar syntax, these methods are not called when objects go out of scope, but are called when the Garbage Collector runs, which occurs under certain conditions. As such, they are not guaranteed to run in any particular order.

Finalizers should be responsible for cleaning up unmanaged resources only (pointers acquired via the Marshal class, received through p/Invoke (system calls) or raw pointers used within unsafe blocks). To clean up managed resources, please review IDisposable, the Dispose pattern and the using statement.

(Further reading: When should I create a destructor?)

Keywords

C# has a predefined collection of "keywords" (or reserved words) which each have a special function. These words can not be used as identifiers (names for variables, methods, classes, etc.) unless prefixed with @.

Apart from these, C# also uses some keywords to provide specific meaning in code. They are called contextual keywords. Contextual keywords can be used as identifiers and doesn't need to be prefixed with @ when used as identifiers.

Generics

Generics in C# are supported all the way down to the runtime: generic types built with C# will have their generic semantics preserved even after compiled to CIL.

This effectively means that, in C#, it is possible to reflect on generic types and see them as they were declared or check if an object is an instance of a generic type, for example. This is in contrast with type erasure, where generic type information is removed during compilation. It is also in contrast with the template approach to generics, where multiple concrete generic types become multiple non-generic types at runtime, and any metadata required to further instantiate the original generic type definitions is lost.

Be careful, however, when reflecting on generic types: generic types' names will be altered on compilation, substituting the angled brackets and the type parameters' names by a backtick followed by the number of generic type parameters. Thus, a Dictionary<TKey, Tvalue> will be translated to Dictionary`2.

Reflection

Reflection allows code to access information about the assemblies, modules and types at run-time (program execution). This can then be further used to dynamically create, modify or access types. Types include properties, methods, fields and attributes.

Further Reading :

Reflection(C#)

Reflection in .Net Framework

Inheritance

Null-Coalescing Operator

The null coalescing operator itself is two consecutive question mark characters: ??

It is a shorthand for the conditional expression:

possibleNullObject != null ? possibleNullObject : defaultValue

The left-side operand (object being tested) must be a nullable value type or reference type, or a compile error will occur.

The ?? operator works for both reference types and value types.

Using Statement

String Escape Sequences

String escape sequences are transformed to the corresponding character at compile time. Ordinary strings that happen to contain backwards slashes are not transformed.

For example, the strings notEscaped and notEscaped2 below are not transformed to a newline character, but will stay as two different characters ('\' and 'n').

string escaped = "\n";
string notEscaped = "\\" + "n";
string notEscaped2 = "\\n";

Console.WriteLine(escaped.Length); // 1
Console.WriteLine(notEscaped.Length); // 2            
Console.WriteLine(notEscaped2.Length); // 2

Exception Handling

Null-conditional Operators

Note that when using the null coalescing operator on a value type T you will get a Nullable<T> back.

Built-in Types

Lambda expressions

A lambda expression is a syntax for creating anonymous functions inline. More formally, from the C# Programming Guide:

A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls.

A lambda expression is created by using the => operator. Put any parameters on the lefthand side of the operator. On the righthand side, put an expression that can use those parameters; this expression will resolve as the return value of the function. More rarely, if necessary, a whole {code block} can be used on the righthand side. If the return type is not void, the block will contain a return statement.

Async-Await

An async method can return void, Task or Task<T>.

The return type Task will wait for the method to finish and the result will be void. Task<T> will return a value from type T after the method completes.

async methods should return Task or Task<T>, as opposed to void, in almost all circumstances. async void methods cannot be awaited, which leads to a variety of problems. The only scenario where an async should return void is in the case of an event handler.

async/await works by transforming your async method into a state machine. It does this by creating a structure behind the scenes which stores the current state and any context (like local variables), and exposes a MoveNext() method to advance states (and run any associated code) whenever an awaited awaitable completes.

Properties

Properties combine the class data storage of fields with the accessibility of methods. Sometimes it may be hard to decide whether to use a property, a property referencing a field, or a method referencing a field. As a rule of thumb:

  • Properties should be used without an internal field if they only get and/or set values; with no other logic occurring. In such cases, adding an internal field would be adding code for no benefit.

  • Properties should be used with internal fields when you need to manipulate or validate the data. An example may be removing leading and trailing spaces from strings or ensuring that a date is not in the past.

With regards to Methods vs Properties, where you can both retrieve (get) and update (set) a value, a property is the better choice. Also, .Net provides a lot of functionality that makes use of a class's structure; e.g. adding a grid to a form, .Net will by default list all properties of the class on that form; thus to make best use of such conventions plan to use properties when this behaviour would be typically desirable, and methods where you'd prefer for the types to not be automatically added.

Threading

A thread is a part of a program that can execute independently of other parts. It can perform tasks simultaneously with other threads. Multithreading is a feature that enables programs to perform concurrent processing so that more than one operation can be done at a time.

For example, you can use threading to update a timer or counter in the background while simultaneously performing other tasks in the foreground.

Multithreaded applications are more responsive to user input and are also easily scalable, because the developer can add threads as and when the workload increases.

By default, a C# program has one thread - the main program thread. However, secondary threads can be created and used to execute code in parallel with the primary thread. Such threads are called worker threads.

To control the operation of a thread, the CLR delegates a function to the operating system known as Thread Scheduler. A thread scheduler assures that all the threads are allocated proper execution time. It also checks that the threads that are blocked or locked do not consume much of the CPU time.

The .NET Framework System.Threading namespace makes using threads easier. System.Threading enables multithreading by providing a number of classes and interfaces. Apart from providing types and classes for a particular thread, it also defines types to hold a collection of threads, timer class and so on. It also provides its support by allowing synchronized access to shared data.

Thread is the main class in the System.Threading namespace. Other classes include AutoResetEvent, Interlocked, Monitor, Mutex, and ThreadPool.

Some of the delegates that are present in the System.Threading namespace include ThreadStart, TimerCallback, and WaitCallback.

Enumerations in System.Threading namespace include ThreadPriority, ThreadState, and EventResetMode.

In .NET Framework 4 and later versions, multithreaded programming is made easier and simpler through the System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), new concurrent collection classes in the System.Collections.Concurrent namespace, and a new task-based programming model.

Using Directive

Methods

Yield Keyword

Events

When raising an event:

  • Always check if the delegate is null. A null delegate means the event has no subscribers. Raising an event with no subscribers will result in a NullReferenceException.
6.0
  • Copy the delegate (e.g. EventName) to a local variable (e.g. eventName) before checking for null / raising the event. This avoids race conditions in multi-threaded environments:

Wrong:

    if(Changed != null)      // Changed has 1 subscriber at this point
                             // In another thread, that one subscriber decided to unsubscribe
        Changed(this, args); // `Changed` is now null, `NullReferenceException` is thrown.

Right:

    // Cache the "Changed" event as a local. If it is not null, then use
    // the LOCAL variable (handler) to raise the event, NOT the event itself.
    var handler = Changed;
    if(handler != null)
        handler(this, args);
6.0
  • Use the null-conditional operator (?.) for raising the method instead of null-checking the delegate for subscribers in an if statement: EventName?.Invoke(SenderObject, new EventArgsT());
  • When using Action<> to declare delegate types, the anonymous method / event handler signature must be the same as the declared anonymous delegate type in the event declaration.

LINQ Queries

To use LINQ queries you need to import System.Linq.

The Method Syntax is more powerful and flexible, but the Query Syntax may be simpler and more familiar. All queries written in Query syntax are translated into the functional syntax by the compiler, so performance is the same.

Query objects are not evaluated until they are used, so they can be changed or added to without a performance penalty.

Common String Operations

Expression Trees

Intro to Expression Trees

Where we came from

Expression trees are all about consuming "source code" at runtime. Consider a method which calculates the sales tax due on a sales order decimal CalculateTotalTaxDue(SalesOrder order). Using that method in a .NET program is easy — you just call it decimal taxDue = CalculateTotalTaxDue(order);. What if you want to apply it to all the results from a remote query (SQL, XML, a remote server, etc)? Those remote query sources cannot call the method! Traditionally, you would have to invert the flow in all these cases. Make the entire query, store it in memory, then loop through the results and calculate tax for each result.

How to avoid flow inversion's memory and latency problems

Expression trees are data structures in a format of a tree, where each node holds an expression. They are used to translate the compiled instructions (like methods used to filter data) in expressions which could be used outside of the program environment such as inside a database query.

The problem here is that a remote query cannot access our method. We could avoid this problem if instead, we sent the instructions for the method to the remote query. In our CalculateTotalTaxDue example, that means we send this information:

  1. Create a variable to store the total tax
  2. Loop through all the lines on the order
  3. For each line, check if the product is taxable
  4. If it is, multiply the line total by the applicable tax rate and add that amount to the total
  5. Otherwise do nothing

With those instructions, the remote query can perform the work as it's creating the data.

There are two challenges to implementing this. How do you transform a compiled .NET method into a list of instructions, and how do you format the instructions in a way that they can be consumed by the remote system?

Without expression trees, you could only solve the first problem with MSIL. (MSIL is the assembler-like code created by the .NET compiler.) Parsing MSIL is possible, but it's not easy. Even when you do parse it properly, it can be hard to determine what the original programmer's intent was with a particular routine.

Expression trees save the day

Expression trees address these exact issues. They represent program instructions a tree data structure where each node represents one instruction and has references to all the information you need to execute that instruction. For example, a MethodCallExpression has reference to 1) the MethodInfo it is going to call, 2) a list of Expressions it will pass to that method, 3) for instance methods, the Expression you'll call the method on. You can "walk the tree" and apply the instructions on your remote query.

Creating expression trees

The easiest way to create an expression tree is with a lambda expression. These expressions look almost the same as normal C# methods. It's important to realize this is compiler magic. When you first create a lambda expression, the compiler checks what you assign it to. If it's a Delegate type (including Action or Func), the compiler converts the lambda expression into a delegate. If it's a LambdaExpression (or an Expression<Action<T>> or Expression<Func<T>> which are strongly typed LambdaExpression's), the compiler transforms it into a LambdaExpression. This is where the magic kicks in. Behind the scenes, the compiler uses the expression tree API to transform your lambda expression into a LambdaExpression.

Lambda expressions cannot create every type of expression tree. In those cases, you can use the Expressions API manually to create the tree you need to. In the Understanding the expressions API example, we create the CalculateTotalSalesTax expression using the API.

NOTE: The names get a bit confusing here. A lambda expression (two words, lower case) refers to the block of code with a => indicator. It represents an anonymous method in C# and is converted into either a Delegate or Expression. A LambdaExpression (one word, PascalCase) refers to the node type within the Expression API which represents a method you can execute.

Expression Trees and LINQ

One of the most common uses of expression trees is with LINQ and database queries. LINQ pairs an expression tree with a query provider to apply your instructions to the target remote query. For example, the LINQ to Entity Framework query provider transforms an expression tree into SQL which is executed against the database directly.

Putting all the pieces together, you can see the real power behind LINQ.

  1. Write a query using a lambda expression: products.Where(x => x.Cost > 5)
  2. The compiler transforms that expression into an expression tree with the instructions "check if the Cost property of the parameter is greater than five".
  3. The query provider parses the expression tree and produces a valid SQL query SELECT * FROM products WHERE Cost > 5
  4. The ORM projects all the results into POCOs and you get a list of objects back

Notes

  • Expression trees are immutable. If you want to change an expression tree you need to create a new one, copy the existing one into the new one (to traverse an expression tree you can use the ExpressionVisitor) and make the wanted changes.

Overload Resolution

The process of overload resolution is described in the C# specification, section 7.5.3. Also relevant are the sections 7.5.2 (type inference) and 7.6.5 (invocation expressions).

How overload resolution works will probably be changed in C# 7. The design notes indicate that Microsoft will roll out a new system for determining which method is better (in complicated scenarios).

String.Format

Notes:

  • String.Format() handles null arguments without throwing an exception.
  • There are overloads that replace the args parameter with one, two, or three object parameters.

nameof Operator

Unsafe Code in .NET

  • In order to be able to use the unsafe keyword in a .Net project, you must check "Allow unsafe code" in Project Properties => Build
  • Using unsafe code can improve performance, however, it is at the expense of code safety (hence the term unsafe).

For instance, when you use a for loop an array like so:

for (int i = 0; i < array.Length; i++)
{
    array[i] = 0;
}

.NET Framework ensures that you do not exceed the bounds of the array, throwing an IndexOutOfRangeException if the index exceeds the bounds.

However, if you use unsafe code, you may exceed the array's bounds like so:

unsafe
{
    fixed (int* ptr = array)
    {
        for (int i = 0; i <= array.Length; i++)
        {
            *(ptr+i) = 0;
        }
    }
}

Initializing Properties

When deciding on how to create a property, start with an auto-implemented property for simplicity and brevity.

Switch to a property with a backing field only when circumstances dictate. If you need other manipulations beyond a simple set and get, you may need to introduce a backing field.

BindingList<T>

ILGenerator

Object initializers

The constructor parentheses can only be omitted if the type being instantiated has a default (parameterless) constructor available.

XML Documentation Comments

Preprocessor directives

Preprocessor directives are typically used to make source programs easy to change and easy to compile in different execution environments. Directives in the source file tell the preprocessor to perform specific actions. For example, the preprocessor can replace tokens in the text, insert the contents of other files into the source file, or suppress compilation of part of the file by removing sections of text. Preprocessor lines are recognized and carried out before macro expansion. Therefore, if a macro expands into something that looks like a preprocessor command, that command is not recognized by the preprocessor.

Preprocessor statements use the same character set as source file statements, with the exception that escape sequences are not supported. The character set used in preprocessor statements is the same as the execution character set. The preprocessor also recognizes negative character values.

Conditional Expressions

Conditional expressions (#if, #elif, etc) do support a limited subset of boolean operators. They are:

  • == and !=. These can only be used for testing whether the symbol is true (defined) or false (not defined)
  • &&, ||, !
  • ()

For example:

#if !DEBUG && (SOME_SYMBOL || SOME_OTHER_SYMBOL) && RELEASE == true
Console.WriteLine("OK!");
#endif

would compile code that prints "OK!" to the console if DEBUG is not defined, either SOME_SYMBOL or SOME_OTHER_SYMBOL is defined, and RELEASE is defined.

Note: These substitutions are done at compile time and are therefore not available for inspection at run time. Code eliminated through use of #if is not part of the compiler's output.

See Also: C# Preprocessor Directives at MSDN.

Dynamic type

The dynamic keyword declares a variable whose type is not known at compile time. A dynamic variable can contain any value, and the type of the value can change during runtime.

As noted in the book "Metaprogramming in .NET", C# does not have a backing type for the dynamic keyword:

The functionality enabled by the dynamic keyword is a clever set of compiler actions that emit and use CallSite objects in the site container of the local execution scope. The compiler manages what programmers perceive as dynamic object references through those CallSite instances. The parameters, return types, fields, and properties that get dynamic treatment at compile time may be marked with some metadata to indicate that they were generated for dynamic use, but the underlying data type for them will always be System.Object.

Anonymous types

Structs

Unlike classes, a struct is a value type, and is created on the local stack and not on the managed heap, by default. This means that once the specific stack goes out of scope, the struct is de-allocated. Contained reference types of de-allocated structs are also swept, once the GC determines they are not longer referenced to by the struct.

structs cannot inherit and cannot be bases for inheritance, they are implicitly sealed, and also cannot include protected members. However, a struct can implement an interface, as classes do.

Tuples

Enum

An Enum (short for "enumerated type") is a type consisting of a set of named constants, represented by a type-specific identifier.

Enums are most useful for representing concepts that have a (usually small) number of possible discrete values. For example, they can be used to represent a day of the week or a month of the year. They can be also be used as flags which can be combined or checked for, using bitwise operations.

Access Modifiers

If the access modifier is omitted,

  • classes are by default internal
  • methods are by deault private
  • getters and setters inherit the modifier of the property, by default this is private

Access modifiers on setters or getters of properties can only restrict access, not widen it: public string someProperty {get; private set;}

Task Parallel Library

Attributes

Guid

Guids are Globally Unique Identifiers, also known as UUID's, Universally Unique Identifiers.

They are 128-bit pseudorandom values. There are so many valid Guids (about 10^18 Guids for each cell of every people on Earth) that if they are generated by a good pseudorandom algorithm, they can be considered unique in the whole universe by all practical means.

Guids are most often used as primary keys in databases. Their advantage is that you don't have to call the database to get a new ID that is (almost) guaranteed to be unique.

Singleton Implementation

Delegates

Summary

A delegate type is a type representing a particular method signature. An instance of this type refers to a particular method with a matching signature. Method parameters may have delegate types, and so this one method to be passed a reference to another method, which may then be invoked

In-built delegate types: Action<...>, Predicate<T> and Func<...,TResult>

The System namespace contains Action<...>,Predicate<T> and Func<...,TResult> delegates, where the "..." represents between 0 and 16 generic type parameters (for 0 parameters, Action is non-generic).

Func represents methods with a return type matching TResult, and Action represents methods without a return value (void). In both cases, the additional generic type parameters match, in order, the method parameters.

Predicate represents method with boolean return type, T is input parameter.

Custom delegate types

Named delegate types can be declared using the delegate keyword.

Invoking delegates

Delegates can be invoked using the same syntax as methods: the name of the delegate instance, followed by parentheses containing any parameters.

Assigning to delegates

Delegates can be assigned to in the following ways:

  • Assigning a named method
  • Assigning an anonymous method using a lambda
  • Assigning a named method using the delegate keyword.

Combining delegates

Multiple delegate objects can be assigned to one delegate instance by using the + operator. The - operator can be used to remove a component delegate from another delegate.

Nullable types

Nullable types can represent all the values of an underlying type as well as null.

The syntax T? is shorthand for Nullable<T>

Nullable values are System.ValueType objects actually, so they can be boxed and unboxed. Also, null value of a nullable object is not the same as null value of a reference object, it's just a flag.

When a nullable object boxing, the null value is converted to null reference, and non-null value is converted to non-nullable underlying type.

DateTime? dt = null;
var o = (object)dt;
var result = (o == null); // is true

DateTime? dt = new DateTime(2015, 12, 11);
var o = (object)dt;
var dt2 = (DateTime)dt; // correct cause o contains DateTime value

The second rule leads to correct, but paradoxical code:

DateTime? dt = new DateTime(2015, 12, 11);
var o = (object)dt;
var type = o.GetType(); // is DateTime, not Nullable<DateTime>

In short form:

DateTime? dt = new DateTime(2015, 12, 11);
var type = dt.GetType(); // is DateTime, not Nullable<DateTime>

Garbage Collector in .Net

Networking

You can get the NetworkStream from a TcpClient with client.GetStream() and pass it into a StreamReader/StreamWriter to gain access to their async read and write methods.

Arrays

In C#, an array is a reference type, which means it is nullable.

An array has a fixed length, which means you cant .Add() to it or .Remove() from it. In order to use these, you would need a dynamic array - List or ArrayList.

Equality Operator

Lock Statement

Using the lock statement you can control different threads' access to code within the code block. It is commonly used to prevent race conditions, for example multiple threads reading and removing items from a collection. As locking forces threads to wait for other threads to exit a code block it can cause delays that could be solved with other synchronization methods.

MSDN

The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.

The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.


In C# 5.0 and later, the lock statement is equivalent to:

bool lockTaken = false;
try 
{
    System.Threading.Monitor.Enter(refObject, ref lockTaken);
    // code 
}
finally 
{
    if (lockTaken)
        System.Threading.Monitor.Exit(refObject);
}

For C# 4.0 and earlier, the lock statement is equivalent to:

System.Threading.Monitor.Enter(refObject);
try 
{
    // code
}
finally 
{
     System.Threading.Monitor.Exit(refObject);
}

Action Filters

XmlDocument and the System.Xml namespace

DateTime Methods

BackgroundWorker

Performing long-running operations within the UI thread can cause your application to become unresponsive, appearing to the user that it has stopped working. It is preferred that these tasks be run on a background thread. Once complete, the UI can be updated.

Making changes to the UI during the BackgroundWorker's operation requires invoking the changes to the UI thread, typically by using the Control.Invoke method on the control you are updating. Neglecting to do so will cause your program to throw an exception.

The BackgroundWorker is typically only used in Windows Forms applications. In WPF applications, Tasks are used to offload work onto background threads (possibly in combination with async/await). Marshalling updates onto the UI thread is typically done automatically, when the property being updated implements INotifyPropertyChanged, or manually by using the UI thread's Dispatcher.

Polymorphism

Static Classes

Indexer

Indexer allows array-like syntax to access a property of an object with an index.

  • Can be used on a class, struct or interface.
  • Can be overloaded.
  • Can use multiple parameters.
  • Can be used to access and set values.
  • Can use any type for it's index.

IDisposable interface

  • It's up to clients of the class implementing IDisposable to make sure they call the Dispose method when they are finished using the object. There is nothing in the CLR that directly searches objects for a Dispose method to invoke.

  • It's not necessary to implement a finalizer if your object only contains managed resources. Be sure to call Dispose on all of the objects that your class uses when you implement your own Dispose method.

  • It's recommended to make the class safe against multiple calls to Dispose, although it should ideally be called only once. This can be achieved by adding a private bool variable to your class and setting the value to true when the Dispose method has run.

Aliases of built-in types

Immutability

XDocument and the System.Xml.Linq namespace

C# 7.0 Features

Performing HTTP requests

Generating Random Numbers in C#

The random seed generated by the system isn't the same in every different run.

Seeds generated in the same time might be the same.

Looping

Named Arguments

Diagnostics

Interfaces

IEnumerable

IEnumerable is the base interface for all non-generic collections that can be enumerated

Naming Conventions

Choose easily readable identifier names

For example, a property named HorizontalAlignment is more readable in English than AlignmentHorizontal.

Favor readability over brevity

The property name CanScrollHorizontally is better than ScrollableX (an obscure reference to the X-axis).

Avoid using underscores, hyphens, or any other non-alphanumeric characters.

Do not use Hungarian notation

Hungarian notation is the practice of including a prefix in identifiers to encode some metadata about the parameter, such as the data type of the identifier, e.g. string strName.

Also, avoid using identifiers that conflict with keywords already used within C#.

Abbreviations and acronyms

In general, you should not use abbreviations or acronyms; these make your names less readable. Similarly, it is difficult to know when it is safe to assume that an acronym is widely recognized.

An overview of c# collections

Checked and Unchecked

Recursion

Functional Programming

Literals

Casting

Casting is not the same as Converting. It is possible to convert the string value "-1" to an integer value (-1), but this must be done through library methods like Convert.ToInt32() or Int32.Parse(). It cannot be done using casting syntax directly.

NullReferenceException

Func delegates

LINQ to XML

Hash Functions

MD5 and SHA1 are insecure and should be avoided. The examples exist for educational purposes and due to the fact that legacy software may still use these algorithms.

Handling FormatException when converting string to other types

Cryptography (System.Security.Cryptography)

INotifyPropertyChanged interface

The interface INotifyPropertyChanged is needed whenever you need to make your class report the changes happening to its properties. The interface defines a single event PropertyChanged.

With XAML Binding the PropertyChanged event is wired up automatically so you only need to implement the INotifyPropertyChanged interface on your view model or data context classes to work with XAML Binding.

Value type vs Reference type

Introduction

Value types

Value types are the simpler of the two. Value types are often used to represent data itself. An integer, a Boolean or a point in 3D space are all examples of good value types.

Value types (structs) are declared by using the struct keyword. See the syntax section for an example of how to declare a new struct.

Generally speaking, We have 2 keywords that are used to declare value types:

  • Structs
  • Enumerations

Reference types

Reference types are slightly more complex. Reference types are traditional objects in the sense of Object Oriented Programming. So, they support inheritance (and the benefits there of) and also support finalizers.

In C# generally we have this reference types:

  • Classes
  • Delegates
  • Interfaces

New reference types (classes) are declared using the class keyword. For an example, see the syntax section for how to declare a new reference type.

Major Differences

The major differences between reference types and value types can be seen below.

Value types exist on the stack, reference types exist on the heap

This is the often mentioned difference between the two, but really, what it boils down to is that when you use a value type in C#, such as an int, the program will use that variable to refer directly to that value. If you say int mine = 0, then the variable mine refers directly to 0, which is efficient. However, reference types actually hold (as the name suggests) a reference to the underlying object, this is akin to pointers in other languages such as C++.

You might not notice the effects of this immediately, but the effects are there, are powerful and are subtle. See the example on changing reference types elsewhere for an example.

This difference is the primary reason for the following other differences, and is worth knowing.

Value types don't change when you change them in a method, reference types do

When a value type is passed into a method as a parameter, if the method changes the value in any way, the value is not changed In contrast, passing a reference type into that same method and changing it will change the underlying object, so that other things that use that same object will have the newly changed object rather than their original value.

See the example of value types vs reference types in methods for more info.

What if I want to change them?

Simply pass them into your method using the "ref" keyword, and you are then passing this object by reference. Meaning, it's the same object in memory. So modifications you make will be respected. See the example on passing by reference for an example.

Value types cannot be null, reference types can

Pretty much as it says, you can assign null to a reference type, meaning the variable you've assigned can have no actual object assigned to it. In the case of value types, however, this is not possible. You can, however, use Nullable, to allow your value type to be nullable, if this is a requirement, though if this is something you are considering, think strongly whether a class might not be the best approach here, if it is your own type.

C# 4.0 Features

IQueryable interface

Task Parallel Library (TPL) Dataflow Constructs

Stream

Runtime Compile

Conditional Statements

Interoperability

Overflow

Equals and GetHashCode

Type Conversion

Type conversion is converting one type of data to another type. It is also known as Type Casting. In C#, type casting has two forms:

Implicit type conversion - These conversions are performed by C# in a type-safe manner. For example, are conversions from smaller to larger integral types and conversions from derived classes to base classes.

Explicit type conversion - These conversions are done explicitly by users using the pre-defined functions. Explicit conversions require a cast operator.

Parallel LINQ (PLINQ)

String Manipulation

String Concatenate

If you are creating a dynamic string, It is a good practice to opt for StringBuilder class rather than joining strings using + or Concat method as each +/Concat creates a new string object everytime it is executed.

Partial class and methods

  • Partial classes must be defined within the same assembly, and namespace, as the class that they are extending.

  • All parts of the class must use the partial keyword.

  • All parts of the class must have the same accessibility; public/protected/private etc..

  • If any part uses the abstract keyword, then the combined type is considered abstract.

  • If any part uses the sealed keyword, then the combined type is considered sealed.

  • If any part uses the a base type, then the combined type inherits from that type.

  • The combined type inherits all the interfaces defined on all the partial classes.

Stopwatches

Stopwatches are often used in benchmarking programs to time code and see how optimal different segments of code take to run.

Regex Parsing

Needed using

using System.Text.RegularExpressions;

Nice to have


Especially beginners are tended to overkill their tasks with regex because it feels powerful and in the right place for complexer text-based lookups. This is the point where people try to parse xml-documents with regex without even asking theirselfes if there could be an already finished class for this task like XmlDocument.

Regex should be the last weapon to pick agains complexity. At least dont forget putting in some effort to search for the right way before writing down 20 lines of patterns.

C# Script

C# 3.0 Features

C# version 3.0 was released as part of .Net version 3.5. Many of the features added with this version were in support of LINQ (Language INtegrated Queries).

List of added features:

  • LINQ
  • Lambda expressions
  • Extension methods
  • Anonymous types
  • Implicitly typed variables
  • Object and Collection Initializers
  • Automatically implemented properties
  • Expression trees

Async/await, Backgroundworker, Task and Thread Examples

To run any of these examples just call them like that:

static void Main()
{
    new Program().ProcessDataAsync();
    Console.ReadLine();
}

Timers

If using Visual Studio, Timers can be added as a control directly to your form from the toolbox.

Function with multiple return values

Binary Serialization

The binary serialization engine is part of the .NET framework, but the examples given here are specific to C#. As compared to other serialization engines built into the .NET framework, the binary serializer is fast and efficient and usually requires very little extra code to get it to work. However, it is also less tolerant to code changes; that is, if you serialize an object and then make a slight change to the object's definition, it likely will not deserialize correctly.

Making a variable thread safe

IComparable

Code Contracts

.NET supports the Design by Contract idea via its Contracts class found in the System.Diagnostics namespace and introduced in .NET 4.0. Code Contracts API includes classes for static and runtime checks of code and allows you to define preconditions, postconditions, and invariants within a method. The preconditions specify the conditions the parameters must fulfill before a method can execute, postconditions that are verified upon completion of a method, and the invariants define the conditions that do not change during the execution of a method.

Why are Code Contracts needed?

Tracking issues of an application when your application is running, is one the foremost concerns of all the developers and administrators. Tracking can be performed in many ways. For example -

  • You can apply tracing on our application and get the details of an application when the application is running

  • You can use event logging mechanism when you are running the application. The messages can be seen using Event Viewer

  • You can apply Performance Monitoring after a specific time interval and write live data from your application.

Code Contracts uses a different approach for tracking and managing issues within an application. Instead of validating everything that is returned from a method call, Code Contracts with the help of preconditions, postconditions, and invariants on methods, ensure that everything entering and leaving your methods are correct.

Iterators

An iterator is a method, get accessor, or operator that performs a custom iteration over an array or collection class by using the yield keyword

AssemblyInfo.cs Examples

The filename AssemblyInfo.cs is used by convention as the source file where developers place metadata attributes that describe the entire assembly they are building.

File and Stream I/O

Code Contracts and Assertions

Caching

C# 5.0 Features

C# 5.0 is coupled with Visual Studio .NET 2012

Implementing Flyweight Design Pattern

StringBuilder

Implementing Decorator Design Pattern

Pros of using Decorator:

  • you can add new functionalities at runtime in different configurations
  • good alternative for inheritance
  • client can choose configuration he wants to use

Accessing Databases

T4 Code Generation

Microsoft.Exchange.WebServices

.NET Compiler Platform (Roslyn)

Data Annotation

Using SQLite in C#

System.Management.Automation

The System.Management.Automation namespace is the root namespace for Windows PowerShell.

System.Management.Automation is an extension library from Microsoft and it can be added to Visual Studio projects via NuGet package manager or package manager console.


nuget-ui


PM> Install-Package System.Management.Automation

FileSystemWatcher

System.DirectoryServices.Protocols.LdapConnection

Named and Optional Arguments

Named Arguments

Ref: MSDN Named arguments enable you to specify an argument for a particular parameter by associating the argument with the parameter’s name rather than with the parameter’s position in the parameter list.

As said by MSDN, A named argument ,

  • Enables you to pass the argument to the function by associating the parameter’s name.
  • No needs for remembering the parameters position that we are not aware of always.
  • No need to look the order of the parameters in the parameters list of called function.
  • We can specify parameter for each arguments by its name.

Optional Arguments

Ref: MSDN The definition of a method, constructor, indexer, or delegate can specify that its parameters are required or that they are optional. Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

As said by MSDN, a Optional Argument,

  • We can omit the argument in the call if that argument is an Optional Argument
  • Every Optional Argument has its own default value
  • It will take default value if we do not supply the value
  • A default value of a Optional Argument must be a
    • Constant expression.
    • Must be a value type such as enum or struct.
    • Must be an expression of the form default(valueType)
  • It must be set at the end of parameter list

Comments and regions

C# Authentication handler

Pointers & Unsafe Code

Pointers

Pointers and unsafe

Due to their nature, pointers produce unverifiable code. Thus, usage of any pointer type requires an unsafe context.

The type System.IntPtr is a safe wrapper around a void*. It is intended as a more convenient alternative to void* when an unsafe context isn't otherwise required to perform the task at hand.

Undefined behavior

Like in C and C++, incorrect usage of pointers can invoke undefined behavior, with possible side-effects being memory corruption and execution of unintended code. Due to the unverifiable nature of most pointer operations, correct usage of pointers is entirely a responsibility of the programmer.

Types that support pointers

Unlike C and C++, not all C# types have corresponding pointer types. A type T may have a corresponding pointer type if both of the following criteria apply:

  • T is a struct type or a pointer type.
  • T contains only members that satisfy both of these criteria recursively.

How to use C# Structs to create a Union type (Similar to C Unions)

Union types are used in several languages, notably C-language, to contain several different types which can "overlap" in the same memory space. In other words, they might contain different fields all of which start at the same memory offset, even when they might have different lengths and types. This has the benefit of both saving memory, and doing automatic conversion.

Please, note the comments in the constructor of the Struct. The order in which the fields are initialized is extremely important. You want to first initialize all of the other fields and then set the value that you intend to change as the last statement. Because the fields overlap, the last value setup is the one that counts.

BigInteger

When To Use

BigInteger objects are by their very nature very heavy on RAM. Consequently, they should only be used when absolutely necessary, ie for numbers on a truly astronomical scale.

Further to this, all arithmetic operations on these objects are an order of magnitude slower than their primitive counterparts, this problem gets further compounded as the number grows as they are not of a fixed size. It is therefore feasibly possible for a rogue BigInteger to cause a crash by consuming all of the available RAM.

Alternatives

If speed is imperative to your solution it may be more efficient to implement this functionality yourself using a class wrapping a Byte[] and overloading the necessary operators yourself. However, this does require a significant amount of extra effort.

Dependency Injection

Wikipedia definition of dependency injection is:

In software engineering, dependency injection is a software design pattern that implements inversion of control for resolving dependencies. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it.

**This site features an answer to the question How to explain Dependency Injection to a 5-year old. The most highly rated answer, provided by John Munsch provides a surprisingly accurate analogy targeted at the (imaginary) five-year-old inquisitor: When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired. What you should be doing is stating a need, “I need something to drink with lunch,” and then we will make sure you have something when you sit down to eat. What this means in terms of object-oriented software development is this: collaborating classes (the five-year-olds) should rely on the infrastructure (the parents) to provide

** This code uses MEF to dynamically load the dll and resolve the dependencies. ILogger dependency is resolved by MEF and injectd into the user class. User class never receives Concrete implementation of ILogger and it has no idea of what or which type of logger its using.**

Reactive Extensions (Rx)

Creational Design Patterns

The creational patterns aim to separate a system from how its objects are created, composed, and represented. They increase the system's flexibility in terms of the what, who, how, and when of object creation. Creational patterns encapsulate the knowledge about which classes a system uses, but they hide the details of how the instances of these classes are created and put together. Programmers have come to realize that composing systems with inheritance makes those systems too rigid. The creational patterns are designed to break this close coupling.

Creating a Console Application using a Plain-Text Editor and the C# Compiler (csc.exe)

Reading and writing .zip files

Generic Lambda Query Builder

The class is called ExpressionBuilder. It has three properties:

 private static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
 private static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
 private static readonly MethodInfo EndsWithMethod = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });

One public method GetExpression that returns the lambda expression, and three private methods:

  • Expression GetExpression<T>
  • BinaryExpression GetExpression<T>
  • ConstantExpression GetConstant

All the methods are explained in details in the examples.

Import Google Contacts

The user contacts data will be received in JSON format, we extract it and finally we loop through this data and thus we get the google contacts.

Lambda Expressions

Closures

Lambda expressions will implicitly capture variables used and create a closure. A closure is a function along with some state context. The compiler will generate a closure whenever a lambda expression 'encloses' a value from its surrounding context.

E.g. when the following is executed

Func<object, bool> safeApplyFiltererPredicate = o => (o != null) && filterer.Predicate(i);

safeApplyFilterPredicate refers to a newly created object which has a private reference to the current value of filterer, and whose Invoke method behaves like

o => (o != null) && filterer.Predicate(i);

This can be important, because as long as the reference to the value now in safeApplyFilterPredicate is maintained, there will be a reference to the object which filterer currently refers to. This has an effect on garbage collection, and may cause unexpected behaviour if the object which filterer currently refers to is mutated.

On the other hand, closures can be used to deliberate effect to encapsulate a behaviour which involves references to other objects.

E.g.

var logger = new Logger();
Func<int, int> Add1AndLog = i => {
    logger.Log("adding 1 to " + i);
    return (i + 1);
};

Closures can also be used to model state machines:

Func<int, int> MyAddingMachine() {
    var i = 0;
    return x => i += x;
};

CLSCompliantAttribute

The Common Language Specification (CLS) is a set of base rules to which any language targeting the CLI(language which confirms the Common Language Infrastructure specifications) should confirm in order to interoperate with other CLS-compliant languages.

List of CLI languages

You should mark your assembly as CLSCompliant in most cases when you are distributing libraries. This attribute will guarantee you that your code will be usable by all CLS-compliant languages. This means that your code can be consumed by any language that can be compiled and run on CLR(Common Language Runtime)

When your assembly is marked with CLSCompliantAttribute, the compiler will check if your code violates any of CLS rules and return warning if it is needed.

ObservableCollection<T>

Synchronization Context in Async-Await

ICloneable

The CLR requires a method definition object Clone() which is not type safe. It is common practice to override this behavior and define a type safe method that returns a copy of the containing class.

It is up to the author to decide if cloning means only shallow copy, or deep copy. For immutable structures containing references it is recommended to do a deep copy. For classes being references themselves it is probably fine to implement a shallow copy.

NOTE: In C# an interface method can be implemented privately with the syntax shown above.

Read & Understand Stacktraces

Linq to Objects

ASP.NET Identity

Access network shared folder with username and password

Asynchronous Socket

Socket and network

How to access a Server outside my own network? This is a common question and when it is asked is mostly flagged as of topic.

Server Side

On the network of your server you need to port forward your router to your server.

For Example PC where server is running on:

local IP = 192.168.1.115

Server is listening to port 1234.

Forward incoming connections on Port 1234 router to 192.168.1.115

Client Side

The only thing you need to change is the IP. You don't want to connect to your loopback address but to the public IP from the network your server is running on. This IP you can get here.

 _connectingSocket.Connect(new IPEndPoint(IPAddress.Parse("10.10.10.10"), 1234));

So now you create a request on this endpoint : 10.10.10.10:1234 if you did property port forward your router your server and client will connect without any problem.

If you want to connect to a local IP you won't have to portforwart just change the loopback address to 192.168.1.178 or something like that.

Sending data:

Data is send in byte array. You need to pack you data into an byte array and unpack it on the other side.

If you are familiar with socket you also can try to encrypt your byte array before sending. This will prevent anyone from stealing your package.

Structural Design Patterns

O(n) Algorithm for circular rotation of an array

Creating Own MessageBox in Windows Form Application

Including Font Resources

Object Oriented Programming In C#

Using json.net

Getting Started: Json with C#

Windows Communication Foundation