Dot NETFramework Notes For Professionals
Dot NETFramework Notes For Professionals
NET
.NET Framework
Notes for Professionals
100+ pages
of professional hints and tricks
Disclaimer
GoalKicker.com This is an unocial free book created for educational purposes and is
not aliated with ocial .NET Framework group(s) or company(s).
Free Programming Books All trademarks and registered trademarks are
the property of their respective owners
Contents
About ................................................................................................................................................................................... 1
Chapter 1: Getting started with .NET Framework ........................................................................................ 2
Section 1.1: Hello World in C# ........................................................................................................................................ 2
Section 1.2: Hello World in F# ....................................................................................................................................... 3
Section 1.3: Hello World in Visual Basic .NET .............................................................................................................. 3
Section 1.4: Hello World in C++/CLI .............................................................................................................................. 3
Section 1.5: Hello World in IL ......................................................................................................................................... 3
Section 1.6: Hello World in PowerShell ......................................................................................................................... 4
Section 1.7: Hello World in Nemerle ............................................................................................................................. 4
Section 1.8: Hello World in Python (IronPython) ......................................................................................................... 4
Section 1.9: Hello World in Oxygene ............................................................................................................................ 4
Section 1.10: Hello World in Boo ................................................................................................................................... 4
Chapter 2: Collections ................................................................................................................................................. 5
Section 2.1: Using collection initializers ........................................................................................................................ 5
Section 2.2: Stack .......................................................................................................................................................... 5
Section 2.3: Creating an initialized List with Custom Types ...................................................................................... 6
Section 2.4: Queue ......................................................................................................................................................... 8
Chapter 3: XmlSerializer ......................................................................................................................................... 10
Section 3.1: Formatting: Custom DateTime format .................................................................................................. 10
Section 3.2: Serialize object ........................................................................................................................................ 10
Section 3.3: Deserialize object .................................................................................................................................... 10
Section 3.4: Behaviour: Map array name to property (XmlArray) ......................................................................... 10
Section 3.5: Behaviour: Map Element name to Property ........................................................................................ 11
Section 3.6: Eciently building multiple serializers with derived types specified dynamically ........................... 11
Chapter 4: HTTP clients .......................................................................................................................................... 14
Section 4.1: Reading GET response as string using System.Net.HttpClient ........................................................... 14
Section 4.2: Basic HTTP downloader using System.Net.Http.HttpClient ................................................................ 14
Section 4.3: Reading GET response as string using System.Net.HttpWebRequest .............................................. 15
Section 4.4: Reading GET response as string using System.Net.WebClient ......................................................... 15
Section 4.5: Sending a POST request with a string payload using System.Net.HttpWebRequest ..................... 15
Section 4.6: Sending a POST request with a string payload using System.Net.WebClient ................................. 16
Section 4.7: Sending a POST request with a string payload using System.Net.HttpClient .................................. 16
Chapter 5: Exceptions ............................................................................................................................................... 17
Section 5.1: Catching and rethrowing caught exceptions ....................................................................................... 17
Section 5.2: Using a finally block ............................................................................................................................... 18
Section 5.3: Exception Filters ...................................................................................................................................... 18
Section 5.4: Rethrowing an exception within a catch block .................................................................................... 19
Section 5.5: Throwing an exception from a dierent method while preserving its information ........................ 19
Section 5.6: Catching an exception ........................................................................................................................... 20
Chapter 6: LINQ ........................................................................................................................................................... 21
Section 6.1: SelectMany (flat map) ............................................................................................................................ 21
Section 6.2: Where (filter) ........................................................................................................................................... 22
Section 6.3: Any ........................................................................................................................................................... 22
Section 6.4: GroupJoin ................................................................................................................................................ 23
Section 6.5: Except ...................................................................................................................................................... 24
Section 6.6: Zip ............................................................................................................................................................. 24
Section 6.7: Aggregate (fold) ..................................................................................................................................... 24
Section 6.8: ToLookup ................................................................................................................................................. 25
Section 6.9: Intersect ................................................................................................................................................... 25
Section 6.10: Concat .................................................................................................................................................... 25
Section 6.11: All ............................................................................................................................................................. 25
Section 6.12: Sum ......................................................................................................................................................... 26
Section 6.13: SequenceEqual ...................................................................................................................................... 26
Section 6.14: Min ........................................................................................................................................................... 26
Section 6.15: Distinct .................................................................................................................................................... 27
Section 6.16: Count ...................................................................................................................................................... 27
Section 6.17: Cast ......................................................................................................................................................... 27
Section 6.18: Range ..................................................................................................................................................... 27
Section 6.19: ThenBy ................................................................................................................................................... 28
Section 6.20: Repeat ................................................................................................................................................... 28
Section 6.21: Empty ..................................................................................................................................................... 28
Section 6.22: Select (map) .......................................................................................................................................... 28
Section 6.23: OrderBy ................................................................................................................................................. 29
Section 6.24: OrderByDescending ............................................................................................................................. 29
Section 6.25: Contains ................................................................................................................................................. 29
Section 6.26: First (find) .............................................................................................................................................. 29
Section 6.27: Single ...................................................................................................................................................... 30
Section 6.28: Last ........................................................................................................................................................ 30
Section 6.29: LastOrDefault ........................................................................................................................................ 30
Section 6.30: SingleOrDefault .................................................................................................................................... 31
Section 6.31: FirstOrDefault ........................................................................................................................................ 31
Section 6.32: Skip ......................................................................................................................................................... 31
Section 6.33: Take ....................................................................................................................................................... 32
Section 6.34: Reverse .................................................................................................................................................. 32
Section 6.35: OfType ................................................................................................................................................... 32
Section 6.36: Max ......................................................................................................................................................... 32
Section 6.37: Average ................................................................................................................................................. 32
Section 6.38: GroupBy ................................................................................................................................................. 33
Section 6.39: ToDictionary .......................................................................................................................................... 33
Section 6.40: Union ...................................................................................................................................................... 34
Section 6.41: ToArray .................................................................................................................................................. 35
Section 6.42: ToList ..................................................................................................................................................... 35
Section 6.43: ElementAt .............................................................................................................................................. 35
Section 6.44: ElementAtOrDefault ............................................................................................................................. 35
Section 6.45: SkipWhile ............................................................................................................................................... 35
Section 6.46: TakeWhile .............................................................................................................................................. 36
Section 6.47: DefaultIfEmpty ...................................................................................................................................... 36
Section 6.48: Join ........................................................................................................................................................ 36
Section 6.49: Left Outer Join ...................................................................................................................................... 37
Chapter 7: Networking ............................................................................................................................................. 39
Section 7.1: Basic TCP chat (TcpListener, TcpClient, NetworkStream) .................................................................. 39
Section 7.2: Basic SNTP client (UdpClient) ................................................................................................................ 40
Chapter 8: NuGet packaging system ............................................................................................................... 42
Section 8.1: Uninstalling a package from one project in a solution ....................................................................... 42
Section 8.2: Installing a specific version of a package ............................................................................................ 42
Section 8.3: Adding a package source feed (MyGet, Klondike, ect) ...................................................................... 42
Section 8.4: Installing the NuGet Package Manager ............................................................................................... 42
Section 8.5: Managing Packages through the UI ..................................................................................................... 43
Section 8.6: Managing Packages through the console ........................................................................................... 43
Section 8.7: Updating a package .............................................................................................................................. 43
Section 8.8: Uninstalling a package .......................................................................................................................... 44
Section 8.9: Uninstall a specific version of package ............................................................................................... 44
Chapter 9: Reflection ................................................................................................................................................ 45
Section 9.1: What is an Assembly? ............................................................................................................................. 45
Section 9.2: Compare two objects with reflection ................................................................................................... 45
Section 9.3: Creating Object and setting properties using reflection .................................................................... 46
Section 9.4: How to create an object of T using Reflection .................................................................................... 46
Section 9.5: Getting an attribute of an enum with reflection (and caching it) ...................................................... 46
Chapter 10: Dictionaries .......................................................................................................................................... 48
Section 10.1: Initializing a Dictionary with a Collection Initializer ............................................................................. 48
Section 10.2: Adding to a Dictionary .......................................................................................................................... 48
Section 10.3: Getting a value from a dictionary ....................................................................................................... 48
Section 10.4: Make a Dictionary<string, T> with Case-Insensivitve keys ............................................................... 49
Section 10.5: IEnumerable to Dictionary (≥ .NET 3.5) ............................................................................................... 49
Section 10.6: Enumerating a Dictionary .................................................................................................................... 49
Section 10.7: ConcurrentDictionary<TKey, TValue> (from .NET 4.0) .................................................................... 50
Section 10.8: Dictionary to List ................................................................................................................................... 51
Section 10.9: Removing from a Dictionary ............................................................................................................... 51
Section 10.10: ContainsKey(TKey) ............................................................................................................................. 52
Section 10.11: ConcurrentDictionary augmented with Lazy'1 reduces duplicated computation .......................... 52
Chapter 11: HTTP servers ........................................................................................................................................ 54
Section 11.1: Basic read-only HTTP file server (ASP.NET Core) ............................................................................... 54
Section 11.2: Basic read-only HTTP file server (HttpListener) ................................................................................. 55
Chapter 12: Settings ................................................................................................................................................... 58
Section 12.1: AppSettings from ConfigurationSettings in .NET 1.x ........................................................................... 58
Section 12.2: Reading AppSettings from ConfigurationManager in .NET 2.0 and later ....................................... 58
Section 12.3: Introduction to strongly-typed application and user settings support from Visual Studio
................................................................................................................................................................................ 59
Section 12.4: Reading strongly-typed settings from custom section of configuration file ................................. 60
Chapter 13: Task Parallel Library (TPL) ........................................................................................................... 63
Section 13.1: Basic producer-consumer loop (BlockingCollection) ......................................................................... 63
Section 13.2: Parallel.Invoke ........................................................................................................................................ 63
Section 13.3: Task: Returning a value ........................................................................................................................ 64
Section 13.4: Parallel.ForEach ..................................................................................................................................... 64
Section 13.5: Parallel.For ............................................................................................................................................. 64
Section 13.6: Task: basic instantiation and Wait ....................................................................................................... 65
Section 13.7: Task.WhenAll .......................................................................................................................................... 65
Section 13.8: Flowing execution context with AsyncLocal ....................................................................................... 65
Section 13.9: Parallel.ForEach in VB.NET ................................................................................................................... 66
Section 13.10: Task: WaitAll and variable capturing ................................................................................................. 66
Section 13.11: Task: WaitAny ........................................................................................................................................ 67
Section 13.12: Task: handling exceptions (using Wait) ............................................................................................. 67
Section 13.13: Task: handling exceptions (without using Wait) ............................................................................... 67
Section 13.14: Task: cancelling using CancellationToken ......................................................................................... 68
Section 13.15: Task.WhenAny ...................................................................................................................................... 69
Chapter 14: Custom Types ..................................................................................................................................... 70
Section 14.1: Struct Definition ...................................................................................................................................... 70
Section 14.2: Class Definition ...................................................................................................................................... 70
Chapter 15: DateTime parsing ............................................................................................................................. 72
Section 15.1: ParseExact .............................................................................................................................................. 72
Section 15.2: TryParse ................................................................................................................................................. 73
Section 15.3: TryParseExact ........................................................................................................................................ 75
Chapter 16: Memory management .................................................................................................................... 76
Section 16.1: Use SafeHandle when wrapping unmanaged resources .................................................................. 76
Section 16.2: Unmanaged Resources ........................................................................................................................ 76
Chapter 17: Managed Extensibility Framework ........................................................................................... 78
Section 17.1: Connecting (Basic) ................................................................................................................................. 78
Section 17.2: Exporting a Type (Basic) ...................................................................................................................... 78
Section 17.3: Importing (Basic) ................................................................................................................................... 79
Chapter 18: SpeechRecognitionEngine class to recognize speech ................................................... 80
Section 18.1: Asynchronously recognizing speech based on a restricted set of phrases .................................... 80
Section 18.2: Asynchronously recognizing speech for free text dictation ............................................................. 80
Chapter 19: System.Reflection.Emit namespace ........................................................................................ 81
Section 19.1: Creating an assembly dynamically ..................................................................................................... 81
Chapter 20: System.Runtime.Caching.MemoryCache (ObjectCache) ............................................. 84
Section 20.1: Adding Item to Cache (Set) .................................................................................................................. 84
Section 20.2: System.Runtime.Caching.MemoryCache (ObjectCache) ................................................................. 84
Chapter 21: JSON Serialization ............................................................................................................................ 86
Section 21.1: Deserialization using System.Web.Script.Serialization.JavaScriptSerializer .................................... 86
Section 21.2: Serialization using Json.NET ................................................................................................................ 86
Section 21.3: Serialization-Deserialization using Newtonsoft.Json ......................................................................... 87
Section 21.4: Deserialization using Json.NET ............................................................................................................ 87
Section 21.5: Dynamic binding ................................................................................................................................... 87
Section 21.6: Serialization using Json.NET with JsonSerializerSettings ................................................................. 88
Chapter 22: TPL Dataflow ...................................................................................................................................... 89
Section 22.1: Asynchronous Producer Consumer With A Bounded BuerBlock .................................................. 89
Section 22.2: Posting to an ActionBlock and waiting for completion .................................................................... 89
Section 22.3: Linking blocks to create a pipeline ..................................................................................................... 89
Section 22.4: Synchronous Producer/Consumer with BuerBlock<T> ................................................................. 90
Chapter 23: File Input/Output .............................................................................................................................. 92
Section 23.1: C# File.Exists() ........................................................................................................................................ 92
Section 23.2: VB WriteAllText ..................................................................................................................................... 92
Section 23.3: VB StreamWriter ................................................................................................................................... 92
Section 23.4: C# StreamWriter ................................................................................................................................... 92
Section 23.5: C# WriteAllText() .................................................................................................................................. 93
Chapter 24: Platform Invoke ................................................................................................................................ 94
Section 24.1: Marshaling structs ................................................................................................................................. 94
Section 24.2: Marshaling unions ................................................................................................................................ 95
Section 24.3: Calling a Win32 dll function ................................................................................................................. 96
Section 24.4: Using Windows API ............................................................................................................................... 97
Section 24.5: Marshalling arrays ............................................................................................................................... 97
Chapter 25: Code Contracts .................................................................................................................................. 98
Section 25.1: Contracts for Interfaces ....................................................................................................................... 98
Section 25.2: Installing and Enabling Code Contracts ............................................................................................. 98
Section 25.3: Preconditions ...................................................................................................................................... 100
Section 25.4: Postconditions .................................................................................................................................... 101
Chapter 26: VB Forms ............................................................................................................................................ 102
Section 26.1: Hello World in VB.NET Forms ............................................................................................................ 102
Section 26.2: For Beginners ..................................................................................................................................... 102
Section 26.3: Forms Timer ........................................................................................................................................ 102
Chapter 27: ForEach ................................................................................................................................................ 105
Section 27.1: Extension method for IEnumerable ................................................................................................... 105
Section 27.2: Calling a method on an object in a list ............................................................................................. 105
Chapter 28: Strings .................................................................................................................................................. 106
Section 28.1: Count characters ................................................................................................................................. 106
Section 28.2: Count distinct characters .................................................................................................................. 106
Section 28.3: Convert string to/from another encoding ....................................................................................... 106
Section 28.4: Comparing strings .............................................................................................................................. 107
Section 28.5: Count occurrences of a character ................................................................................................... 107
Section 28.6: Split string into fixed length blocks ................................................................................................... 107
Section 28.7: Object.ToString() virtual method ...................................................................................................... 108
Section 28.8: Immutability of strings ....................................................................................................................... 109
Chapter 29: Expression Trees ............................................................................................................................. 110
Section 29.1: building a predicate of form field == value ....................................................................................... 110
Section 29.2: Simple Expression Tree Generated by the C# Compiler ................................................................ 110
Section 29.3: Expression for retrieving a static field .............................................................................................. 111
Section 29.4: InvocationExpression Class ............................................................................................................... 111
Chapter 30: Threading ........................................................................................................................................... 114
Section 30.1: Accessing form controls from other threads ................................................................................... 114
Chapter 31: System.Diagnostics ........................................................................................................................ 116
Section 31.1: Run shell commands ........................................................................................................................... 116
Section 31.2: Send Command to CMD and Receive Output .................................................................................. 116
Section 31.3: Stopwatch ............................................................................................................................................ 118
Chapter 32: ADO.NET .............................................................................................................................................. 119
Section 32.1: Best Practices - Executing Sql Statements ....................................................................................... 119
Section 32.2: Executing SQL statements as a command ..................................................................................... 120
Section 32.3: Using common interfaces to abstract away vendor specific classes .......................................... 121
Chapter 33: CLR ......................................................................................................................................................... 122
Section 33.1: An introduction to Common Language Runtime ............................................................................. 122
Chapter 34: Process and Thread anity setting .................................................................................... 123
Section 34.1: Get process anity mask .................................................................................................................. 123
Section 34.2: Set process anity mask .................................................................................................................. 123
Chapter 35: Dependency Injection .................................................................................................................. 125
Section 35.1: How Dependency Injection Makes Unit Testing Easier ................................................................... 125
Section 35.2: Dependency Injection - Simple example ......................................................................................... 125
Section 35.3: Why We Use Dependency Injection Containers (IoC Containers) ................................................ 126
Chapter 36: Globalization in ASP.NET MVC using Smart internationalization for ASP.NET
............................................................................................................................................................................................ 129
Section 36.1: Basic configuration and setup ........................................................................................................... 129
Chapter 37: Task Parallel Library (TPL) API Overviews ........................................................................ 131
Section 37.1: Perform work in response to a button click and update the UI ..................................................... 131
Chapter 38: System.IO ........................................................................................................................................... 132
Section 38.1: Reading a text file using StreamReader ........................................................................................... 132
Section 38.2: Serial Ports using System.IO.SerialPorts .......................................................................................... 132
Section 38.3: Reading/Writing Data Using System.IO.File .................................................................................... 133
Chapter 39: Unit testing ........................................................................................................................................ 135
Section 39.1: Adding MSTest unit testing project to an existing solution ............................................................. 135
Section 39.2: Creating a sample test method ........................................................................................................ 135
Chapter 40: Serial Ports ....................................................................................................................................... 136
Section 40.1: Basic operation ................................................................................................................................... 136
Section 40.2: List available port names .................................................................................................................. 136
Section 40.3: Asynchronous read ............................................................................................................................ 136
Section 40.4: Synchronous text echo service ......................................................................................................... 136
Section 40.5: Asynchronous message receiver ..................................................................................................... 137
Chapter 41: System.IO.File class ....................................................................................................................... 140
Section 41.1: Delete a file ........................................................................................................................................... 140
Section 41.2: Strip unwanted lines from a text file ................................................................................................. 141
Section 41.3: Convert text file encoding .................................................................................................................. 141
Section 41.4: Enumerate files older than a specified amount ............................................................................... 142
Section 41.5: Move a File from one location to another ........................................................................................ 142
Chapter 42: Synchronization Contexts .......................................................................................................... 144
Section 42.1: Execute code on the UI thread after performing background work ............................................. 144
Chapter 43: Using Progress<T> and IProgress<T> .................................................................................. 145
Section 43.1: Simple Progress reporting .................................................................................................................. 145
Section 43.2: Using IProgress<T> ............................................................................................................................ 145
Chapter 44: ReadOnlyCollections ................................................................................................................... 147
Section 44.1: Creating a ReadOnlyCollection ......................................................................................................... 147
Section 44.2: Updating a ReadOnlyCollection ....................................................................................................... 147
Section 44.3: Warning: Elements in a ReadOnlyCollection are not inherently read-only ................................. 147
Chapter 45: Regular Expressions (System.Text.RegularExpressions) .......................................... 149
Section 45.1: Check if pattern matches input ......................................................................................................... 149
Section 45.2: Remove non alphanumeric characters from string ....................................................................... 149
Section 45.3: Passing Options .................................................................................................................................. 149
Section 45.4: Match into groups .............................................................................................................................. 149
Section 45.5: Find all matches ................................................................................................................................. 149
Section 45.6: Simple match and replace ................................................................................................................ 150
Chapter 46: System.Net.Mail .............................................................................................................................. 151
Section 46.1: MailMessage ........................................................................................................................................ 151
Section 46.2: Mail with Attachment ......................................................................................................................... 152
Chapter 47: Encryption / Cryptography ..................................................................................................... 153
Section 47.1: Encryption and Decryption using Cryptography (AES) .................................................................. 153
Section 47.2: RijndaelManaged ............................................................................................................................... 154
Section 47.3: Encrypt and decrypt data using AES (in C#) ................................................................................... 155
Section 47.4: Create a Key from a Password / Random SALT (in C#) ............................................................... 158
Chapter 48: Parallel processing using .Net framework ....................................................................... 161
Section 48.1: Parallel Extensions .............................................................................................................................. 161
Chapter 49: JSON in .NET with Newtonsoft.Json .................................................................................... 162
Section 49.1: Deserialize an object from JSON text ............................................................................................... 162
Section 49.2: Serialize object into JSON ................................................................................................................. 162
Chapter 50: .NET Core ............................................................................................................................................ 163
Section 50.1: Basic Console App .............................................................................................................................. 163
Chapter 51: JIT compiler ....................................................................................................................................... 164
Section 51.1: IL compilation sample ......................................................................................................................... 164
Chapter 52: Stack and Heap ............................................................................................................................... 167
Section 52.1: Value types in use ............................................................................................................................... 167
Section 52.2: Reference types in use ...................................................................................................................... 167
Chapter 53: Work with SHA1 in C# ................................................................................................................... 169
Section 53.1: #Generate SHA1 checksum of a file .................................................................................................. 169
Section 53.2: #Generate hash of a text ................................................................................................................... 169
Chapter 54: Garbage Collection ....................................................................................................................... 170
Section 54.1: A basic example of (garbage) collection ......................................................................................... 170
Section 54.2: Live objects and dead objects - the basics ..................................................................................... 170
Section 54.3: Multiple dead objects ......................................................................................................................... 171
Section 54.4: Weak References ............................................................................................................................... 171
Section 54.5: Dispose() vs. finalizers ....................................................................................................................... 172
Section 54.6: Proper disposal and finalization of objects ..................................................................................... 173
Chapter 55: Reading and writing Zip files ................................................................................................... 175
Section 55.1: Listing ZIP contents ............................................................................................................................. 175
Section 55.2: Extracting files from ZIP files ............................................................................................................ 175
Section 55.3: Updating a ZIP file .............................................................................................................................. 175
Chapter 56: Write to and read from StdErr stream ............................................................................... 177
Section 56.1: Write to standard error output using Console ................................................................................. 177
Section 56.2: Read from standard error of child process ..................................................................................... 177
Chapter 57: Upload file and POST data to webserver ......................................................................... 178
Section 57.1: Upload file with WebRequest ............................................................................................................. 178
Appendix A: Acronym Glossary ......................................................................................................................... 180
Section A.1: .Net Related Acronyms ........................................................................................................................ 180
Credits ............................................................................................................................................................................ 181
You may also like ...................................................................................................................................................... 184
About
Please feel free to share this PDF with anyone for free,
latest version of this book can be downloaded from:
https://goalkicker.com/DotNETFrameworkBook
This .NET Framework Notes for Professionals book is compiled from Stack Overflow
Documentation, the content is written by the beautiful people at Stack Overflow.
Text content is released under Creative Commons BY-SA, see credits at the end
of this book whom contributed to the various chapters. Images may be copyright
of their respective owners unless otherwise specified
This is an unofficial free book created for educational purposes and is not
affiliated with official .NET Framework group(s) or company(s) nor Stack
Overflow. All trademarks and registered trademarks are the property of their
respective company owners
class Program
{
// The Main() function is the first function to be executed in a program
static void Main()
{
// Write the string "Hello World to the standard out
Console.WriteLine("Hello World");
}
}
Console.WriteLine has several overloads. In this case, the string "Hello World" is the parameter, and it will output
the "Hello World" to the standard out stream during execution. Other overloads may call the .ToString of the
Introduction to C#
[<EntryPoint>]
let main argv =
printfn "Hello World"
0
Introduction to F#
Module Program
Public Sub Main()
Console.WriteLine("Hello World")
End Sub
End Module
Introduction to PowerShell
import clr
from System import Console
Console.WriteLine("Hello World")
interface
type
App = class
public
class method Main(args: array of String);
end;
implementation
end.
Internally, the C# compiler actually converts this initialization to a series of calls to the Add method. Consequently,
you can use this syntax only for collections that actually support the Add method.
For complex collections such as the Dictionary<TKey, TValue> class, that take key/value pairs, you can specify
each key/value pair as an anonymous type in the initializer list.
The first item in each pair is the key, and the second is the value.
using System.Collections.Generic;
string value;
value = stack.Pop(); // return Ringo
value = stack.Pop(); // return George
value = stack.Pop(); // return Paul
value = stack.Pop(); // return John
There is a non generic version of the type, which works with objects.
using System.Collections;
object value;
value = stack.Pop(); // return Product (Product type)
value = stack.Pop(); // return true (bool)
value = stack.Pop(); // return 1d (double)
value = stack.Pop(); // return 5 (int)
value = stack.Pop(); // return Hello World (string)
There is also a method called Peek() which returns the last element added but without removing it from the Stack.
It is possible to iterate on the elements on the stack and it will respect the order of the stack (LIFO).
50
40
30
20
10
Here we have a Class with no constructor with two properties: Name and a nullable boolean property Selected. If we
wanted to initialize a List<Model>, there are a few different ways to execute this.
Here, we are creating several new instances of our Model class, and initializing them with data. What if we added a
constructor?
Notice we reverted the constructor on the Model class to simplify the example a little bit.
using System.Collections.Generic;
string dequeueValue;
dequeueValue = queue.Dequeue(); // return John
dequeueValue = queue.Dequeue(); // return Paul
dequeueValue = queue.Dequeue(); // return George
dequeueValue = queue.Dequeue(); // return Ringo
There is a non generic version of the type, which works with objects.
using System.Collections;
object dequeueValue;
dequeueValue = queue.Dequeue(); // return Hello World (string)
dequeueValue = queue.Dequeue(); // return 5 (int)
dequeueValue = queue.Dequeue(); // return 1d (double)
dequeueValue = queue.Dequeue(); // return true (bool)
dequeueValue = queue.Dequeue(); // return Product (Product type)
10
20
30
40
50
[XmlIgnore]
public DateTime Birth {get; set;}
[XmlElement(ElementName="Birth")]
public string BirthString
{
get { return Birth.ToString(_birthStringFormat); }
set { Birth = DateTime.ParseExact(value, _birthStringFormat, CultureInfo.InvariantCulture);
}
}
}
Sometimes we can't provide all of the required metadata needed for the XmlSerializer framework in attribute.
Suppose we have a base class of serialized objects, and some of the derived classes are unknown to the base class.
We can't place an attribute for all of the classes which are not know at the design time of the base type. We could
have another team developing some of the derived classes.
What can we do
We can use new XmlSerializer(type, knownTypes), but that would be a O(N^2) operation for N serializers, at least
to discover all of the types supplied in arguments:
In this example, the the Base type is not aware of it's derived types, which is normal in OOP.
Doing it efficiently
Luckily, there is a method which addresses this particular problem - supplying known types for multiple serializers
efficiently:
The FromTypes method allows you to efficiently create an array of XmlSerializer objects for processing an
array of Type objects.
Output:
0
0
This error message recommends what we tried to avoid (or what we can not do in some scenarios) - referencing
derived types from base class:
Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
<Base xsi:type="Derived">
Base corresponds to the property type declared in the Container type, and Derived being the type of the instance
actually supplied.
class HttpGet
{
private static async Task DownloadAsync(string fromUrl, string toFile)
{
using (var fileStream = File.OpenWrite(toFile))
{
using (var httpClient = new HttpClient())
{
Console.WriteLine("Connecting...");
using (var networkStream = await httpClient.GetStreamAsync(fromUrl))
{
Console.WriteLine("Downloading...");
await networkStream.CopyToAsync(fileStream);
await fileStream.FlushAsync();
}
}
}
}
Console.WriteLine("Done!");
}
}
byte[] responseBody;
byte[] requestBodyBytes = Encoding.UTF8.GetBytes(requestBodyString);
// remember that the stack trace of the outer Exception will point to the
// next line
// you'll need to examine the InnerException property to get the stack trace
// to the line that actually started the problem
You can filter by exception type and even by exception properties (new in C# 6.0, a bit longer available in VB.NET
(citation needed)):
Documentation/C#/new features
It can be utilized to free or clean up resources acquired in the try { ... } block safely.
try
{
fileStream = File.Open(filename);
}
catch (FileNotFoundException)
{
Console.WriteLine("File '{0}' could not be found.", filename);
}
finally
{
if (fileStream != null)
{
fileStream.Dispose();
}
}
This is similar to using a simple if but does not unwind the stack if the condition inside the when is not met.
Example
try
{
// ...
}
catch (Exception e) when (e.InnerException != null) // Any condition can go in here.
{
// ...
}
The same info can be found in the C# 6.0 Features here: Exception filters
try {...}
catch (Exception ex) {
// Note: the ex variable is *not* used
throw;
}
A common anti-pattern is to instead throw ex, which has the effect of limiting the next exception handler's view of
the stack trace:
try {...}
catch (Exception ex) {
// Note: the ex variable is thrown
// future stack traces of the exception will not see prior calls
throw ex;
}
In general using throw ex isn't desirable, as future exception handlers which inspect the stack trace will only be
able to see calls as far back as throw ex. By omitting the ex variable, and using the throw keyword alone the
original exception will "bubble-up".
using System.Runtime.ExceptionServices;
void Main()
{
ExceptionDispatchInfo capturedException = null;
try
{
throw new Exception();
}
catch (Exception ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
}
Foo(capturedException);
}
if (capturedException != null)
{
// Exception stack trace will show it was thrown from Main() and not from Foo()
exceptionDispatchInfo.Throw();
}
The caller can handle these exceptions by "catching" them, and should only do so when:
It should be noted that choosing not to catch an exception is perfectly valid if the intention is for it to be handled at
a higher level.
Catching an exception is done by wrapping the potentially-throwing code in a try { ... } block as follows, and
catching the exceptions it's able to handle in a catch (ExceptionType) { ... } block:
Stream fileStream;
try
{
fileStream = File.Open(filename);
}
catch (FileNotFoundException)
{
Console.WriteLine("File '{0}' could not be found.", filename);
}
Lambda expressions passed to Enumerable.Select must return a single item. Lambda expressions passed to
Enumerable.SelectMany must produce a child sequence. This child sequence may contain a varying number of
elements for each element in the input sequence.
Example
class Invoice
{
public int Id { get; set; }
}
class Customer
{
public Invoice[] Invoices {get;set;}
}
Console.WriteLine(
string.Join(",", allInvoicesFromAllCustomers.Select(i => i.Id).ToArray()));
Output:
View Demo
Enumerable.SelectMany can also be achieved with a syntax-based query using two consecutive from clauses:
var allInvoicesFromAllCustomers
= from customer in customers
from invoice in customer.Invoices
select invoice;
Example
Output:
Foo,Fizz
View Demo
class Project
{
public int DeveloperId { get; set; }
public string Name { get; set; }
}
Console.WriteLine(string.Join(",", result));
//1, 2, 3, 4, 5, 7, 9
Console.WriteLine(string.Join(",", sums));
//11,22,33,44,55
Console.WriteLine(commaSeparatedElements); //1,2,3,4,5,
Console.WriteLine(commaSeparatedElements2.ToString()); //1,2,3,4,5,
Console.WriteLine(commaSeparatedElements4); //12,3,4,5,
Console.WriteLine(string.Join(",", numbers5to10));
//5,6,7,8,9,10
Console.WriteLine(string.Join(",", numbers1to8));
//1,2,3,4,5,4,5,6,7,8
Note that duplicates are kept in the result. If this is undesirable, use Union instead.
Note that the All method functions by checking for the first element to evaluate as false according to the
predicate. Therefore, the method will return true for any predicate in the case that the set is empty:
Console.WriteLine(string.Join(",", distinctNumbers));
//1,2,3,4,5
This does not compile since ArrayList does not implement IEnumerable<T>:
Cast does not perform conversion casts. The following compiles but throws InvalidCastException at runtime:
// prints 1,2,3,4,5,6,7,8,9,10
Console.WriteLine(string.Join(",", Enumerable.Range(1, 10)));
// prints 10,11,12,13,14
Console.WriteLine(string.Join(",", Enumerable.Range(10, 5)));
/* output:
Hello
Hello
Hello
Hello
*/
//Foo,Bar,Fizz,Buzz
//2,4,3,1
//1,3,4,2
The following throws InvalidOperationException since there is more than one element in the sequence:
//3,4,5
//1,2,3
Console.WriteLine(string.Join(",", reversed.ToArray()));
//5,4,3,2,1
Console.WriteLine(string.Join(",", numbers.ToArray()));
//1,2,3,4
Group invoices by country, generating a new object with the number of record, total paid, and average paid
Specifying just a key selector function will create a Dictionary<TKey,TVal> with TKey the return Type of the key
selector, TVal the original object Type, and the original object as the stored value.
Console.WriteLine(personsById[1].Name); //Fizz
Console.WriteLine(personsById[2].Name); //Buzz
Specifying a value selector function as well will create a Dictionary<TKey,TVal> with TKey still the return type of
the key selector, but TVal now the return type of the value selector function, and the returned value as the stored
value.
Console.WriteLine(namesById[3]); //Foo
Console.WriteLine(namesById[4]); //Bar
As stated above, the keys returned by the key selector must be unique. The following will throw an exception.
If a unique key can not be given for the source collection, consider using ToLookup instead. On the surface,
ToLookup behaves similarly to ToDictionary, however, in the resulting Lookup each key is paired with a collection of
values with matching keys.
Console.WriteLine(string.Join(",", numbers1to8));
//1,2,3,4,5,6,7,8
Note that duplicates are removed from the result. If this is undesirable, use Concat instead.
Console.WriteLine(someNumbers.GetType().Name);
//WhereArrayIterator`1
Console.WriteLine(someNumbersArray.GetType().Name);
//Int32[]
Console.WriteLine(someNumbers.GetType().Name);
//WhereArrayIterator`1
Console.WriteLine(
someNumbersList.GetType().Name + " - " +
someNumbersList.GetType().GetGenericArguments()[0].Name);
//List`1 - Int32
Console.WriteLine(string.Join(",", oddNumbers.ToArray()));
//1,3,5,7
Console.WriteLine(string.Join(",", evenNumbers.ToArray()));
//2,4,6
class Project
{
public int DeveloperId { get; set; }
public string Name { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
class TcpChat
{
static void Main(string[] args)
{
if(args.Length == 0)
{
Console.WriteLine("Basic TCP chat");
Console.WriteLine();
Console.WriteLine("Usage:");
Console.WriteLine("tcpchat server <port>");
Console.WriteLine("tcpchat client <url> <port>");
return;
}
try
{
Run(args);
}
catch(IOException)
{
Console.WriteLine("--- Connection lost");
}
catch(SocketException ex)
{
Console.WriteLine("--- Can't connect: " + ex.Message);
}
}
if(args[0].StartsWith("s", StringComparison.InvariantCultureIgnoreCase))
{
var port = int.Parse(args[1]);
var listener = new TcpListener(IPAddress.Any, port);
listener.Start();
Console.WriteLine("--- Waiting for a connection...");
client = listener.AcceptTcpClient();
}
else
{
var hostName = args[1];
var port = int.Parse(args[2]);
client = new TcpClient();
client.Connect(hostName, port);
stream = client.GetStream();
Console.WriteLine("--- Connected. Start typing! (exit with Ctrl-C)");
while(true)
{
if(Console.KeyAvailable)
{
var lineToSend = Console.ReadLine();
var bytesToSend = encoding.GetBytes(lineToSend + "\r\n");
stream.Write(bytesToSend, 0, bytesToSend.Length);
stream.Flush();
}
if (stream.DataAvailable)
{
var receivedBytesCount = stream.Read(buffer, 0, buffer.Length);
var receivedString = encoding.GetString(buffer, 0, receivedBytesCount);
Console.Write(receivedString);
}
}
}
}
using System;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Sockets;
class SntpClient
{
const int SntpPort = 123;
static DateTime BaseDate = new DateTime(1900, 1, 1);
double localTimeZoneInHours = 0;
if(args.Length > 1)
localTimeZoneInHours = double.Parse(args[1], CultureInfo.InvariantCulture);
byte[] sntpResponse;
try
{
IPEndPoint remoteEndpoint = null;
sntpResponse = udpClient.Receive(ref remoteEndpoint);
}
catch(SocketException)
{
Console.WriteLine("*** No response received from the server");
return;
}
uint numberOfSeconds;
if(BitConverter.IsLittleEndian)
numberOfSeconds = BitConverter.ToUInt32(
sntpResponse.Skip(40).Take(4).Reverse().ToArray()
,0);
else
numberOfSeconds = BitConverter.ToUInt32(sntpResponse, 40);
Console.WriteLine(
$"Current date in server: {date:yyyy-MM-dd HH:mm:ss}
UTC{localTimeZoneInHours:+0.#;-0.#;.}");
}
}
Starting with Visual Studio 2012, NuGet is included in every edition, and can be used from: Tools -> NuGet Package
Manager -> Package Manager Console.
You do so through the Tools menu of Visual Studio, clicking Extensions and Updates:
Available through clicking "Manage NuGet Packages..." on a project or its References folder
Here you can issue, amongst others, install-package commands which installs the entered package into the
currently selected "Default project":
Install-Package Elmah
You can also provide the project to install the package to, overriding the selected project in the "Default project"
dropdown:
using System.Reflection;
Assemblies are self-documenting: they do not only contain types, methods and their IL code, but also the Metadata
necessary to inspect and consume them, both at compile and runtime:
Console.WriteLine(typeof(int).Assembly.FullName);
// Will print: "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
If this name includes a PublicKeyToken, it is called a strong name. Strong-naming an assembly is the process of
creating a signature by using the private key that corresponds to the public key distributed with the assembly. This
signature is added to the Assembly manifest, which contains the names and hashes of all the files that make up the
assembly, and its PublicKeyToken becomes part of the name. Assemblies that have the same strong name should
be identical; strong names are used in versioning and to prevent assembly conflicts.
return true;
}
return accumulator;
}
}
Note: this example do a field based comparasion (ignore static fields and properties) for simplicity
T variable = Activator.CreateInstance(typeof(T));
// Get the custom attributes of the type desired found on the struct.
T[] attribs = (T[])fieldInfo.GetCustomAttributes(typeof(T), false);
return result;
}
}
// To safely add items (check to ensure item does not already exist - would throw)
if(!dict.ContainsKey(3))
{
dict.Add(3, "Third");
}
Alternatively they can be added/set via the an indexer. (An indexer internally looks like a property, having a get and
set, but takes a parameter of any type which is specified between the brackets) :
Unlike the Add method which throws an exception, if a key is already contained in the dictionary, the indexer just
replaces the existing value.
You may want to read the value for the entry with key 1. If key doesn't exist getting a value will throw
KeyNotFoundException, so you may want to first check for that with ContainsKey:
if (dict.ContainsKey(1))
Console.WriteLine(dict[1]);
This has one disadvantage: you will search through your dictionary twice (once to check for existence and one to
read the value). For a large dictionary this can impact performance. Fortunately both operations can be performed
together:
string value;
if (dict.TryGetValue(1, out value))
Console.WriteLine(value);
using System;
using System.Collections.Generic;
using System.Linq;
Using Keys
Using Values
Represents a thread-safe collection of key/value pairs that can be accessed by multiple threads
concurrently.
Creating an instance
Creating an instance works pretty much the same way as with Dictionary<TKey, TValue>, e.g.:
Adding or Updating
You might be surprised, that there is no Add method, but instead there is AddOrUpdate with 2 overloads:
(1) AddOrUpdate(TKey key, TValue, Func<TKey, TValue, TValue> addValue) - Adds a key/value pair if the key does
not already exist, or updates a key/value pair by using the specified function if the key already exists.
Adding or updating a value, no matter what was the value if it was already present for given key (1):
Adding or updating a value, but now altering the value in update, based on the previous value (1):
string addedValue3 = dict.AddOrUpdate(1, (key) => key == 1 ? "First" : "Not First", (updateKey,
valueOld) => $"{valueOld} Updated");
Getting value
There are two mehod overloads, that will get or add a value in a thread-safe manner.
Get value with key 2, or add value "Second" if the key is not present:
Executing this code removes the key 2 and it's value from the dictionary. Remove returns a boolean value indicating
whether the specified key was found and removed from the dictionary. If the key does not exist in the dictionary,
nothing is removed from the dictionary, and false is returned (no exception is thrown).
It's incorrect to try and remove a key by setting the value for the key to null.
This will not remove the key. It will just replace the previous value with a value of null.
To remove all keys and values from a dictionary, use the Clear method.
dict.Clear();
After executing Clear the dictionary's Count will be 0, but the internal capacity remains unchanged.
if (dictionary.ContainsKey("C2"))
{
// exists
}
ConcurrentDictionary shines when it comes to instantly returning of existing keys from cache, mostly lock free, and
contending on a granular level. But what if the object creation is really expensive, outweighing the cost of context
switching, and some cache misses occur?
If the same key is requested from multiple threads, one of the objects resulting from colliding operations will be
eventually added to the collection, and the others will be thrown away, wasting the CPU resource to create the
object and memory resource to store the object temporarily. Other resources could be wasted as well. This is really
bad.
We can combine ConcurrentDictionary<TKey, TValue> with Lazy<TValue>. The idea is that ConcurrentDictionary
GetOrAdd method can only return the value which was actually added to the collection. The loosing Lazy objects
could be wasted in this case too, but that's not much problem, as the Lazy object itself is relatively unexpensive. The
Value property of the losing Lazy is never requested, because we are smart to only request the Value property of
the one actually added to the collection - the one returned from the GetOrAdd method:
Caching of XmlSerializer objects can be particularly expensive, and there is a lot of contention at the application
startup too. And there is more to this: if those are custom serializers, there will be a memory leak too for the rest of
the process lifecycle. The only benefit of the ConcurrentDictionary in this case is that for the rest of the process
lifecycle there will be no locks, but application startup and memory usage would be inacceptable. This is a job for
our ConcurrentDictionary, augmented with Lazy:
2 - Create a file named project.json with the following content (adjust the port number and rootDirectory as
appropriate):
{
"dependencies": {
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:60000"
},
"frameworks": {
"dnxcore50": { }
},
"fileServer": {
"rootDirectory": "c:\\users\\username\\Documents"
}
}
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.StaticFiles;
using Microsoft.Extensions.Configuration;
Note: These commands need to be run only once. Use dnvm list to check the actual number of the latest installed
version of the core CLR.
5 - Start the server with: dnx web. Files can now be requested at http://localhost:60000/path/to/file.ext.
For simplicity, filenames are assumed to be all ASCII (for the filename part in the Content-Disposition header) and
file access errors are not handled.
For simplicity, filenames are assumed to be all ASCII (for the filename part in the Content-Disposition header) and file
access errors are not handled.
using System;
using System.IO;
using System.Net;
class HttpFileServer
{
private static HttpListenerResponse response;
private static HttpListener listener;
private static string baseFilesystemPath;
if(args.Length < 2)
{
Console.WriteLine("Basic read-only HTTP file server");
Console.WriteLine();
Console.WriteLine("Usage: httpfileserver <base filesystem path> <port>");
Console.WriteLine("Request format: http://url:port/path/to/file.ext");
return;
}
baseFilesystemPath = Path.GetFullPath(args[0]);
var port = int.Parse(args[1]);
if (request.HttpMethod.ToUpper() != "GET")
{
SendErrorResponse(405, "Method must be GET");
continue;
}
response.OutputStream.Close();
response = null;
Console.WriteLine(" Ok!");
}
}
The ConfigurationSettings class was the original way to retrieve settings for an assembly in .NET 1.0 and 1.1. It has
been superseded by the ConfigurationManager class and the WebConfigurationManager class.
If you have two keys with the same name in the appSettings section of the configuration file, the last one is used.
app.config
Program.cs
using System;
using System.Configuration;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
string keyValue = ConfigurationSettings.AppSettings["keyName"];
Debug.Assert("anything, as a string".Equals(keyValue));
Console.ReadKey();
}
}
}
app.config
Program.cs
using System;
using System.Configuration;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
string keyValue = ConfigurationManager.AppSettings["keyName"];
Debug.Assert("anything, as a string".Equals(keyValue));
Console.ReadKey();
}
}
}
1. Settings can be made strongly typed. Any type which can be serialized can be used for a settings value.
2. Application settings can be easily separated from user settings. Application settings are stored in a single
configuration file: web.config for Web sites and Web applications, and app.config, renamed as
assembly.exe.config, where assembly is the name of the executable. User settings (not used by Web projects)
are stored in a user.config file in the user's Application Data folder (which varies with the operating system
version).
3. Application settings from class libraries can be combined into a single configuration file without risk of name
collisions, since each class library can have its own custom settings section.
In most project types, the Project Properties Designer has a Settings tab which is the starting point for creating
custom application and user settings. Initially, the Settings tab will be blank, with a single link to create a default
settings file. Clicking the link results in these changes:
1. If a configuration file (app.config or web.config) does not exist for the project, one will be created.
2. The Settings tab will be replaced with a grid control which enables you to create, edit, and delete individual
settings entries.
3. In Solution Explorer, a Settings.settings item is added under the Properties special folder. Opening this
4. A new file with a new partial class is added under the Properties folder in the project folder. This new file is
named Settings.Designer.__ (.cs, .vb, etc.), and the class is named Settings. The class is code-generated,
so it should not be edited, but the class is a partial class, so you can extend the class by putting additional
members in a separate file. Furthermore, the class is implemented using the Singleton Pattern, exposing the
singleton instance with the property named Default.
As you add each new entry to the Settings tab, Visual Studio does these two things:
1. Saves the setting in the configuration file, in a custom configuration section designed to be managed by the
Settings class.
2. Creates a new member in the Settings class to read, write, and present the setting in the specific type
selected from the Settings tab.
Add an application setting named ExampleTimeout, using the time System.Timespan, and set the value to 1 minute:
Save the Project Properties, which saves the Settings tab entries, as well as re-generates the custom Settings class
and updates the project configuration file.
Program.cs
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
TimeSpan exampleTimeout = Settings.Default.ExampleTimeout;
Debug.Assert(TimeSpan.FromMinutes(1).Equals(exampleTimeout));
Console.ReadKey();
}
}
}
Look in the project configuration file to see how the application setting entry has been created:
Notice that the appSettings section is not used. The applicationSettings section contains a custom namespace-
qualified section that has a setting element for each entry. The type of the value is not stored in the configuration
file; it is only known by the Settings class.
Look in the Settings class to see how it uses the ConfigurationManager class to read this custom section.
...
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00:01:00")]
public global::System.TimeSpan ExampleTimeout {
get {
return ((global::System.TimeSpan)(this["ExampleTimeout"]));
Notice that a DefaultSettingValueAttribute was created to stored the value entered in the Settings tab of the
Project Properties Designer. If the entry is missing from the configuration file, this default value is used instead.
It is worth noting that if you do not call collection.CompleteAdding();, you are able to keep adding to the
collection even if your consumer task is running. Just call collection.CompleteAdding(); when you are sure there
are no more additions. This functionality can be used to make a Multiple Producer to a Single Consumer pattern
where you have multiple sources feeding items into the BlockingCollection and a single consumer pulling items out
and doing something with them. If your BlockingCollection is empty before you call complete adding, the
Enumerable from collection.GetConsumingEnumerable() will block until a new item is added to the collection or
BlockingCollection.CompleteAdding(); is called and the queue is empty.
Task.WaitAll(producerTask, consumerTask);
Console.WriteLine("Everything completed!");
try
{
Parallel.Invoke(actions);
}
catch(AggregateException ex)
{
foreach(var inner in ex.InnerExceptions)
Console.WriteLine("Task failed: " + inner.Message);
return sum;
});
If the Task execute asynchronously than awaiting the Task returns it's result.
using System.Threading;
int Foo()
{
int total = 0;
var numbers = Enumerable.Range(1, 10000).ToList();
Parallel.ForEach(numbers,
() => 0, // initial value,
(num, state, localSum) => num + localSum,
localSum => Interlocked.Add(ref total, localSum));
return total; // total = 50005000
}
using System.Threading;
int Foo()
{
int total = 0;
Parallel.For(1, 10001,
Console.WriteLine("Starting task...");
task.Start();
task.Wait();
Console.WriteLine("Task completed!");
Console.WriteLine("Starting task...");
var task = Task.Run(() =>
{
Console.WriteLine("Task code starting...");
Thread.Sleep(2000);
Console.WriteLine("...task code ending!");
});
task.Wait();
Console.WriteLine("Task completed!");
Note that only in the first case it is necessary to explicitly invoke Start.
void Main()
{
// this does not affect other tasks - values are local relative to the branches of execution flow
Task.Run(() => user.Value = "user from another task");
Task.Run(() =>
{
// outputs "user from task1" - value has flown from main method to task1
// than value was changed and flown to this task.
Console.WriteLine(user.Value);
}).Wait();
});
task1.Wait();
// outputs "initial user" - changes do not propagate back upstream the execution flow
Console.WriteLine(user.Value);
}
Note: As can be seen from the example above AsynLocal.Value has copy on read semantic, but if you flow some
reference type and change its properties you will affect other tasks. Hence, best practice with AsyncLocal is to use
value types or immutable types.
while(pendingTasks.Length > 0)
{
var finishedTask = pendingTasks[Task.WaitAny(pendingTasks)];
Console.WriteLine("Task {0} finished", finishedTask.Result);
pendingTasks = pendingTasks.Except(new[] {finishedTask}).ToArray();
}
Task.WaitAll(allTasks);
Note: The final WaitAll is necessary becasue WaitAny does not cause exceptions to be observed.
Console.WriteLine("Starting tasks...");
try
{
Task.WaitAll(task1, task2);
}
catch(AggregateException ex)
{
Console.WriteLine("Task(s) failed!");
foreach(var inner in ex.InnerExceptions)
Console.WriteLine(inner.Message);
}
Console.WriteLine("Starting tasks...");
while(tasks.All(task => !task.IsCompleted));
cancellationTokenSource.Cancel();
try
{
task.Wait();
}
catch(AggregateException ex)
{
ex.Handle(inner => inner is OperationCanceledException);
}
Note how the cancellation token is passed to the task constructor in the cancellationToken parameter. This is
needed so that the task transitions to the Canceled state, not to the Faulted state, when
ThrowIfCancellationRequested is invoked. Also, for the same reason, the cancellation token is explicitly supplied
in the constructor of OperationCanceledException in the second case.
await Task.WhenAll(tasks);
Console.WriteLine("All tasks finished!");
Passed by value means that the value of the parameter is copied for the method, and any changes made to the
parameter in the method are not reflected outside of the method. For instance, consider the following code, which
calls a method named AddNumbers, passing in the variables a and b, which are of type int, which is a Value type.
int a = 5;
int b = 6;
AddNumbers(a,b);
Even though we added 5 to x inside the method, the value of a remains unchanged, because it's a Value type, and
that means x was a copy of a's value, but not actually a.
Remember, Value types live on the stack, and are passed by value.
Passed by reference means that a reference to the parameter is passed to the method, and any changes to the
parameter will be reflected outside of the method when it returns, because the reference is to the exact same object
in memory. Let's use the same example as before, but we'll "wrap" the ints in a class first.
AddNumbers(instanceOfMyClass);
This time, when we changed sample.a to 10, the value of instanceOfMyClass.a also changes, because it was passed
by reference. Passed by reference means that a reference (also sometimes called a pointer) to the object was passed
into the method, instead of a copy of the object itself.
Remember, Reference types live on the heap, and are passed by reference.
11/24/2015 12:00:00 AM
Note that passing CultureInfo.CurrentCulture as the third parameter is identical to passing null. Or, you can
pass a specific culture.
Format Strings
Input string can be in any format that matches the format string
11/24/2015 12:00:00 AM
Any characters that are not format specifiers are treated as literals
11/24/2015 12:00:00 AM
11/24/2015 11:01:30 AM
Note that the month and minute values were parsed into the wrong destinations.
Exceptions
ArgumentNullException
FormatException
// Format strings must match the input exactly* (see next section)
var date = DateTime.ParseExact("2015-11-24", "d", null); // Expects 11/24/2015 or 24/11/2015 for
most cultures
If the parse fails, the variable passed as the out parameter is set to the default value, DateTime.MinValue.
DateTime parsedValue;
This method attempts to parse the input string based on the system regional settings and known formats such as
Since this method does not accept culture info, it uses the system locale. This can lead to unexpected results.
False
False
True
Note that if you are in the US, you might be surprised that the parsed result is November 10, not October 11.
Unlike its sibling method, this overload allows a specific culture and style(s) to be specified. Passing null for the
IFormatProvider parameter uses the system culture.
Exceptions
Note that it is possible for this method to throw an exception under certain conditions. These relate to the
parameters introduced for this overload: IFormatProvider and DateTimeStyles.
This overload attempts to parse the input string against a specific format. The input string must match that format
in order to be parsed.
This overload attempts to parse the input string against an array of formats. The input string must match at least
one format in order to be parsed.
using System.Runtime.InteropServices;
Disclaimer: This example is an attempt to show how to guard a managed resource with SafeHandle which
implements IDisposable for you and configures finalizers appropriately. It is very contrived and likely pointless to
allocate a chunk of memory in this manner.
When handling unmanaged resources, you should make sure that they are properly disposed. You can do this by
explicitly calling Dispose() in a finally block, or with a using statement.
StreamReader sr;
string textFromFile;
string filename = "SomeFile.txt";
try
or
string textFromFile;
string filename = "SomeFile.txt";
The latter is the preferred method, and is automatically expanded to the former during compilation.
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace Demo
{
public static class Program
{
public static void Main()
{
using (var catalog = new ApplicationCatalog())
using (var exportProvider = new CatalogExportProvider(catalog))
using (var container = new CompositionContainer(exportProvider))
{
exportProvider.SourceProvider = container;
Other types of catalogs (e.g., DirectoryCatalog) can be used instead of (or in addition to) ApplicationCatalog, to
look in other places for exports that satisfy the imports.
namespace Demo
{
[Export(typeof(IUserProvider))]
public sealed class UserProvider : IUserProvider
{
public ReadOnlyCollection<User> GetAllUsers()
{
return new List<User>
{
new User(0, "admin"),
new User(1, "Dennis"),
This could be defined virtually anywhere; all that matters is that the application knows where to look for it (via the
ComposablePartCatalogs it creates).
namespace Demo
{
public sealed class UserWriter
{
[Import(typeof(IUserProvider))]
private IUserProvider userProvider;
This is a type that has a dependency on an IUserProvider, which could be defined anywhere. Like the previous
example, all that matters is that the application knows where to look for the matching export (via the
ComposablePartCatalogs it creates).
// ...
class DemoAssemblyBuilder
{
public static void Main()
{
// An assembly consists of one or more modules, each of which
// contains zero or more types. This code creates a single-module
// assembly, the most common case. The module contains one type,
// named "MyDynamicType", that has a private field, a property
// that gets and sets the private field, constructors that
// initialize the private field, and a method that multiplies
// a user-supplied number by the private field value and returns
// the result. In C# the type might look like this:
/*
public class MyDynamicType
{
private int m_number;
TypeBuilder tb = mb.DefineType(
"MyDynamicType",
TypeAttributes.Public);
ILGenerator il = mbMyMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Load this - always the first argument of any instance method
il.Emit(OpCodes.Ldfld, fbNumber);
il.Emit(OpCodes.Ldarg_1); // Load the integer argument
il.Emit(OpCodes.Mul); // Multiply the two numbers with no overflow checking
il.Emit(OpCodes.Ret); // Return
// Next, we build the property. This involves building the property itself, as well as the
// getter and setter methods.
PropertyBuilder pbNumber = tb.DefineProperty(
"Number", // Name
PropertyAttributes.None,
typeof(int), // Type of the property
new Type[0]); // Types of indices, if any
il = mbGetNumber.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Load this
il.Emit(OpCodes.Ldfld, fbNumber); // Load the value of this.m_number
il.Emit(OpCodes.Ret); // Return the value
pbNumber.SetGetMethod(mbGetNumber);
// The types from the assembly can be used directly using reflection, or we can save the
assembly to use as a reference
object ourInstance = Activator.CreateInstance(ourType);
Console.WriteLine(ourType.GetProperty("Number").GetValue(ourInstance)); // 42
// Save the assembly for use elsewhere. This is very useful for debugging - you can use e.g.
ILSpy to look at the equivalent IL/C# code.
ab.Save(@"DynamicAssemblyExample.dll");
// Using newly created type
var myDynamicType = tb.CreateType();
var myDynamicTypeInstance = Activator.CreateInstance(myDynamicType);
Console.WriteLine(myDynamicTypeInstance.GetType()); // MyDynamicType
Console.WriteLine(numberField.GetValue(myDynamicTypeInstance)); // 10
}
}
//returns existing item form cache or add the new value if it does not exist.
var cachedItem = _cacheContainer.AddOrGetExisting(key, newValue, policy) as
Lazy<TValue>;
using System.Collections;
using System.Web.Script.Serialization;
// ...
Person person = new Person { PersonName = "Andrius", PersonAge = 99, Address = "Some address" };
string rawJson = JsonConvert.SerializeObject(person);
Console.WriteLine(rawJson); // {"name":"Andrius","age":99}
Notice how properties (and classes) can be decorated with attributes to change their appearance in resulting json
string or to remove them from json string at all (JsonIgnore).
In C#, public identifiers are written in PascalCase by convention. In JSON, the convention is to use camelCase for all
names. You can use a contract resolver to convert between the two.
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
Console.WriteLine(json); // {"name":"Andrius","age":99}
}
using Newtonsoft.Json;
// ...
Serialization
De-serialization
Notice that the keys in the rawJson object have been turned into member variables in the dynamic object.
This is useful in cases where an application can accept/ produce varying formats of JSON. It is however suggested to
use an extra level of validation for the Json string or to the dynamic object generated as a result of serialization/ de-
serialization.
Another serious serializer issue in .net is the self referencing loop. In the case of a student that is enrolled in a
course, its instance has a course property and a course has a collection of students that means a List<Student>
which will create a reference loop. You can handle this with JsonSerializerSettings :
while (!cancellationToken.IsCancellationRequested)
{
var value = random.Next();
await bufferBlock.SendAsync(value, cancellationToken);
}
});
block.Complete(); // Tell the block to complete and stop accepting new items
await block.Completion; // Asynchronously wait until all items completed processingu
// Create a block the accepts a uri and returns its contents as a string
var downloaderBlock = new TransformBlock<string, string>(
// Create a block that accepts the content and prints it to the console
var printerBlock = new ActionBlock<string>(
contents => Console.WriteLine(contents));
// Post urls to the first block which will pass their contents to the second one.
downloaderBlock.Post("http://youtube.com");
downloaderBlock.Post("http://github.com");
downloaderBlock.Post("http://twitter.com");
class Program
{
private static BufferBlock<double> buffer = new BufferBlock<double>();
static void Main (string[] args)
{
//start a task that will every 1 second post a value from the producer to buffer block
var producerTask = Task.Run(async () =>
{
var producer = new Producer();
while(true)
{
buffer.Post(producer.Produce());
await Task.Delay(1000);
}
});
//start a task that will recieve values from bufferblock and consume it
var consumerTask = Task.Run(() =>
{
var consumer = new Consumer();
while(true)
if(File.Exists(filePath))
{
Console.WriteLine("Exists");
}
else
{
Console.WriteLine("Does not exist");
}
}
}
C++ signature:
C# definition
C++ signature
typedef struct
{
int length;
int *data;
} VECTOR;
The data array should be defined as IntPtr and memory should be explicitly allocated with
Marshal.AllocHGlobal() (and freed with Marshal.FreeHGlobal() afterwords):
[StructLayout(LayoutKind.Sequential)]
public struct VECTOR : IDisposable
{
int length;
IntPtr dataBuf;
[DllImport("vectors.dll")]
public static extern void SetVector([In]ref VECTOR vector);
C++ signature:
typedef struct
{
char *name;
} USER;
When such data is passed out of unmanaged code and memory is allocated by the unmanaged functions, the
managed caller should receive it into an IntPrt variable and convert the buffer to a managed array. In case of
strings there is a convenient Marshal.PtrToStringAnsi() method:
[StructLayout(LayoutKind.Sequential)]
public struct USER
{
IntPtr nameBuffer;
public string name { get { return Marshal.PtrToStringAnsi(nameBuffer); } }
}
[DllImport("users.dll")]
public static extern bool GetCurrentUser(out USER user);
C++ declaration
typedef union
{
char c;
C# declaration
[StructLayout(LayoutKind.Explicit)]
public struct CharOrInt
{
[FieldOffset(0)]
public byte c;
[FieldOffset(0)]
public int i;
}
Overlapping a reference value with a value type one is not allowed so you cannot simply use the FieldOffset(0)
text; FieldOffset(0) i; will not compile for
typedef union
{
char text[128];
int i;
} TextOrInt;
and generally you would have to employ custom marshaling. However, in particular cases like this simpler technics
may be used:
[StructLayout(LayoutKind.Sequential)]
public struct TextOrInt
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] text;
public int i { get { return BitConverter.ToInt32(text, 0); } }
}
class PInvokeExample
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint MessageBox(IntPtr hWnd, String text, String caption, int options);
Declare a function as static extern stting DllImportAttribute with its Value property set to .dll name. Don't
forget to use System.Runtime.InteropServices namespace. Then call it as an regular static method.
The Platform Invocation Services will take care of loading the .dll and finding the desired finction. The P/Invoke in
most simple cases will also marshal parameters and return value to and from the .dll (i.e. convert from .NET
datatypes to Win32 ones and vice versa).
Before declaring an extern Windows API function in your code, consider looking for it on pinvoke.net. They most
likely already have a suitable declaration with all supporting types and good examples.
[DllImport("Example.dll")]
static extern void SetArray(
[MarshalAs(UnmanagedType.LPArray, SizeConst = 128)]
byte[] data);
Arrays of string
[DllImport("Example.dll")]
static extern void SetStrArray(string[] textLines);
C# Example...
[ContractClass(typeof(MyInterfaceContract))]
public interface IMyInterface
{
string DoWork(string input);
}
//Never inherit from this contract defintion class
[ContractClassFor(typeof(IMyInterface))]
internal abstract class MyInterfaceContract : IMyInterface
{
private MyInterfaceContract() { }
Under Extensions and Updates search for Code Contracts then install the Code Contracts Tools
Example...
//do work
}
Example...
string GetValue()
{
Contract.Ensures(Contract.Result<string>() != null);
return null;
}
Load() will be called first, and only once, when the form first loads. Show() will be called every time the user
launches the form. Activate() will be called every time the user makes the form active.
Load() will execute before Show() is called, but be warned: calling msgBox() in show can cause that msgBox() to
execute before Load() is finished. It is generally a bad idea to depend on event ordering between Load(),
Show(), and similar.
End Class
Use &, not + for string concatenation. Strings should be studied in some detail as they are widely used.
Never use Application.DoEvents. Pay attention to the 'Caution'. When you reach a point where this seems like
something you must use, ask.
But this timer is not suited for timing. An example would be using it for a countdown. In this example we will
simulate a countdown to three minutes. This may very well be one of the most boringly important examples here.
The reason for the discrepancy is in the documentation, "The Windows Forms Timer component is single-threaded,
and is limited to an accuracy of 55 milliseconds." This is why it shouldn't be used for timing.
By using the timer and stopwatch a little differently we can obtain better results.
There are other timers that can be used as needed. This search should help in that regard.
ToList first
The enumeration (or query) will be evaluated, copying the results into a new list or calling the database. The
method is then called on each item.
This method has obvious memory usage overhead, as an intermediate list is created.
Extension method
Use:
Caution: The Framework's LINQ methods have been designed with the intention of being pure, which means they
do not produce side effects. The ForEach method's only purpose is to produce side effects, and deviates from the
other methods in this aspect. You may consider just using a plain foreach loop instead.
customers.Add(new Customer());
customers.Add(new Customer());
A small optimization may rewrite EnumerateCharacters() extension method specifically for this purpose:
int count = 0;
var enumerator = StringInfo.GetTextElementEnumerator(text);
while (enumerator.MoveNext())
++count;
return count;
}
}
One step further is to count occurrences of each character, if performance aren't an issue you may simply do it
like this (in this example regardless of case):
Conversions are performed by classes derived from System.Text.Encoder and System.Text.Decoder which,
together, can convert to/from another encoding (from a byte X encoded array byte[] to an UTF-16 encoded
System.String and vice-versa).
Because the encoder/decoder usually works very close to each other they're grouped together in a class derived
Examples:
Convert a string to UTF-8
byte[] data = Encoding.UTF8.GetBytes("This is my text");
This code will read content of an UTF-8 encoded text file and save it back encoded as UTF-16. Note that this code is
not optimal if file is big because it will read all its content into memory:
As you may know string is just an array of characters. But if you think that strings equality check and comparison
is made character by character, you are mistaken. This operation is culture specific (see Remarks below): some
character sequences can be treated as equal depending on the culture.
Think twice before short circuiting equality check by comparing Length properties of two strings!
Use overloads of String.Equals method which accept additional StringComparison enumeration value, if you
need to change default behavior.
Note that string comparison (in contrast to character comparison which is culture invariant) must always be
performed according to rules to a specific culture.
if (!enumerator.MoveNext())
yield break;
}
}
The result of this method is also extensively used by debugging tools. If, for some reason, you do not want to
override this method, but want to customize how debugger shows the value of your type, use DebuggerDisplay
Attribute (MSDN):
If you need to perform many operations with string value, use StringBuilder class which is designed for efficient
strings manipulation:
Given a predicate _ => _.Field and a string value "VALUE", create an expression that tests whether or not the
predicate is true.
This method will build an appropriate Equal expression that tests whether or not Field equals "VALUE".
The predicate can be used by including the predicate in a Where extension method.
Because the C# compiler sees that the lambda expression is assigned to an Expression type rather than a delegate
type it generates an expression tree roughly equivalent to this code
The root of the tree is the lambda expression which contains a body and a list of parameters. The lambda has 1
parameter called "a". The body is a single expression of CLR type BinaryExpression and NodeType of Add. This
expression represents addition. It has two subexpressions denoted as Left and Right. Left is the
The expression tree can be compiled into a C# delegate and executed by the CLR
Usually expressions are translated to other languages like SQL, but can be also used to invoke private, protected
and internal members of public or non-public types as alternative to Reflection.
public TestClass
{
public static string StaticPublicField = "StaticPublicFieldValue";
}
It can be then i.e. compiled into a delegate for retrieving field value.
Problem We want to get on the items which have "car" in their description. We need to check it for null before
searching for a string inside but we don't want it to be called excessively, as the computation could be expensive.
using System;
using System.Linq;
using System.Linq.Expressions;
Console.WriteLine(elementIsInterestingExpression.ToString());
var countExpensiveComputations = 0;
Action incCount = () => countExpensiveComputations++;
elements
.Where(
CreateSearchPredicate(
"car",
(Element e) => ExpensivelyComputed(
e, incCount
)
).Compile()
)
.Count();
Output
First thing to note is how the actual propery access, wrapped in an Invoke:
, and this is the only part that touches e.Description, and in place of it, extracted parameter of type string is
passed to the next one:
Another important thing to note here is AndAlso. It computes only the left part, if the first part returns 'false'. It's a
common mistake to use the bitwise operator 'And' instead of it, which always computes both parts, and would fail
with a NullReferenceException in this example.
"Cross-thread operation not valid: Control 'control_name' accessed from a thread other than the thread it
was created on."
Using this example code on a system.windows.forms form will cast an exception with that message:
Instead when you want to change a textbox's text from within a thread that doesn't own it use Control.Invoke or
Control.BeginInvoke. You can also use Control.InvokeRequired to check if invoking the control is necessary.
If you need to do this often, you can write an extension for invokeable objects to reduce the amount of code
necessary to make this check:
And updating the textbox from any thread becomes a bit simpler:
If you need to be sure that textBox1 is updated before continuing, use Control.Invoke instead, which will block the
calling thread until your delegate has been executed. Do note that this approach can slow your code down
significantly if you make many invoke calls and note that it will deadlock your application if your GUI thread is
waiting for the calling thread to complete or release a held resource.
p.Start();
Usage
Output
string currentUsers = "USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME Joe.Bloggs ica-cgp#0 2
On some occasions, access to the server in question may be restricted to certain users. If you have the login
credentials for this user, then it is possible to send queries with this method:
Verb = "runas",
Domain = "doman1.co.za",
UserName = "administrator",
Password = GetPassword()
};
p.Start();
return ss;
}
Notes
Both of the above methods will return a concatenation of STDOUT and STDERR, as OutputDataReceived and
ErrorDataReceived are both appending to the same variable - cmdOut.
using System;
using System.Diagnostics;
public Benchmark()
{
sw = Stopwatch.StartNew();
}
ADO.Net provides a connection-less architecture. It is a secure approach to interact with a database, since, the
connection doesn't have to be maintained during the entire session.
// best practice - always use the correct types when specifying your parameters, Value
is assigned to a DateTime instance and not a string representation of a Date
sc.Parameters.Add(new SqlParameter("@dateOfBirth", SqlDbType.Date){ Value =
newEmployee.DateOfBirth });
// best practice - open your connection as late as possible unless you need to verify
that the database connection is valid and won't fail and the proceeding code execution takes a long
time (not the case here)
con.Open();
sc.ExecuteNonQuery();
}
// the end of the using block will close and dispose the SqlConnection
// best practice - end the using block as soon as possible to release the database connection
}
}
Rule of thumb is to open connection for minimal time. Close the connection explicitly once your procedure
execution is over this will return the connection object back to connection pool. Default connection pool max
size = 100. As connection pooling enhances the performance of physical connection to SQL
Server.Connection Pooling in SQL Server
Wrap all database connections in a using block so they are always closed & disposed even in the event of an
Exception. See using Statement (C# Reference) for more information on using statements
Retrieve the connection strings by name from the app.config or web.config (depending on the application
type)
This requires an assembly reference to System.configuration
See Connection Strings and Configuration Files for additional information on how to structure your
configuration file
Always use parameters for incoming values to
Avoid sql injection attacks
Avoid errors if malformed text is used like including a single quote which is the sql equivalent of
escaping or starting a string (varchar/nvarchar)
Letting the database provider reuse query plans (not supported by all database providers) which
increases efficiency
When working with parameters
Sql parameters type and size mismatch is a common cause of insert/ updated/ select failure
Give your Sql parameters meaningful names just like you do variables in your code
Specify the database data type of the column you are using, this ensures the wrong parameter types is
not used which could lead to unexpected results
Validate your incoming parameters before you pass them into the command (as the saying goes,
"garbage in, garbage out"). Validate incoming values as early as possible in the stack
Use the correct types when assigning your parameter values, example: do not assign the string value
of a DateTime, instead assign an actual DateTime instance to the value of the parameter
Specify the size of string-type parameters. This is because SQL Server can re-use execution plans if the
parameters match in type and size. Use -1 for MAX
Do not use the method AddWithValue, the main reason is it is very easy to forget to specify the
parameter type or the precision/scale when needed. For additional information see Can we stop using
AddWithValue already?
When using database connections
Open the connection as late as possible and close it as soon as possible. This is a general guideline
when working with any external resource
Never share database connection instances (example: having a singleton host a shared instance of
type SqlConnection). Have your code always create a new database connection instance when needed
and then have the calling code dispose of it and "throw it away" when it is done. The reason for this is
Most database providers have some sort of connection pooling so creating new managed
connections is cheap
It eliminates any future errors if the code starts working with multiple threads
// Most ADO.NET objects are disposable and, thus, require the using keyword.
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
// Use parameters instead of string concatenation to add user-supplied
// values to avoid SQL injection and formatting issues. Explicitly supply datatype.
connection.Open();
command.ExecuteNonQuery();
}
Note 1: Please see SqlDbType Enumeration for the MSFT SQL Server-specific variation.
A portable bytecode language called Common Intermediate Language (abbreviated CIL, or IL)
A Just-In-Time compiler that generates machine code
A tracing garbage collector that provides automatic memory management
Support for lightweight sub-processes called AppDomains
Security mechanisms through the concepts of verifiable code and trust levels
Code that runs in the CLR is referred to as managed code to distinguish it from code running outside the CLR
(usually native code) which is referred to as unmanaged code. There are various mechanisms that facilitate
interoperability between managed and unmanaged code.
return processorAffinity;
}
Example of usage :
Console.ReadKey();
}
// Output:
// Process Test.vshost Affinity Mask is : 11111111
Example of usage :
Console.ReadKey();
}
// Output :
// Process Test.vshost Old Affinity Mask is : 11111111
// Process Test.vshost New Affinity Mask is : 10101010
The actual implementation of IGreetingProvider might retrieve a string from an API call or a database. The
implementation of IGreetingWriter might display the greeting in the console. But because Greeter has its
dependencies injected into its constructor, it's easy to write a unit test that injects mocked versions of those
interfaces. In real life we might use a framework like Moq, but in this case I'll write those mocked implementations.
[TestClass]
public class GreeterTests
{
[TestMethod]
public void Greeter_WritesGreeting()
{
var greetingProvider = new TestGreetingProvider();
var greetingWriter = new TestGreetingWriter();
var greeter = new Greeter(greetingProvider, greetingWriter);
greeter.Greet();
Assert.AreEqual(greetingWriter[0], TestGreetingProvider.TestGreeting);
}
}
The behavior of IGreetingProvider and IGreetingWriter are not relevant to this test. We want to test that
Greeter gets a greeting and writes it. The design of Greeter (using dependency injection) allows us to inject mocked
dependencies without any complicated moving parts. All we're testing is that Greeter interacts with those
dependencies as we expect it to.
The Greeting class depends on both IGreetingProvider and IGreetingWriter, but it is not responsible for
creating instances of either. Instead it requires them in its constructor. Whatever creates an instance of Greeting
must provide those two dependencies. We can call that "injecting" the dependencies.
Because dependencies are provided to the class in its constructor, this is also called "constructor injection."
The constructor saves the dependencies as private fields. As soon as the class is instantiated, those
dependencies are available to all other non-static methods of the class.
The private fields are readonly. Once they are set in the constructor they cannot be changed. This indicates
that those fields should not (and cannot) be modified outside of the constructor. That further ensures that
those dependencies will be available for the lifetime of the class.
The dependencies are interfaces. This is not strictly necessary, but is common because it makes it easier to
substitute one implementation of the dependency with another. It also allows providing a mocked version of
the interface for unit testing purposes.
This is not the same thing as using a dependency injection framework (often called a "DI container", "IoC container",
or just "container") like Castle Windsor, Autofac, SimpleInjector, Ninject, Unity, or others.
A container just makes dependency injection easier. For example, suppose you write a number of classes that rely
on dependency injection. One class depends on several interfaces, the classes that implement those interfaces
depend on other interfaces, and so on. Some depend on specific values. And just for fun, some of those classes
Each individual class is well-written and easy to test. But now there's a different problem: Creating an instance of a
class has become much more complicated. Suppose we're creating an instance of a CustomerService class. It has
dependencies and its dependencies have dependencies. Constructing an instance might look something like this:
You might wonder, why not put the whole giant construction in a separate function that just returns
CustomerService? One reason is that because the dependencies for each class are injected into it, a class isn't
responsible for knowing whether those dependencies are IDisposable or disposing them. It just uses them. So if a
we had a GetCustomerService() function that returned a fully-constructed CustomerService, that class might
contain a number of disposable resources and no way to access or dispose them.
And aside from disposing IDisposable, who wants to call a series of nested constructors like that, ever? That's a
short example. It could get much, much worse. Again, that doesn't mean that we wrote the classes the wrong way.
The classes might be individually perfect. The challenge is composing them together.
A dependency injection container simplifies that. It allows us to specify which class or value should be used to fulfill
each dependency. This slightly oversimplified example uses Castle Windsor:
We call this "registering dependencies" or "configuring the container." Translated, this tells our WindsorContainer:
If a class requires ILogWriter, create an instance of LogWriter. LogWriter requires a file path. Use this value
from AppSettings.
When we request a dependency from the container we call that "resolving" a dependency. It's bad practice to do
that directly using the container, but that's a different story. For demonstration purposes, we could now do this:
If it gets to a point where a class requires a dependency that we haven't registered, like IDoesSomethingElse, then
when we try to resolve CustomerService it will throw a clear exception telling us that we haven't registered
anything to fulfill that requirement.
Each DI framework behaves a little differently, but typically they give us some control over how certain classes are
instantiated. For example, do we want it to create one instance of LogWriter and provide it to every class that
depends on ILogWriter, or do we want it to create a new one every time? Most containers have a way to specify
that.
What about classes that implement IDisposable? That's why we call container.Release(customerService); at the
end. Most containers (including Windsor) will step back through all of the dependencies created and Dispose the
ones that need disposing. If CustomerService is IDisposable it will dispose that too.
Registering dependencies as seen above might just look like more code to write. But when we have lots of classes
with lots of dependencies then it really pays off. And if we had to write those same classes without using
dependency injection then that same application with lots of classes would become difficult to maintain and test.
This scratches the surface of why we use dependency injection containers. How we configure our application to use
one (and use it correctly) is not just one topic - it's a number of topics, as the instructions and examples vary from
one container to the next.
3. Add a folder named "locale" to the root of your site. Create a subfolder for each culture you wish to support.
For example, /locale/fr/.
4. In each culture-specific folder, create a text file named messages.po.
5. For testing purposes, enter the following lines of text in your messages.po file:
#: Translation test
msgid "Hello, world!"
msgstr "Bonjour le monde!"
using System.Web.Mvc;
namespace I18nDemo.Controllers
{
public class DefaultController : Controller
{
public ActionResult Index()
{
// Text inside [[[triple brackets]]] must precisely match
// the msgid in your .po file.
return Content("[[[Hello, world!]]]");
}
}
}
7. Run your MVC application and browse to the route corresponding to your controller action, such as
http://localhost:[yourportnumber]/default.
Observe that the URL is changed to reflect your default culture, such as
http://localhost:[yourportnumber]/en/default.
8. Replace /en/ in the URL with /fr/ (or whatever culture you've selected.) The page should now display the
translated version of your text.
9. Change your browser's language setting to prefer your alternate culture and browse to /default again.
Observe that the URL is changed to reflect your alternate culture and the translated text appears.
string fileData;
Note that this StreamReader constructor overload does some auto encoding detection, which may or may not
conform to the actual encoding used in the file.
Please note that there are some convenience methods that read all text from file available on the System.IO.File
class, namely File.ReadAllText(path) and File.ReadAllLines(path).
NOTE: Those are just three of the seven overloads of the constructor for the SerialPort type.
The simplest way is to use the SerialPort.Read and SerialPort.Write methods. However you can also retrieve a
System.IO.Stream object which you can use to stream data over the SerialPort. To do this, use
SerialPort.BaseStream.
Reading
Writing
However you can also send data over like this when needed:
//Note that you can swap out the byte-array with a char-array if you so choose.
byte[] data = new byte[1] { 255 };
port.Write(data, 0, data.Length);
On the first line, we read all the data in the file as a string.
On the second line, we read the data in the file into a string-array. Each line in the file becomes an element in
the array.
On the third we read the bytes from the file.
Next, let's see three different methods of appending data to a file. If the file you specify doesn't exist, each method
will automatically create the file before attempting to append the data to it.
On the first line we simply add a string to the end of the specified file.
On the second line we add each element of the array onto a new line in the file.
Finally on the third line we use File.AppendText to open up a streamwriter which will append whatever data
is written to it.
And lastly, let's see three different methods of writing data to a file. The difference between appending and writing
being that writing over-writes the data in the file while appending adds to the data in the file. If the file you specify
doesn't exist, each method will automatically create the file before attempting to write the data to it.
[TestClass]
public class FizzBuzzFixture
{
[TestMethod]
public void Test1()
{
//arrange
var solver = new FizzBuzzSolver();
//act
var result = solver.FizzBuzz(1);
//assert
Assert.AreEqual("1",result);
}
}
namespace TextEchoService
{
class Program
{
static void Main(string[] args)
{
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
string message = "";
while (message != "quit")
{
message = serialPort.ReadLine();
serialPort.WriteLine(message);
}
namespace AsyncReceiver
{
class Program
{
const byte STX = 0x02;
const byte ETX = 0x03;
const byte ACK = 0x06;
const byte NAK = 0x15;
static ManualResetEvent terminateService = new ManualResetEvent(false);
static readonly object eventLock = new object();
static List<byte> unprocessedBuffer = null;
This program waits for messages enclosed in STX and ETX bytes and outputs the text coming between them.
Everything else is discarded. On write buffer overflow it stops. On other errors it reset input and output buffers and
waits for further messages.
File.Delete(path);
Note that last point (file does not exist) is usually circumvented with a code snippet like this:
if (File.Exists(path))
File.Delete(path);
However it's not an atomic operation and file may be delete by someone else between the call to File.Exists()
and before File.Delete(). Right approach to handle I/O operation requires exception handling (assuming an
alternative course of actions may be taken when operation fails):
if (File.Exists(path))
{
try
{
File.Delete(path);
}
catch (IOException exception)
{
if (!File.Exists(path))
return; // Someone else deleted this file
Note that this I/O errors sometimes are transitory (file in use, for example) and if a network connection is involved
then it may automatically recover without any action from our side. It's then common to retry an I/O operation few
times with a small delay between each attempt:
if (i == NumberOfAttempts)
throw;
Thread.Sleep(DelayBetweenEachAttempt);
}
Note: in Windows environment file will not be really deleted when you call this function, if someone else open the
file using FileShare.Delete then file can be deleted but it will effectively happen only when owner will close the
file.
In this example we read all lines from a file and drop all blank lines then we write back to original path:
File.WriteAllLines(path,
File.ReadAllLines(path).Where(x => !String.IsNullOrWhiteSpace(x)));
If file is too big to load it in memory and output path is different from input path:
File.WriteAllLines(outputPath,
File.ReadLines(inputPath).Where(x => !String.IsNullOrWhiteSpace(x)));
File.Move(@"C:\TemporaryFile.txt", @"C:\TemporaryFiles\TemporaryFile.txt");
However, there are many things that could go wrong with this simple operation. For instance, what if the user
running your program does not have a Drive that is labelled 'C'? What if they did - but they decided to rename it to
'B', or 'M'?
What if the Source file (the file in which you would like to move) has been moved without your knowing - or what if
it simply doesn't exist.
This can be circumvented by first checking to see whether the source file does exist:
This will ensure that at that very moment, the file does exist, and can be moved to another location. There may be
In this example, if you tried to directly update MyTextBox.Text inside the for loop, you would get a threading error.
By posting the UpdateCallback action to the SynchronizationContext, the text box is updated on the same thread
as the rest of the UI.
In practice, progress updates should be performed using an instance of System.IProgress<T>. The default
implementation System.Progress<T> automatically captures the synchronisation context it is created on.
void Main()
{
IProgress<int> p = new Progress<int>(progress =>
{
Console.WriteLine("Running Step: {0}", progress);
});
LongJob(p);
}
Output:
Running Step: 0
Running Step: 3
Running Step: 4
Running Step: 5
Running Step: 6
Running Step: 7
Running Step: 8
Running Step: 9
Running Step: 2
Running Step: 1
Note that when you this code runs, you may see numbers be output out of order. This is because the
IProgress<T>.Report() method is run asynchronously, and is therefore not as suitable for situations where the
progress must be reported in order.
Using LINQ
Note
Typically, you want to maintain the source collection privately and allow public access to the ReadOnlyCollection.
While you could create a ReadOnlyCollection from an in-line list, you would be unable to modify the collection
after you created it.
If you find yourself doing this, you may want to consider using another data structure, such as an
ImmutableCollection.
View Demo
// The customer can't add or remove items, but they can change
// the price of an item, even though it is a ReadOnlyCollection
customerPreview.Last().Price = 0.25m;
View Demo
// true
return Regex.IsMatch(input, pattern);
}
// true
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
}
// World
return match.Groups["Subject"].Value;
}
Code
Output
Carrot
Cherry
Clementine
MyMail.Subject = subject;
MyMail.IsBodyHtml = true;
MyMail.Body = body;
MyMail.Priority = MailPriority.Normal;
smtpMailObj.Send(MyMail);
return true;
using System.Net.Mail;
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
Encryption Code
Usage
Usage
Note:
Section 47.3: Encrypt and decrypt data using AES (in C#)
using System;
using System.IO;
using System.Security.Cryptography;
namespace Aes_Example
{
class AesExample
{
public static void Main()
{
try
{
string original = "Here is some data to encrypt!";
byte[] encrypted;
encrypted = msEncrypt.ToArray();
}
}
}
return plaintext;
}
}
}
It is a console demo application, showing how to encrypt a string by using the standard AES encryption, and how to
decrypt it afterwards.
(AES = Advanced Encryption Standard, a specification for the encryption of electronic data established by the U.S.
National Institute of Standards and Technology (NIST) in 2001 which is still the de-facto standard for symmetric
encryption)
Notes:
To create a good (and not a weak) Key, either use a cryptographic random generator or use the example
above (Create a Key from a Password). The recommended KeySize is 256 bit. Supported key sizes are
available via the LegalKeySizes property.
To initialize the initialization vector IV, you can use a SALT as shown in the example above (Random SALT)
Supported block sizes are available via the SupportedBlockSizes property, the block size can be assigned via
the BlockSize property
try
{
Console.WriteLine("Creating a key with PasswordDeriveBytes...");
Console.WriteLine("Operation complete.");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear the buffers
ClearBytes(pwd);
ClearBytes(salt);
Console.ReadLine();
}
/// <summary>
/// Generates a random salt value of the specified length.
/// </summary>
public static byte[] CreateRandomSalt(int length)
{
// Create a buffer
byte[] randBytes;
if (length >= 1)
{
randBytes = new byte[length];
}
else
{
randBytes = new byte[1];
}
/// <summary>
/// Clear the bytes in a buffer so they can't later be read from memory.
/// </summary>
public static void ClearBytes(byte[] buffer)
{
// Check arguments.
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
#endregion
}
It is a console demo, and it shows how to create a secure key based on a user-defined password, and how to create
a random SALT based on the cryptographic random generator.
The built-in function PasswordDeriveBytes uses the standard PBKDF1 algorithm to generate a key from the
password. Per default, it uses 100 iterations to generate the key to slow down brute force attacks. The SALT
generated randomly further strenghens the key.
The function CryptDeriveKey converts the key generated by PasswordDeriveBytes into a key compatible
with the specified encryption algorithm (here "TripleDES") by using the specified hash algorithm (here
"SHA1"). The keysize in this example is 192 bytes, and the initialization vector IV is taken from the triple-DES
crypto provider
Usually, this mechanism is used to protect a stronger random generated key by a password, which encrypts
large amount of data. You can also use it to provide multiple passwords of different users to give access to
the same data (being protected by a different random key).
//Sequential version
Process(item);
// Parallel equivalent
The above mentioned Parallel.ForEach construct utilizes the multiple cores and thus enhances the performance in
the same fashion.
This yields a Person object with Name "Joe Smith" and Age 21.
When you think of .NET Core the following should come to mind (flexible deployment, cross-platform, command-
line tools, open source).
Another great thing is that even if it's open source Microsoft is actively supporting it.
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
}
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype
[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
All value types are derived from the System.ValueType class, and this includes most of the built in types.
When creating a new value type, the an area of memory called the stack is used.
The stack will grow accordingly, by the size the declared type. So for example, an int will always be allocated 32 bits
of memory on the stack. When the value type is no longer in scope, the space on the stack will be deallocated.
The code below demonstrates a value type being assigned to a new variable. A struct is being used as a convenient
way to create a custom value type (the System.ValueType class cannot be otherwise extended).
The important thing to understand is that when assigning a value type, the value itself copied to the new variable,
meaning we have two distinct instances of the object, that cannot affect each other.
struct PersonAsValueType
{
public string Name;
}
class Program
{
static void Main()
{
PersonAsValueType personA;
personA.Name = "Bob";
personA.Name = "Linda";
In addition to the memory space required for the instance itself, additional space is required to store the reference
The code below demonstrates a reference type being assigned to a new variable. In this instance, we are using a
class, all classes are reference types (even if static).
When a reference type is assigned to another variable, it is the reference to the object that is copied over, not the
value itself. This is an important distinction between value types and reference types.
The implications of this are that we now have two references to the same object.
Any changes to the values within that object will be reflected by both variables.
class PersonAsReferenceType
{
public string Name;
}
class Program
{
static void Main()
{
PersonAsReferenceType personA;
personA.Name = "Linda";
Some of the examples below are "lab cases" to show the Garbage Collector at work and some significant details of
its behavior, while other focus on how to prepare classes for proper handling by the Garbage Collector.
~FinalizableObject()
{
Console.WriteLine("Instance finalized");
}
}
<namespace>.FinalizableObject initialized
If nothing else happens, the object is not finalized until the program ends (which frees all objects on the managed
heap, finalizing these in the process).
<namespace>.FinalizableObject initialized
<namespace>.FinalizableObject finalized
This time, as soon as the Garbage Collector was invoked, the unused (aka "dead") object was finalized and freed
from the managed heap.
<namespace>.FinalizableObject1 initialized
<namespace>.FinalizableObject2 initialized
<namespace>.FinalizableObject1 finalized
At the time when the Garbage Collector is invoked, FinalizableObject1 is a dead object and gets finalized, while
FinalizableObject2 is a live object and it is kept on the managed heap.
<namespace>.FinalizedObject1 initialized
<namespace>.FinalizedObject2 initialized
<namespace>.FinalizedObject1 finalized
<namespace>.FinalizedObject2 finalized
The two objects are finalized and freed from the managed heap despite referencing each other (because no other
reference exists to any of them from an actually live object).
<namespace>.FinalizableObject initialized
The object is freed from the managed heap despite being referenced by the WeakReference variable (still in scope
when the Garbage collector was invoked).
Consequence #1: at any time, it is unsafe to assume whether a WeakReference target is still allocated on the
managed heap or not.
Consequence #2: whenever a program needs to access the target of a Weakreference, code should be provided for
both cases, of the target being still allocated or not. The method to access the target is TryGetTarget:
The generic version of WeakReference is available since .Net 4.5. All framework versions provide a non-generic,
untyped version that is built in the same way and checked as follows:
Another scenario is declaring a class to be instantiated by the framework. In this case the new class usually inherits
a base class, for instance in MVC one creates a controller class as a subclass of System.Web.Mvc.ControllerBase.
When the base class implements IDisposable interface, this is a good hint that Dispose() would be invoked properly
by the framework - but again there is no strong guarantee.
Thus Dispose() is not a substitute for a finalizer; instead, the two should be used for different purposes:
A finalizer eventually frees resources to avoid memory leaks that would occur otherwise
Dispose() frees resources (possibly the same ones) as soon as these are no longer needed, to ease pressure
on overall memory allocation.
One solution is writing the cleanup code in such a way that running it once or twice would produce the same result
as running it only once. Feasibility depends on the nature of the cleanup, for instance:
Closing an already closed database connection would probably have no effect so it works
Updating some "usage count" is dangerous and would produce a wrong result when called twice instead of
once.
A safer solution is ensuring by design that the cleanup code is called once and only once whatever the external
context. This can be achieved the "classic way" using a dedicated flag:
~DisposableFinalizable1() { Cleanup(); }
Alternately, the Garbage Collector provides a specific method SuppressFinalize() that allows skipping the finalizer
after Dispose has been invoked:
There is also the option to write directly to a file within the archive:
};
process.ErrorDataReceived += (s, e) => errors.AppendLine(e.Data);
process.Start();
process.BeginErrorReadLine();
process.WaitForExit();
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
await writer.FlushAsync();
using (var fileStream = File.OpenRead(filename))
await fileStream.CopyToAsync(requestStream);
await writer.WriteAsync($"\r\n--{boundary}--\r\n");
}
Usage:
var response = await uploader.UploadFile("< YOUR URL >", "< PATH TO YOUR FILE >",
new Dictionary<string, object>
{
{"Comment", "test"},
{"Modified", DateTime.Now }