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.
To concatenate string literals, use the @ symbol at the beginning of each string.
var combinedString = @"\t means a tab" + @" and \n means a newline";
All operators are defined as static methods
and they are not virtual
and they are not inherited.
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 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
.
after a type instance, then it comes in VS intellisense.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 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"
The sixth version of C# was released July 2015 alongside Visual Studio 2015 and .NET 4.6.
As well as adding some new language features it includes a complete rewrite of the compiler. Previously csc.exe
was a native Win32 application written in C++, with C# 6 it is now a .NET managed application written in C#. This rewrite was known as project "Roslyn" and the code is now open source and available on GitHub.
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?)
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 @
.
abstract
as
base
bool
break
byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
else
enum
event
explicit
extern
false
finally
fixed
float
for
foreach
goto
if
implicit
in
int
interface
internal
is
lock
long
namespace
new
null
object
operator
out
override
params
private
protected
public
readonly
ref
return
sbyte
sealed
short
sizeof
stackalloc
static
string
struct
switch
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
(directive)using
(statement)virtual
void
volatile
when
while
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 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 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 :
Classes can inherit directly from only one class, but (instead or at the same time) can implement one or more interfaces.
Structs can implement interfaces but cannot explicitly inherit from any type. They implicitly inherit from System.ValueType
, which in turn inherits directly from System.Object
.
Static classes cannot implement interfaces.
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.
The object in the using
statement must implement the IDisposable
interface.
using(var obj = new MyObject())
{
}
class MyObject : IDisposable
{
public void Dispose()
{
// Cleanup
}
}
More complete examples for IDisposable
implementation can be found at the MSDN docs.
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
Note that when using the null coalescing operator on a value type T
you will get a Nullable<T>
back.
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.
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 await
ed, 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 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.
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.
The using
keyword is both a directive (this topic) and a statement.
For the using
statement (i.e. to encapsulate the scope of an IDisposable
object, ensuring that outside of that scope the object becomes cleanly disposed) please see Using Statement.
Putting the yield
keyword in a method with the return type of IEnumerable
, IEnumerable<T>
, IEnumerator
, or IEnumerator<T>
tells the compiler to generate an implementation of the return type (IEnumerable
or IEnumerator
) that, when looped over, runs the method up to each "yield" to get each result.
The yield
keyword is useful when you want to return "the next" element of a theoretically unlimited sequence, so calculating the entire sequence beforehand would be impossible, or when calculating the complete sequence of values before returning would lead to an undesirable pause for the user.
yield break
can also be used to terminate the sequence at any time.
As the yield
keyword requires an iterator interface type as the return type, such as IEnumerable<T>
, you cannot use this in an async method as this returns a Task<IEnumerable<T>>
object.
Further reading
When raising an event:
null
. A null delegate means the event has no subscribers. Raising an event with no subscribers will result in a NullReferenceException
.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);
if
statement: EventName?.Invoke(SenderObject, new EventArgsT());
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.
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.
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:
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.
MethodCallExpression
has reference to 1) the MethodInfo
it is going to call, 2) a list of Expression
s 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.
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.
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.
products.Where(x => x.Cost > 5)
SELECT * FROM products WHERE Cost > 5
ExpressionVisitor
) and make the wanted changes.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).
Notes:
String.Format()
handles null
arguments without throwing an exception.args
parameter with one, two, or three object parameters.unsafe
keyword in a .Net project, you must check "Allow unsafe code" in Project Properties => Buildunsafe
).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;
}
}
}
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.
The constructor parentheses can only be omitted if the type being instantiated has a default (parameterless) constructor available.
Some times you need to create extended text documentation from you xml comments. Unfortunatly there is no standard way for it.
But there are some separate projects that you can use for this case:
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 (#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.
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 useCallSite
objects in the site container of the local execution scope. The compiler manages what programmers perceive as dynamic object references through thoseCallSite
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 beSystem.Object
.
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 struct
s are also swept, once the GC determines they are not longer referenced to by the struct
.
struct
s 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.
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.
If the access modifier is omitted,
internal
private
private
Access modifiers on setters or getters of properties can only restrict access, not widen it:
public string someProperty {get; private set;}
Guid
s are Globally Unique Identifiers, also known as UUID's, Universally Unique Identifiers.
They are 128-bit pseudorandom values. There are so many valid Guid
s (about 10^18 Guid
s 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.
Guid
s 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.
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
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.
Named delegate types can be declared using the delegate
keyword.
Delegates can be invoked using the same syntax as methods: the name of the delegate instance, followed by parentheses containing any parameters.
Delegates can be assigned to in the following ways:
delegate
keyword.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 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>
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.
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
.
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);
}
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.
Indexer allows array-like syntax to access a property of an object with an index.
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.
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.
IEnumerable is the base interface for all non-generic collections that can be enumerated
For example, a property named HorizontalAlignment is more readable in English than AlignmentHorizontal.
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.
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#.
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.
Note that using recursion can have a severe impact on your code, as each recursive function call will be appended to the stack. If there are too many calls this could lead to a StackOverflowException. Most "natural recursive functions" can be written as a for
, while
or foreach
loop construct, and whilst not looking so posh or clever will be more efficient.
Always think twice and use recursion carefully - know why you use it:
If you want more theory, please read:
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.
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.
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 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:
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:
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.
The major differences between reference types and value types can be seen below.
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.
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.
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.
Working with Win32 API using C#
Windows exposes lots of functionality in the form of Win32 API. Using these API you can perform direct operation in windows, which increases performance of your application.Source Click here
Windows exposes a broad range of API. To get information about various APIs you can check sites like pinvoke.
Each implementation of Equals
must fulfil the following requirements:
Reflexive: An object must equal itself.x.Equals(x)
returns true
.
Symmetric: There is no difference if I compare x to y or y to x - the result is the same. x.Equals(y)
returns the same value as y.Equals(x)
.
Transitive: If one object is equal to another object and this one is equal to a third one, the first has to be equal to the third.
if (x.Equals(y) && y.Equals(z))
returns true
, then x.Equals(z)
returns true
.
Consistent: If you compare an object to another multiple times, the result is always the same.
Successive invocations of x.Equals(y)
return the same value as long as the objects referenced by x and y are not modified.
Comparison to null: No object is equal to null
.x.Equals(null)
returns false
.
Implementations of GetHashCode
:
Compatible with Equals
: If two objects are equal (meaning that Equals
returns true), then GetHashCode
must return the same value for each of them.
Large range: If two objects are not equal (Equals
says false), there should be a high probability their hash codes are distinct. Perfect hashing is often not possible as there is a limited number of values to choose from.
Cheap: It should be inexpensive to calculate the hash code in all cases.
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.
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 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 are often used in benchmarking programs to time code and see how optimal different segments of code take to run.
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# 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:
To run any of these examples just call them like that:
static void Main()
{
new Program().ProcessDataAsync();
Console.ReadLine();
}
If using Visual Studio, Timers can be added as a control directly to your form from the toolbox.
There is no inherent answer in C# to this - so called - need. Nonetheless there are workarounds to satisfy this need.
The reason I qualify the need as "so called" is that we only need methods with 2 or more than 2 values to return when we violate good programming principals. Especially the Single Responsibility Principle.
Hence, it would be better to be alerted when we need functions returning 2 or more values, and improve our design.
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.
.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.
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
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.
Stream
objects. This can be done with a using
block as shown above or by manually calling myStream.Close()
.@"C:\MyFolder\MyFile.txt"
C# 5.0 is coupled with Visual Studio .NET 2012
Pros of using Decorator:
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.
PM> Install-Package System.Management.Automation
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 ,
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,
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.
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.
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.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
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.
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.
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.**
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.
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.
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 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;
};
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.
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.
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.
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.