Dot Net Framework PDF
Dot Net Framework PDF
NET Framework
#.net
Table of Contents
About 1
Remarks 2
Versions 2
.NET 2
Compact Framework 3
Micro Framework 3
Examples 3
Hello World in C# 3
Hello World in F# 4
Hello World in IL 5
Introduction 7
Remarks 7
Examples 7
Examples 9
Chapter 4: ADO.NET 10
Introduction 10
Remarks 10
Examples 10
Executing SQL statements as a command 10
Chapter 5: CLR 14
Examples 14
Remarks 15
Examples 15
Preconditions 15
Postconditions 15
Chapter 7: Collections 19
Remarks 19
Examples 19
Queue 20
Stack 22
Remarks 25
Examples 25
Struct Definition 25
Structs inherit from System.ValueType, are value types, and live on the stack. When value 25
Class Definition 26
Classes inherit from System.Object, are reference types, and live on the heap. When refere 26
Enum Definition 26
An enum is a special type of class. The enum keyword tells the compiler that this class in 26
Examples 29
ParseExact 29
TryParse 30
TryParseExact 32
Remarks 33
Examples 34
Examples 39
Enumerating a Dictionary 39
Adding to a Dictionary 40
Creating an instance 41
Adding or Updating 41
Getting value 42
ContainsKey(TKey) 43
Dictionary to List 44
Problem 44
Solution 44
Remarks 46
Examples 46
RijndaelManaged 46
Encrypt and decrypt data using AES (in C#) 47
Remarks 54
Examples 54
Catching an exception 54
Exception Filters 56
Remarks 59
Examples 59
InvocationExpression Class 61
Parameters 64
Remarks 64
Examples 64
VB WriteAllText 64
VB StreamWriter 64
C# StreamWriter 64
C# WriteAllText() 64
C# File.Exists() 65
Remarks 66
Examples 66
Introduction 68
Remarks 68
Examples 68
Weak References 70
Chapter 18: Globalization in ASP.NET MVC using Smart internationalization for ASP.NET 74
Remarks 74
Examples 74
Remarks 76
Examples 76
Examples 80
Introduction 84
Remarks 84
Examples 84
IL compilation sample 84
Introduction 87
Examples 87
Remarks 88
Examples 88
Dynamic binding 90
Introduction 92
Syntax 92
Remarks 99
Lazy Evaluation 99
Examples 100
OrderBy 101
OrderByDescending 101
Contains 101
Except 102
Intersect 102
Concat 102
Last 103
LastOrDefault 103
SingleOrDefault 104
FirstOrDefault 104
Any 104
All 105
Sum 106
Skip 106
Take 107
SequenceEqual 107
Reverse 107
OfType 107
Max 107
Min 108
Average 108
Zip 108
Distinct 109
GroupBy 109
ToDictionary 110
Union 111
ToArray 111
ToList 111
Count 111
ElementAt 112
ElementAtOrDefault 112
SkipWhile 112
TakeWhile 112
DefaultIfEmpty 112
ToLookup 113
Join 114
GroupJoin 115
Cast 116
Empty 117
ThenBy 117
Range 117
Repeat 118
Remarks 119
Examples 119
Remarks 122
Examples 122
Remarks 124
Examples 124
Remarks 127
Examples 127
Introduction 133
Examples 133
Syntax 134
Examples 134
Parameters 138
Remarks 138
Examples 138
Introduction 140
Remarks 140
Examples 140
Remarks 143
Note 144
Examples 146
Examples 149
Using 150
Code 150
Output 150
Examples 151
Examples 155
Introduction to strongly-typed application and user settings support from Visual Studio 156
Syntax 160
Parameters 160
Remarks 161
Examples 161
Remarks 162
Examples 162
Remarks 165
Examples 166
Examples: 168
Remarks 171
Examples 171
Examples 173
Stopwatch 173
Examples 176
Syntax 179
Parameters 179
Examples 179
"Touch" a large amount of files (to update last write time) 181
File.Move 182
Examples 184
MailMessage 184
Examples 186
Examples 189
Remarks 191
Examples 191
Task.WhenAny 195
Task.WhenAll 195
Parallel.Invoke 196
Parallel.ForEach 196
Parallel.For 196
Remarks 199
Examples 199
Examples 200
Remarks 202
Examples 202
Examples 205
Examples 206
Examples 208
Examples 210
Examples 214
Introduction 215
Examples 215
Examples 216
Remarks 217
Examples 217
Efficiently building multiple serializers with derived types specified dynamically 218
Credits 222
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: -net-framework
It is an unofficial and free .NET Framework ebook created for educational purposes. All the
content is extracted from Stack Overflow Documentation, which is written by many hardworking
individuals at Stack Overflow. It is neither affiliated with Stack Overflow nor official .NET
Framework.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/ 1
Chapter 1: Getting started with .NET
Framework
Remarks
The .NET Framework is a set of libraries and a runtime, originally designed by Microsoft. All .NET
programs compile to a bytecode called Microsoft Intermediate Language (MSIL). The MSIL is run
by the Common Language Runtime (CLR).
Below you can find several examples of "Hello World" in various languages that support the .NET
Framework. "Hello World" is a program that displays "Hello World" on the display device. It's used
for illustrating the basic syntax for constructing a working program. It can also be used as a sanity
test to make sure that a language's compiler, development environment, and runtime environment
are all working correctly.
Versions
.NET
1.0 2002-02-13
1.1 2003-04-24
2.0 2005-11-07
3.0 2006-11-06
3.5 2007-11-19
4.0 2010-04-12
4.5 2012-08-15
4.5.1 2013-10-17
4.5.2 2014-05-05
4.6 2015-07-20
4.6.1 2015-11-17
https://riptutorial.com/ 2
Version Release Date
4.6.2 2016-08-02
4.7 2017-04-05
Compact Framework
1.0 2000-01-01
2.0 2005-10-01
3.5 2007-11-19
3.7 2009-01-01
3.9 2013-06-01
Micro Framework
4.2 2011-10-04
4.3 2012-12-04
4.4 2015-10-20
Examples
Hello World in C#
using System;
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
https://riptutorial.com/ 3
may call the .ToString of the argument before writing to the stream. See the .NET Framework
Documentation for more information.
Introduction to C#
Imports System
Module Program
Public Sub Main()
Console.WriteLine("Hello World")
End Sub
End Module
Hello World in F#
open System
[<EntryPoint>]
let main argv =
printfn "Hello World"
0
Introduction to F#
Introduction to PowerShell
https://riptutorial.com/ 4
System.Console.WriteLine("Hello World");
namespace HelloWorld;
interface
type
App = class
public
class method Main(args: array of String);
end;
implementation
end.
import clr
from System import Console
Console.WriteLine("Hello World")
Hello World in IL
https://riptutorial.com/ 5
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
https://riptutorial.com/ 6
Chapter 2: .NET Core
Introduction
.NET Core is a general purpose development platform maintained by Microsoft and the .NET
community on GitHub. It is cross-platform, supporting Windows, macOS and Linux, and can be
used in device, cloud, and embedded/IoT scenarios.
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.
Remarks
By itself, .NET Core includes a single application model -- console apps -- which is useful for tools,
local services and text-based games. Additional application models have been built on top of .NET
Core to extend its functionality, such as:
• ASP.NET Core
• Windows 10 Universal Windows Platform (UWP)
• Xamarin.Forms
Also, .NET Core implements the .NET Standard Library, and therefore supports .NET Standard
Libraries.
The .NET Standard Library is an API spec that describes the consistent set of .NET APIs that
developers can expect in each .NET implementation. .NET implementations need to implement
this spec in order to be considered .NET Standard Library compliant and to support libraries that
target the .NET Standard Library.
Examples
Basic Console App
https://riptutorial.com/ 7
Read .NET Core online: https://riptutorial.com/dot-net/topic/9059/-net-core
https://riptutorial.com/ 8
Chapter 3: Acronym Glossary
Examples
.Net Related Acronyms
Please note that some terms like JIT and GC are generic enough to apply to many programming
language environments and runtimes.
https://riptutorial.com/ 9
Chapter 4: ADO.NET
Introduction
ADO(ActiveX Data Objects).Net is a tool provided by Microsoft which provides access to data
sources such as SQL Server, Oracle, and XML through its components. .Net front-end
applications can retrieve, create, and manipulate data, once they are connected to a data source
through ADO.Net with appropriate privileges.
Remarks
A note on parameterizing SQLs with Parameters.AddWithValue: AddWithValue is never a good
starting point. That method relies on inferring the type of the data from what is passed in. With this,
you might end up in a situation where the conversion prevents your query from using an index.
Note that some SQL Server data types, such as char/varchar (without preceding "n") or date do not
have a corresponding .NET data type. In those cases, Add with the correct data type should be
used instead.
Examples
Executing SQL statements as a command
// 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();
https://riptutorial.com/ 10
command.ExecuteNonQuery();
}
Note 1: Please see SqlDbType Enumeration for the MSFT SQL Server-specific variation.
{
// best practice - use column names in your INSERT statement so you are not dependent
on the sql schema column order
// best practice - always use parameters to avoid sql injection attacks and errors if
malformed text is used like including a single quote which is the sql equivalent of escaping
or starting a string (varchar/nvarchar)
// best practice - give your parameters meaningful names just like you do variables in
your code
using(SqlCommand sc = new SqlCommand("INSERT INTO employee (FirstName, LastName,
DateOfBirth /*etc*/) VALUES (@firstName, @lastName, @dateOfBirth /*etc*/)", con))
{
// best practice - always specify the database data type of the column you are
using
// best practice - check for valid values in your code and/or use a database
constraint, if inserting NULL then use System.DbNull.Value
sc.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar, 200){Value =
newEmployee.FirstName ?? (object) System.DBNull.Value});
sc.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar, 200){Value =
newEmployee.LastName ?? (object) System.DBNull.Value});
// 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 wont 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
}
}
https://riptutorial.com/ 11
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
https://riptutorial.com/ 12
○ 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
https://riptutorial.com/ 13
Chapter 5: CLR
Examples
An introduction to Common Language Runtime
The Common Language Runtime (CLR) is a virtual machine environment and part of the .NET
Framework. It contains:
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.
https://riptutorial.com/ 14
Chapter 6: Code Contracts
Remarks
Code contracts allow for compile or runtime analysis of pre/post conditions of methods and
invariant conditions for objects. These conditions may be used to ensure callers and return value
match valid states for application processing. Other uses for Code Contracts include
documentation generation.
Examples
Preconditions
Preconditions allows methods to provide minimum required values for input parameters
Example...
//do work
}
Postconditions
Postconditions ensure that the returned results from a method will match the provided definition.
This provides the caller with a definition of the expected result. Postconditions may allowed for
simplied implmentations as some possible outcomes can be provided by the static analyizer.
Example...
string GetValue()
{
Contract.Ensures(Contract.Result<string>() != null);
return null;
}
https://riptutorial.com/ 15
Contracts for Interfaces
Using Code Contracts it is possible to apply a contract to an interface. This is done by declaring an
abstract class that implments the interfaces. The interface should be tagged with the
ContractClassAttribute and the contract definition (the abstract class) should be tagged with the
ContractClassForAttribute
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() { }
While System.Diagnostics.Contracts is included within the .Net Framework. To use Code Contracts
you must install the Visual Studio extensions.
https://riptutorial.com/ 16
Under Extensions and Updates search for Code Contracts then install the Code Contracts Tools
After the tools are installed you must enable Code Contracts within your Project solution. At the
minimum you probably want to enable the Static Checking (check after build). If you are
implementing a library that will be used by other solutions you may want to consider also enabling
Runtime Checking.
https://riptutorial.com/ 17
Read Code Contracts online: https://riptutorial.com/dot-net/topic/1937/code-contracts
https://riptutorial.com/ 18
Chapter 7: Collections
Remarks
There are several kinds of collection:
• Array
• List
• Queue
• SortedList
• Stack
• Dictionary
Examples
Creating an initialized List with Custom Types
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?
https://riptutorial.com/ 19
This allows us to initialize our List a little differently.
Notice we reverted the constructor on the Model class to simplify the example a little bit.
Queue
There is a collection in .Net used to manage values in a Queue that uses the FIFO (first-in first-out)
concept. The basics of queues is the method Enqueue(T item) which is used to add elements in the
queue and Dequeue() which is used to get the first element and remove it from the queue. The
generic version can be used like the following code for a queue of strings.
https://riptutorial.com/ 20
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)
There is also a method called Peek() which returns the object at the beginning of the queue
without removing it the elements.
https://riptutorial.com/ 21
10
20
30
40
50
Stack
There is a collection in .Net used to manage values in a Stack that uses the LIFO (last-in first-out)
concept. The basics of stacks is the method Push(T item) which is used to add elements in the
stack and Pop() which is used to get the last element added and remove it from the stack. The
generic version can be used like the following code for a queue of strings.
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)
https://riptutorial.com/ 22
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
Some collection types can be initialized at the declaration time. For example, the following
statement creates and initializes the numbers with some integers:
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.
https://riptutorial.com/ 23
The first item in each pair is the key, and the second is the value.
https://riptutorial.com/ 24
Chapter 8: Custom Types
Remarks
Typically a struct is used only when performance is very important. Since value types live on the
stack, they can be accessed much quicker than classes. However, the stack has much less room
than the heap, so structs should be kept small (Microsoft recommends structs take up no more
than 16 bytes).
A class is the most-used type (of these three) in C#, and is generally what you should go with first.
An enum is used whenever you can have a clearly defined, distinct list of items that only need to be
defined once (at compile time). Enums are helpful to programmers as a lightweight reference to
some value: instead of defining a list of constant variables to compare to, you can use an enum,
and get Intellisense support to make sure you don't accidentally use a wrong value.
Examples
Struct Definition
Struct MyStruct
{
public int x;
public int y;
}
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);
https://riptutorial.com/ 25
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.
Class Definition
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.
Enum Definition
https://riptutorial.com/ 26
items.
You can think of an enum as a convenient way of mapping constants to some underlying value.
The enum defined above declares values for each day of the week, and starts with 1. Tuesday
would then automatically become mapped to 2, Wednesday to 3, etc.
By default, enums use int as the underlying type and start at 0, but you can use any of the
following integral types: byte, sbyte, short, ushort, int, uint, long, or ulong, and can specify
explicit values for any item. If some items are explicitly specified, but some are not, each item after
the last defined one will be incremented by 1.
We would use this example by casting some other value to a MyEnum like so:
int x = 2;
instance = (MyEnum)x; // now 'instance' has a value of MyEnum.Tuesday
Another useful, although more complex, type of enum is called Flags. By decorating an enum with
the Flags attribute, you can assign a variable more than one value at a time. Note that when doing
this you must define values explicitly in base 2 representation.
[Flags]
public enum MyEnum
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
Now you can compare more than one value at a time, either using bitwise comparisons or, if you
are using .NET 4.0 or later, the built-in Enum.HasFlag method.
if (instance.HasFlag(MyEnum.Wednesday))
{
https://riptutorial.com/ 27
// it doesn't, so this block is skipped
}
else if (instance.HasFlag(MyEnum.Thursday))
{
// it does, so this block is executed
}
Since the Enum class is subclassed from System.ValueType, it is treated as a value type and passed
by value, not by reference. The base object is created on the heap, but when you pass an enum
value into a function call, a copy of the value using the underlying value type of the Enum (typically
System.Int32) is pushed onto the stack. The compiler tracks the association between this value
and the base object that was created on the stack. See ValueType Class (System) (MSDN) for
more information.
https://riptutorial.com/ 28
Chapter 9: DateTime parsing
Examples
ParseExact
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
https://riptutorial.com/ 29
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
TryParse
This method accepts a string as input, attempts to parse it into a DateTime, and returns a Boolean
result indicating success or failure. If the call succeeds, the variable passed as the out parameter
is populated with the parsed result.
If the parse fails, the variable passed as the out parameter is set to the default value,
DateTime.MinValue.
DateTime parsedValue;
https://riptutorial.com/ 30
if (DateTime.TryParse("monkey", out parsedValue))
{
Console.WriteLine("Apparently, 'monkey' is a date/time value. Who knew?");
}
This method attempts to parse the input string based on the system regional settings and known
formats such as ISO 8601 and other common formats.
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
https://riptutorial.com/ 31
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.
TryParseExact
This method behaves as a combination of TryParse and ParseExact: It allows custom format(s) to be
specified, and returns a Boolean result indicating success or failure rather than throwing an
exception if the parse fails.
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.
https://riptutorial.com/ 32
Chapter 10: Dependency Injection
Remarks
Problems Solved By Dependency Injection
If we didn't use dependency injection, the Greeter class might look more like this:
It's a "control freak" because it controls creating the class that provides the greeting, it controls
where the SQL connection string comes from, and it controls the output.
Using dependency injection, the Greeter class relinquishes those responsibilities in favor of a
single responsibility, writing a greeting provided to it.
The Dependency Inversion Principle suggests that classes should depend on abstractions (like
interfaces) rather than on other concrete classes. Direct dependencies (coupling) between classes
can make maintenance progressively difficult. Depending on abstractions can reduce that
coupling.
Dependency injection helps us to achieve that dependency inversion because it leads to writing
classes that depend on abstractions. The Greeter class "knows" nothing at all of the
implementation details of IGreetingProvider and IGreetingWriter. It only knows that the injected
dependencies implement those interfaces. That means that changes to the concrete classes that
implement IGreetingProvider and IGreetingWriter will not affect Greeter. Neither will replacing them
with entirely different implementations. Only changes to the interfaces will. Greeter is decoupled.
ControlFreakGreeter is impossible to properly unit test. We want to test one small unit of code, but
instead our test would include connecting to SQL and executing a stored procedure. It would also
include testing the console output. Because ControlFreakGreeter does so much it's impossible to
test in isolation from other classes.
Greeter is easy to unit test because we can inject mocked implementations of its dependencies
that are easier to execute and verify than calling a stored procedure or reading the output of the
console. It doesn't require a connection string in app.config.
https://riptutorial.com/ 33
example, we'd inject the SQL connection string into SqlGreetingProvider.) But that complexity is
"hidden" from other classes which only depend on the interfaces. That makes it easier to modify
one class without a "ripple effect" that requires us to make corresponding changes to other
classes.
Examples
Dependency Injection - Simple example
This class is called Greeter. Its responsibility is to output a greeting. It has two dependencies. It
needs something that will give it the greeting to output, and then it needs a way to output that
greeting. Those dependencies are both described as interfaces, IGreetingProvider and
IGreetingWriter. In this example, those two dependencies are "injected" into Greeter. (Further
explanation following the example.)
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."
https://riptutorial.com/ 34
• 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 builds on the previous example of the Greeter class which has two dependencies,
IGreetingProvider and IGreetingWriter.
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
https://riptutorial.com/ 35
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.
Dependency injection means writing classes so that they do not control their dependencies -
instead, their dependencies are provided to them ("injected.")
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 implement IDisposable and need to be disposed.
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.
https://riptutorial.com/ 36
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.
• If a class requires IAuthorizationRepository, create an instance of SqlAuthorizationRepository.
It requires a connection string. Use this value from the ConnectionStrings section.
• If a class requires ICustomerDataProvider, create a CustomerApiClient and provide the string it
needs 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
https://riptutorial.com/ 37
every time? Most containers have a way to specify that.
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.
https://riptutorial.com/ 38
Chapter 11: Dictionaries
Examples
Enumerating a Dictionary
Using Keys
Using Values
https://riptutorial.com/ 39
Adding to a Dictionary
// 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))
https://riptutorial.com/ 40
Console.WriteLine(value);
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):
Using the overload (2) we can also add new value using a factory:
https://riptutorial.com/ 41
Getting value
Getting a value is the same as with the Dictionary<TKey,TValue>:
Get value with key 2, or add value "Second" if the key is not present:
using System;
using System.Collections.Generic;
using System.Linq;
https://riptutorial.com/ 42
var dict = new Dictionary<int, string>()
{
{ 1, "First" },
{ 2, "Second" },
{ 3, "Third" }
};
Use the Remove method to remove a key and its associated value.
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.
ContainsKey(TKey)
To check if a Dictionary has an specifique key, you can call the method ContainsKey(TKey) and
provide the key of TKey type. The method returns a bool value when the key exists on the
dictionary. For sample:
if (dictionary.ContainsKey("C2"))
{
// exists
}
https://riptutorial.com/ 43
Dictionary to List
Problem
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.
Solution
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:
https://riptutorial.com/ 44
{
return
d.GetOrAdd(
key,
key1 =>
new Lazy<TValue>(() => factory(key1),
LazyThreadSafetyMode.ExecutionAndPublication)).Value;
}
}
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:
https://riptutorial.com/ 45
Chapter 12: Encryption / Cryptography
Remarks
.NET Framework provides implementation of many cryptographic algorithms. They include
basically symmetric algorithms, asymmetric algorithms and hashes.
Examples
RijndaelManaged
https://riptutorial.com/ 46
}
} finally {
aesAlg?.Clear();
}
return encrypt.ToArray();
}
Usage
Note:
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!";
https://riptutorial.com/ 47
// Create a new instance of the Aes class.
// This generates a new key and initialization vector (IV).
using (Aes myAes = Aes.Create())
{
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(original,
myAes.Key,
myAes.IV);
byte[] encrypted;
https://riptutorial.com/ 48
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.
https://riptutorial.com/ 49
(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:
• In a real encryption scenario, you need to choose a proper cipher mode (can be assigned to
the Mode property by selecting a value from the CipherMode enumeration). Never use the
CipherMode.ECB (electronic codebook mode), since this procuces a weak cypher stream
• 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
using System;
using System.Security.Cryptography;
using System.Text;
try
{
Console.WriteLine("Creating a key with PasswordDeriveBytes...");
Console.WriteLine("Operation complete.");
https://riptutorial.com/ 50
}
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");
}
https://riptutorial.com/ 51
buffer[x] = 0;
}
}
#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.
Notes:
• 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).
Decryption Code
https://riptutorial.com/ 52
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(),
CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
Encryption Code
cipherText = Convert.ToBase64String(ms.ToArray());
}
}
return cipherText;
}
Usage
https://riptutorial.com/ 53
Chapter 13: Exceptions
Remarks
Related:
Examples
Catching an exception
Code can and should throw exceptions in exceptional circumstances. Examples of this include:
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);
}
https://riptutorial.com/ 54
Using a finally block
The finally { ... } block of a try-finally or try-catch-finally will always execute, regardless of
whether an exception occurred or not (except when a StackOverflowException has been thrown or
call has been made to Environment.FailFast()).
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();
}
}
When you want to catch an exception and do something, but you can't continue execution of the
current block of code because of the exception, you may want to rethrow the exception to the next
exception handler in the call stack. There are good ways and bad ways to do this.
https://riptutorial.com/ 55
// only do this if you need to change the type of the Exception to be thrown
// and wrap the inner Exception
// 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
Exception Filters
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.
{
https://riptutorial.com/ 56
// ...
}
The same info can be found in the C# 6.0 Features here: Exception filters
Within a catch block the throw keyword can be used on its own, without specifying an exception
value, to rethrow the exception which was just caught. Rethrowing an exception allows the original
exception to continue up the exception handling chain, preserving its call stack or associated data:
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".
Occasionally you'd want to catch an exception and throw it from a different thread or method while
preserving the original exception stack. This can be done with ExceptionDispatchInfo:
using System.Runtime.ExceptionServices;
void Main()
{
ExceptionDispatchInfo capturedException = null;
try
{
throw new Exception();
}
catch (Exception ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
}
Foo(capturedException);
https://riptutorial.com/ 57
}
if (capturedException != null)
{
// Exception stack trace will show it was thrown from Main() and not from Foo()
exceptionDispatchInfo.Throw();
}
}
https://riptutorial.com/ 58
Chapter 14: Expression Trees
Remarks
Expression trees are data structures used to represent code expressions in the .NET Framework.
They can be generated by code and traversed programmatically to translate the code to another
language or execute it. The most popular generator of Expression Trees is the C# compiler itself.
The C# compiler can generate expression trees if a lambda expression is assigned to a variable of
type Expression<Func<...>>. Usually this happens in the context of LINQ. The most popular
consumer is Entity Framework's LINQ provider. It consumes the expression trees given to Entity
Framework and generates equivalent SQL code which is then executed against the database.
Examples
Simple Expression Tree Generated by the C# Compiler
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 ParameterExpression for the parameter "a" and Right is a
ConstantExpression with the value 1.
The expression tree can be compiled into a C# delegate and executed by the CLR
https://riptutorial.com/ 59
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.
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.
public TestClass
{
public static string StaticPublicField = "StaticPublicFieldValue";
}
https://riptutorial.com/ 60
It can be then i.e. compiled into a delegate for retrieving field value.
InvocationExpression Class
InvocationExpression class allows invocation of other lambda expressions that are parts of the
same Expression tree.
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
)
https://riptutorial.com/ 61
).Compile()
)
.Count();
Output
First thing to note is how the actual propery access, wrapped in an Invoke:
https://riptutorial.com/ 62
Invoke(e => e.Description, element)
, 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.
https://riptutorial.com/ 63
Chapter 15: File Input/Output
Parameters
Parameter Details
Remarks
Returns true if the file exists, false otherwise.
Examples
VB WriteAllText
Imports System.IO
VB StreamWriter
C# StreamWriter
using System.Text;
using System.IO;
C# WriteAllText()
using System.IO;
using System.Text;
https://riptutorial.com/ 64
string filename = "c:\path\to\file.txt";
File.writeAllText(filename, "Text to write\n");
C# File.Exists()
using System;
using System.IO;
if(File.Exists(filePath))
{
Console.WriteLine("Exists");
}
else
{
Console.WriteLine("Does not exist");
}
}
}
https://riptutorial.com/ 65
Chapter 16: ForEach
Remarks
Use it at all?
You might argue that the intention of the .NET framework is that queries do not have any side
effects and the ForEach method is by definition causing a side effect. You might find your code
more maintainable and easier to test if you use a plain foreach instead.
Examples
Calling a method on an object in a list
customers.Add(new Customer());
customers.Add(new Customer());
ForEach() is defined on the List<T> class, but not on IQueryable<T> or IEnumerable<T>. You have two
choices in those cases:
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
https://riptutorial.com/ 66
public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach(T item in enumeration)
{
action(item);
}
}
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.
https://riptutorial.com/ 67
Chapter 17: Garbage Collection
Introduction
In .Net, objects created with new() are allocated on the managed heap. These objects are never
explicitly finalized by the program that uses them; instead, this process is controlled by the .Net
Garbage Collector.
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.
Remarks
The Garbage Collector is aimed to lower the program cost in terms of allocated memory, but doing
so has a cost in terms of processing time. In order to achieve a good overall compromise, there
are a number of optimizations that should be taken into consideration while programming with the
Garbage Collector in mind:
• If the Collect() method is to be explicitly invoked (which should not often be the case
anyway), consider using the "optimized" mode which finalizes dead object only when
memory is actually needed
• Instead of invoking the Collect() method, consider using the AddMemoryPressure() and
RemoveMemoryPressure() methods, which trigger a memory collection only if actually
needed
• A memory collection is not guaranteed to finalize all dead objects; instead, the Garbage
Collector manages 3 "generations", an object sometimes "surviving" from a generation into
the next one
• Several threading models may apply, depending on various factors including setup fine
tuning, resulting in different degrees of interference between the Garbage Collector thread
and the other application thread(s)
Examples
A basic example of (garbage) collection
~FinalizableObject()
https://riptutorial.com/ 68
{
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.
Rule of thumb: when garbage collection occurs, "live objects" are those still in use, while "dead
objects" are those no longer used (any variable or field referencing them, if any, has gone out of
scope before the collection occurs).
<namespace>.FinalizableObject1 initialized
<namespace>.FinalizableObject2 initialized
<namespace>.FinalizableObject1 finalized
https://riptutorial.com/ 69
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.
What if two (or several) otherwise dead objects reference one another? This is shown in the
example below, supposing that OtherObject is a public property of FinalizableObject:
<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).
Weak References
Weak references are... references, to other objects (aka "targets"), but "weak" as they do not
prevent those objects from being garbage-collected. In other words, weak references do not count
when the Garbage Collector evaluates objects as "live" or "dead".
<namespace>.FinalizableObject initialized
<namespace>.FinalizableObject finalized
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
https://riptutorial.com/ 70
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:
Implement Dispose() method (and declare the containing class as IDisposable) as a means to
ensure any memory-heavy resources are freed as soon as the object is no longer used. The
"catch" is that there is no strong guarantee the the Dispose() method would ever be invoked
(unlike finalizers that always get invoked at the end of the life of the object).
https://riptutorial.com/ 71
// Initialize an object that uses heavy external resources
var disposableObject = new ClassThatImplementsIDisposable();
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.
As Dispose() and finalizers are aimed to different purposes, a class managing external memory-
heavy resources should implement both of them. The consequence is writing the class so that it
handles well two possible scenarios:
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:
https://riptutorial.com/ 72
~DisposableFinalizable1() { Cleanup(); }
Alternately, the Garbage Collector provides a specific method SuppressFinalize() that allows
skipping the finalizer after Dispose has been invoked:
https://riptutorial.com/ 73
Chapter 18: Globalization in ASP.NET MVC
using Smart internationalization for ASP.NET
Remarks
Smart internationalization for ASP.NET page
The benefit of this approach is that you don't have to clutter controllers and other classes with
code to look up values from .resx files. You simply surround text in [[[triple brackets.]]] (The
delimiter is configurable.) An HttpModule looks for a translation in your .po file to replace the
delimited text. If a translation is found, the HttpModule substitutes the translation. If no translation is
found, it removes the triple brackets and renders the page with the original untranslated text.
.po files are a standard format for supplying translations for applications, so there are a number of
applications available for editing them. It's easy to send a .po file to a non-technical user so that
they can add translations.
Examples
Basic configuration and setup
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!"
https://riptutorial.com/ 74
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.
10. In web.config, add handlers so that users cannot browse to your locale folder.
Read Globalization in ASP.NET MVC using Smart internationalization for ASP.NET online:
https://riptutorial.com/dot-net/topic/5086/globalization-in-asp-net-mvc-using-smart-
internationalization-for-asp-net
https://riptutorial.com/ 75
Chapter 19: HTTP clients
Remarks
The currently relevant HTTP/1.1 RFCs are:
• 7238: The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)
Related protocols:
• 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)
• 4791: Calendaring Extensions to WebDAV (CalDAV)
Examples
Reading GET response as string using System.Net.HttpWebRequest
https://riptutorial.com/ 76
using (var client = new WebClient())
{
responseData = client.DownloadString(requestUri);
}
byte[] responseBody;
byte[] requestBodyBytes = Encoding.UTF8.GetBytes(requestBodyString);
https://riptutorial.com/ 77
client.Headers[HttpRequestHeader.ContentType] = contentType;
responseBody = client.UploadData(requestUri, requestMethod, requestBodyBytes);
}
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
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();
}
}
}
}
https://riptutorial.com/ 78
{
Run(args).Wait();
}
catch (Exception ex)
{
if (ex is AggregateException)
ex = ((AggregateException)ex).Flatten().InnerExceptions.First();
Console.WriteLine("Done!");
}
}
https://riptutorial.com/ 79
Chapter 20: HTTP servers
Examples
Basic read-only HTTP file server (HttpListener)
Notes:
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]);
https://riptutorial.com/ 80
}
catch(Exception ex)
{
Console.WriteLine(ex);
if(response != null)
{
SendErrorResponse(500, "Internal server error");
}
}
}
if (request.HttpMethod.ToUpper() != "GET")
{
SendErrorResponse(405, "Method must be GET");
continue;
}
response.OutputStream.Close();
response = null;
Console.WriteLine(" Ok!");
}
}
https://riptutorial.com/ 81
}
}
1 - Create an empty folder, it will contain the files created in the next steps.
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;
https://riptutorial.com/ 82
"Content-Disposition",
$"Attachment; filename=\"{context.File.Name}\"");
};
app.UseStaticFiles(options);
}
}
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.
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.
https://riptutorial.com/ 83
Chapter 21: JIT compiler
Introduction
JIT compilation, or just-in-time compilation, is an alternative approach to interpretation of code or
ahead-of-time compilation. JIT compilation is used in the .NET framework. The CLR code (C#, F#,
Visual Basic, etc.) is first compiled into something called Interpreted Language, or IL. This is lower
level code that is closer to machine code, but is not platform specific. Rather, at runtime, this code
is compiled into machine code for the relevant system.
Remarks
Why use JIT compilation?
• Better compatibility: each CLR language needs only one compiler to IL, and this IL can run
on any platform on which it can be converted into machine code.
• Speed: JIT compilation attempts to combine the speed of running ahead-of-time compiled
code, and the flexibility of interpretation (can analyze code that will be executed for potential
optimizations before compiling)
Examples
IL compilation sample
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
}
https://riptutorial.com/ 84
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly HelloWorld
{
.custom instance void
[mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01
00 08 00 00 00 00 00 )
.custom instance void
[mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01
00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- 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 )
20 32 30 31 37 00 00 ) // 2017..
.custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 )
2D 34 30 32 32 2D 61 66 63 63 2D 33 66 38 65 33 // -4022-afcc-3f8e3
32 33 33 63 35 62 30 00 00 ) // 233c5b0..
.custom instance void
[mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30
2E 30 2E 30 00 00 ) // ...1.0.0.0..
.custom instance void
[mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1C 2E 4E
45 54 46 72 61 6D 65 77 6F 72 6B // ....NETFramework
2C 56 65 72 73 69 6F 6E 3D 76 34 2E 35 2E 32 01 // ,Version=v4.5.2.
00 54 0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 // .T..FrameworkDis
70 6C 61 79 4E 61 6D 65 14 2E 4E 45 54 20 46 72 // playName..NET Fr
https://riptutorial.com/ 85
61 6D 65 77 6F 72 6B 20 34 2E 35 2E 32 ) // amework 4.5.2
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module HelloWorld.exe
// MVID: {2A7E1D59-1272-4B47-85F6-D7E1ED057831}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00020003 // ILONLY 32BITPREFERRED
// Image base: 0x0000021C70230000
https://riptutorial.com/ 86
Chapter 22: JSON in .NET with
Newtonsoft.Json
Introduction
The NuGet package Newtonsoft.Json has become the defacto standard for using and manipulating
JSON formatted text and objects in .NET. It is a robust tool that is fast, and easy to use.
Examples
Serialize object into JSON
using Newtonsoft.Json;
This yields a Person object with Name "Joe Smith" and Age 21.
https://riptutorial.com/ 87
Chapter 23: JSON Serialization
Remarks
JavaScriptSerializer vs Json.NET
The JavaScriptSerializer class was introducted in .NET 3.5 and is used internally by .NET's
asynchronous communication layer for AJAX-enabled applications. It can be used to work with
JSON in managed code.
Despite the existence of the JavaScriptSerializer class, Microsoft recommends using the open
source Json.NET library for serialization and deserialization. Json.NET offers better performance
and a friendlier interface for mapping JSON to custom classes (a custom JavaScriptConverter
object would be needed to accomplish the same with JavaScriptSerializer).
Examples
Deserialization using System.Web.Script.Serialization.JavaScriptSerializer
using System.Collections;
using System.Web.Script.Serialization;
// ...
// ...
https://riptutorial.com/ 88
Sequence sequence = JsonConvert.DeserializeObject<Sequence>(rawJSON);
[JsonObject("person")]
public class Person
{
[JsonProperty("name")]
public string PersonName { get; set; }
[JsonProperty("age")]
public int PersonAge { get; set; }
[JsonIgnore]
public string Address { get; set; }
}
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}
}
https://riptutorial.com/ 89
Unlike the other helpers, this one uses static class helpers to serialize and deserialize, hence it is
a little bit easier than the others to use.
using Newtonsoft.Json;
Dynamic binding
Newtonsoft's Json.NET allows you to bind json dynamically (using ExpandoObject / Dynamic
objects) without the need to create the type explicitly.
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.
This serializer has some nice features that the default .net json serializer doesn't have, like Null
value handling, you just need to create the JsonSerializerSettings :
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
https://riptutorial.com/ 90
JsonSerializerSettings :
https://riptutorial.com/ 91
Chapter 24: LINQ
Introduction
LINQ (Language Integrated Query) is an expression that retrieves data from a data source. LINQ
simplifies this situation by offering a consistent model for working with data across various kinds of
data sources and formats. In a LINQ query, you are always working with objects. You use the
same basic coding patterns to query and transform data in XML documents, SQL databases,
ADO.NET Datasets, .NET collections, and any other format for which a provider is available. LINQ
can be used in C# and VB.
Syntax
• public static TSource Aggregate<TSource>(this IEnumerable<TSource> source,
Func<TSource,TSource,TSource> func)
• public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource>
source, TAccumulate seed, Func<TAccumulate,TSource,TAccumulate> func)
• public static TResult Aggregate<TSource, TAccumulate, TResult>(this
IEnumerable<TSource> source, TAccumulate seed,
Func<TAccumulate,TSource,TAccumulate> func, Func<TAccumulate,TResult>
resultSelector)
• public static Boolean All<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static Boolean Any<TSource>(this IEnumerable<TSource> source)
• public static Boolean Any<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource>
source)
• public static Decimal Average(this IEnumerable<Decimal> source)
• public static Double Average(this IEnumerable<Double> source)
• public static Double Average(this IEnumerable<Int32> source)
• public static Double Average(this IEnumerable<Int64> source)
• public static Nullable<Decimal> Average(this IEnumerable<Nullable<Decimal>> source)
• public static Nullable<Double> Average(this IEnumerable<Nullable<Double>> source)
• public static Nullable<Double> Average(this IEnumerable<Nullable<Int32>> source)
• public static Nullable<Double> Average(this IEnumerable<Nullable<Int64>> source)
• public static Nullable<Single> Average(this IEnumerable<Nullable<Single>> source)
• public static Single Average(this IEnumerable<Single> source)
• public static Decimal Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Decimal> selector)
• public static Double Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Double> selector)
• public static Double Average<TSource>(this IEnumerable<TSource> source,
Func<TSource, Int32> selector)
https://riptutorial.com/ 92
• public static Double Average<TSource>(this IEnumerable<TSource> source,
Func<TSource, Int64> selector)
• public static Nullable<Decimal> Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Decimal>> selector)
• public static Nullable<Double> Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Double>> selector)
• public static Nullable<Double> Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int32>> selector)
• public static Nullable<Double> Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int64>> selector)
• public static Nullable<Single> Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Single>> selector)
• public static Single Average<TSource>(this IEnumerable<TSource> source,
Func<TSource,Single> selector)
• public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
• public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second)
• public static Boolean Contains<TSource>(this IEnumerable<TSource> source, TSource
value)
• public static Boolean Contains<TSource>(this IEnumerable<TSource> source, TSource
value, IEqualityComparer<TSource> comparer)
• public static Int32 Count<TSource>(this IEnumerable<TSource> source)
• public static Int32 Count<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource>
source)
• public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource>
source, TSource defaultValue)
• public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source)
• public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source,
IEqualityComparer<TSource> comparer)
• public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, Int32 index)
• public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source,
Int32 index)
• public static IEnumerable<TResult> Empty<TResult>()
• public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second)
• public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
• public static TSource First<TSource>(this IEnumerable<TSource> source)
• public static TSource First<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
• public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static IEnumerable<IGrouping<TKey,TSource>> GroupBy<TSource, TKey>(this
https://riptutorial.com/ 93
IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static IEnumerable<IGrouping<TKey,TSource>> GroupBy<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
IEqualityComparer<TKey> comparer)
• public static IEnumerable<IGrouping<TKey,TElement>> GroupBy<TSource, TKey,
TElement>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector)
• public static IEnumerable<IGrouping<TKey,TElement>> GroupBy<TSource, TKey,
TElement>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector, IEqualityComparer<TKey> comparer)
• public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TKey,IEnumerable<TSource>,TResult> resultSelector)
• public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TKey,IEnumerable<TSource>,TResult> resultSelector, IEqualityComparer<TKey>
comparer)
• public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector, Func<TKey,IEnumerable<TElement>,TResult>
resultSelector)
• public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector, Func<TKey,IEnumerable<TElement>,TResult>
resultSelector, IEqualityComparer<TKey> comparer)
• public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this
IEnumerable<TOuter> outer,IEnumerable<TInner> inner, Func<TOuter,TKey>
outerKeySelector, Func<TInner,TKey> innerKeySelector,
Func<TOuter,IEnumerable<TInner>,TResult> resultSelector)
• public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this
IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter,TKey>
outerKeySelector, Func<TInner,TKey> innerKeySelector,
Func<TOuter,IEnumerable<TInner>,TResult> resultSelector, IEqualityComparer<TKey>
comparer)
• public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second)
• public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
• public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this
IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter,TKey>
outerKeySelector, Func<TInner,TKey> innerKeySelector, Func<TOuter,TInner,TResult>
resultSelector)
• public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this
IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter,TKey>
outerKeySelector, Func<TInner,TKey> innerKeySelector, Func<TOuter,TInner,TResult>
resultSelector, IEqualityComparer<TKey> comparer)
https://riptutorial.com/ 94
• public static TSource Last<TSource>(this IEnumerable<TSource> source)
• public static TSource Last<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)
• public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static Int64 LongCount<TSource>(this IEnumerable<TSource> source)
• public static Int64 LongCount<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static Decimal Max(this IEnumerable<Decimal> source)
• public static Double Max(this IEnumerable<Double> source)
• public static Int32 Max(this IEnumerable<Int32> source)
• public static Int64 Max(this IEnumerable<Int64> source)
• public static Nullable<Decimal> Max(this IEnumerable<Nullable<Decimal>> source)
• public static Nullable<Double> Max(this IEnumerable<Nullable<Double>> source)
• public static Nullable<Int32> Max(this IEnumerable<Nullable<Int32>> source)
• public static Nullable<Int64> Max(this IEnumerable<Nullable<Int64>> source)
• public static Nullable<Single> Max(this IEnumerable<Nullable<Single>> source)
• public static Single Max(this IEnumerable<Single> source)
• public static TSource Max<TSource>(this IEnumerable<TSource> source)
• public static Decimal Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Decimal> selector)
• public static Double Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Double> selector)
• public static Int32 Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Int32> selector)
• public static Int64 Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Int64> selector)
• public static Nullable<Decimal> Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Decimal>> selector)
• public static Nullable<Double> Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Double>> selector)
• public static Nullable<Int32> Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int32>> selector)
• public static Nullable<Int64> Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int64>> selector)
• public static Nullable<Single> Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Single>> selector)
• public static Single Max<TSource>(this IEnumerable<TSource> source,
Func<TSource,Single> selector)
• public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource,TResult> selector)
• public static Decimal Min(this IEnumerable<Decimal> source)
• public static Double Min(this IEnumerable<Double> source)
• public static Int32 Min(this IEnumerable<Int32> source)
• public static Int64 Min(this IEnumerable<Int64> source)
https://riptutorial.com/ 95
• public static Nullable<Decimal> Min(this IEnumerable<Nullable<Decimal>> source)
• public static Nullable<Double> Min(this IEnumerable<Nullable<Double>> source)
• public static Nullable<Int32> Min(this IEnumerable<Nullable<Int32>> source)
• public static Nullable<Int64> Min(this IEnumerable<Nullable<Int64>> source)
• public static Nullable<Single> Min(this IEnumerable<Nullable<Single>> source)
• public static Single Min(this IEnumerable<Single> source)
• public static TSource Min<TSource>(this IEnumerable<TSource> source)
• public static Decimal Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Decimal> selector)
• public static Double Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Double> selector)
• public static Int32 Min<TSource>(this IEnumerable<TSource> source, Func<TSource,Int32>
selector)
• public static Int64 Min<TSource>(this IEnumerable<TSource> source, Func<TSource,Int64>
selector)
• public static Nullable<Decimal> Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Decimal>> selector)
• public static Nullable<Double> Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Double>> selector)
• public static Nullable<Int32> Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int32>> selector)
• public static Nullable<Int64> Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int64>> selector)
• public static Nullable<Single> Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Single>> selector)
• public static Single Min<TSource>(this IEnumerable<TSource> source,
Func<TSource,Single> selector)
• public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource,TResult> selector)
• public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source)
• public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector, IComparer<TKey>
comparer)
• public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector, IComparer<TKey>
comparer)
• public static IEnumerable<Int32> Range(Int32 start, Int32 count)
• public static IEnumerable<TResult> Repeat<TResult>(TResult element, Int32 count)
• public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource>
source)
• public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource>
source, Func<TSource,TResult> selector)
https://riptutorial.com/ 96
• public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource>
source, Func<TSource,Int32,TResult> selector)
• public static IEnumerable<TResult> SelectMany<TSource, TResult>(this
IEnumerable<TSource> source, Func<TSource,IEnumerable<TResult>> selector)
• public static IEnumerable<TResult> SelectMany<TSource, TResult>(this
IEnumerable<TSource> source, Func<TSource,Int32,IEnumerable<TResult>> selector)
• public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this
IEnumerable<TSource> source, Func<TSource,IEnumerable<TCollection>>
collectionSelector, Func<TSource,TCollection,TResult> resultSelector)
• public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this
IEnumerable<TSource> source, Func<TSource,Int32,IEnumerable<TCollection>>
collectionSelector, Func<TSource,TCollection,TResult> resultSelector)
• public static Boolean SequenceEqual<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second)
• public static Boolean SequenceEqual<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
• public static TSource Single<TSource>(this IEnumerable<TSource> source)
• public static TSource Single<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
• public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source,
Int32 count)
• public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource>
source, Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource>
source, Func<TSource,Int32,Boolean> predicate)
• public static Decimal Sum(this IEnumerable<Decimal> source)
• public static Double Sum(this IEnumerable<Double> source)
• public static Int32 Sum(this IEnumerable<Int32> source)
• public static Int64 Sum(this IEnumerable<Int64> source)
• public static Nullable<Decimal> Sum(this IEnumerable<Nullable<Decimal>> source)
• public static Nullable<Double> Sum(this IEnumerable<Nullable<Double>> source)
• public static Nullable<Int32> Sum(this IEnumerable<Nullable<Int32>> source)
• public static Nullable<Int64> Sum(this IEnumerable<Nullable<Int64>> source)
• public static Nullable<Single> Sum(this IEnumerable<Nullable<Single>> source)
• public static Single Sum(this IEnumerable<Single> source)
• public static Decimal Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Decimal> selector)
• public static Double Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Double> selector)
• public static Int32 Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Int32> selector)
• public static Int64 Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Int64> selector)
https://riptutorial.com/ 97
• public static Nullable<Decimal> Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Decimal>> selector)
• public static Nullable<Double> Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Double>> selector)
• public static Nullable<Int32> Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int32>> selector)
• public static Nullable<Int64> Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Int64>> selector)
• public static Nullable<Single> Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Nullable<Single>> selector)
• public static Single Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource,Single> selector)
• public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source,
Int32 count)
• public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource>
source, Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource>
source, Func<TSource,Int32,Boolean> predicate)
• public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this
IOrderedEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this
IOrderedEnumerable<TSource> source, Func<TSource,TKey> keySelector,
IComparer<TKey> comparer)
• public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this
IOrderedEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this
IOrderedEnumerable<TSource> source, Func<TSource,TKey> keySelector,
IComparer<TKey> comparer)
• public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
• public static Dictionary<TKey,TSource> ToDictionary<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static Dictionary<TKey,TSource> ToDictionary<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
IEqualityComparer<TKey> comparer)
• public static Dictionary<TKey,TElement> ToDictionary<TSource, TKey, TElement>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector)
• public static Dictionary<TKey,TElement> ToDictionary<TSource, TKey, TElement>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector, IEqualityComparer<TKey> comparer)
• public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
• public static ILookup<TKey,TSource> ToLookup<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
• public static ILookup<TKey,TSource> ToLookup<TSource, TKey>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
IEqualityComparer<TKey> comparer)
https://riptutorial.com/ 98
• public static ILookup<TKey,TElement> ToLookup<TSource, TKey, TElement>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector)
• public static ILookup<TKey,TElement> ToLookup<TSource, TKey, TElement>(this
IEnumerable<TSource> source, Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector, IEqualityComparer<TKey> comparer)
• public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second)
• public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
• public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
Func<TSource,Boolean> predicate)
• public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
Func<TSource,Int32,Boolean> predicate)
• public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this
IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst,TSecond,TResult>
resultSelector)
Remarks
• See also LINQ.
The LINQ built-in methods are extension methods for the IEnumerable<T> interface that live in the
System.Linq.Enumerable class in the System.Core assembly. They are available in .NET Framework
3.5 and later.
LINQ allows for simple modification, transformation, and combination of various IEnumerables using
a query-like or functional syntax.
While the standard LINQ methods can work on any IEnumerable<T>, including the simple arrays and
List<T>s, they can also be used on database objects, where the set of LINQ expressions can be
transformed in many cases to SQL if the data object supports it. See LINQ to SQL.
For the methods that compare objects (such as Contains and Except), IEquatable<T>.Equals is used
if the type T of the collection implements that interface. Otherwise, the standard Equals and
GetHashCode of the type (possibly overriden from the default Object implementations) are used.
There are also overloads for these methods that allow to specify a custom IEqualityComparer<T>.
Lazy Evaluation
Virtually every query that returns an IEnumerable<T> is not evaluated immediately; instead, the logic
is delayed until the query is iterated over. One implication is that each time someone iterates over
an IEnumerable<T> created from one of these queries, e.g., .Where(), the full query logic is repeated.
https://riptutorial.com/ 99
If the predicate is long-running, this can be a cause for performance issues.
One simple solution (when you know or can control the approximate size of the resulting
sequence) is to fully buffer the results using .ToArray() or .ToList(). .ToDictionary() or .ToLookup()
can fulfill the same role. One can also, of course, iterate over the entire sequence and buffer the
elements according to other custom logic.
ToArray() or ToList()?
Both .ToArray() and .ToList() loop through all elements of an IEnumerable<T> sequence and save
the results in a collection stored in-memory. Use the following guidelines to determine which to
choose:
Examples
Select (map)
//Foo,Bar,Fizz,Buzz
Where (filter)
This method returns an IEnumerable with all the elements that meets the lambda expression
Example
https://riptutorial.com/ 100
var personNames = new[]
{
"Foo", "Bar", "Fizz", "Buzz"
};
Output:
Foo,Fizz
View Demo
OrderBy
//2,4,3,1
OrderByDescending
//1,3,4,2
Contains
https://riptutorial.com/ 101
Except
Console.WriteLine(string.Join(",", result));
//1, 2, 3, 4, 5, 7, 9
Intersect
Console.WriteLine(string.Join(",", numbers5to10));
//5,6,7,8,9,10
Concat
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.
First (find)
Single
https://riptutorial.com/ 102
var oneNumber = new[] {5};
var theOnlyNumber = oneNumber.Single();
Console.WriteLine(theOnlyNumber); //5
The following throws InvalidOperationException since there is more than one element in the
sequence:
Last
LastOrDefault
https://riptutorial.com/ 103
SingleOrDefault
FirstOrDefault
Any
Returns true if the collection has any elements that meets the condition in the lambda expression:
https://riptutorial.com/ 104
Console.WriteLine(anyNumberIsSix); //False
All
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:
Example
class Invoice
{
public int Id { get; set; }
}
class Customer
{
public Invoice[] Invoices {get;set;}
}
https://riptutorial.com/ 105
new Invoice {Id=2},
}
},
new Customer {
Invoices = new[] {
new Invoice {Id=3},
new Invoice {Id=4},
}
},
new Customer {
Invoices = new[] {
new Invoice {Id=5},
new Invoice {Id=6},
}
}
};
Console.WriteLine(
string.Join(",", allInvoicesFromAllCustomers.Select(i => i.Id).ToArray()));
Output:
1,2,3,4,5,6
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;
Sum
Skip
Skip will enumerate the first N items without returning them. Once item number N+1 is reached,
https://riptutorial.com/ 106
Skip starts returning every enumerated item:
//3,4,5
Take
//1,2,3
SequenceEqual
Reverse
Console.WriteLine(string.Join(",", reversed.ToArray()));
//5,4,3,2,1
OfType
Console.WriteLine(string.Join(",", numbers.ToArray()));
//1,2,3,4
Max
https://riptutorial.com/ 107
var numbers = new[] {1,2,3,4};
Min
Average
Zip
.NET4.0
https://riptutorial.com/ 108
var tens = new[] {10,20,30,40,50};
var units = new[] {1,2,3,4,5};
Console.WriteLine(string.Join(",", sums));
//11,22,33,44,55
Distinct
Console.WriteLine(string.Join(",", distinctNumbers));
//1,2,3,4,5
GroupBy
Group invoices by country, generating a new object with the number of record, total paid, and
average paid
https://riptutorial.com/ 109
Average = g.Average(i => i.Paid) });
ToDictionary
Returns a new dictionary from the source IEnumerable using the provided keySelector function to
determine keys. Will throw an ArgumentException if keySelector is not injective(returns a unique
value for each member of the source collection.) There are overloads which allow one to specify
the value to be stored as well as the key.
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.
https://riptutorial.com/ 110
};
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.
Union
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.
ToArray
Console.WriteLine(someNumbers.GetType().Name);
//WhereArrayIterator`1
Console.WriteLine(someNumbersArray.GetType().Name);
//Int32[]
ToList
Console.WriteLine(someNumbers.GetType().Name);
//WhereArrayIterator`1
Console.WriteLine(
someNumbersList.GetType().Name + " - " +
someNumbersList.GetType().GetGenericArguments()[0].Name);
//List`1 - Int32
Count
https://riptutorial.com/ 111
var numbersCount = numbers.Count();
Console.WriteLine(numbersCount); //10
ElementAt
ElementAtOrDefault
SkipWhile
Console.WriteLine(string.Join(",", oddNumbers.ToArray()));
//1,3,5,7
TakeWhile
Console.WriteLine(string.Join(",", evenNumbers.ToArray()));
//2,4,6
DefaultIfEmpty
https://riptutorial.com/ 112
var numbers = new[] {2,4,6,8,1,3,5,7};
Aggregate (fold)
Console.WriteLine(commaSeparatedElements); //1,2,3,4,5,
Console.WriteLine(commaSeparatedElements2.ToString()); //1,2,3,4,5,
Console.WriteLine(commaSeparatedElements4); //12,3,4,5,
ToLookup
https://riptutorial.com/ 113
var persons = new[] {
new { Name="Fizz", Job="Developer"},
new { Name="Buzz", Job="Developer"},
new { Name="Foo", Job="Astronaut"},
new { Name="Bar", Job="Astronaut"},
};
Join
class Developer
{
public int Id { get; set; }
public string Name { get; set; }
}
class Project
{
public int DeveloperId { get; set; }
public string Name { get; set; }
}
https://riptutorial.com/ 114
DeveloperId = 2,
Name = "Pro Pong 2016"
}
};
GroupJoin
class Developer
{
public int Id { get; set; }
public string Name { get; set; }
}
class Project
{
public int DeveloperId { get; set; }
public string Name { get; set; }
}
https://riptutorial.com/ 115
DeveloperId = 2,
Name = "Citizen Kane - The action game"
},
new Project {
DeveloperId = 2,
Name = "Pro Pong 2016"
}
};
Cast
Cast is different from the other methods of Enumerable in that it is an extension method for
IEnumerable, not for IEnumerable<T>. Thus it can be used to convert instances of the former into
instances of the later.
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:
https://riptutorial.com/ 116
decimal[] numbersAsDecimal = numbers.Select(n => (decimal)n).ToArray();
Empty
ThenBy
ThenBy can only be used after a OrderBy clause allowing to order using multiple criteria
Range
The two parameters to Range are the first number and the count of elements to produce (not the
last number).
// 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)));
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
https://riptutorial.com/ 117
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
var query =
from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new
{
person.FirstName,
PetName = subpet?.Name ?? "-" // Use - if he has no pet
};
Repeat
/* output:
Hello
Hello
Hello
Hello
*/
https://riptutorial.com/ 118
Chapter 25: Managed Extensibility
Framework
Remarks
One of MEF's big advantages over other technologies that support the inversion-of-control pattern
is that it supports resolving dependencies that are not known at design-time, without needing
much (if any) configuration.
Also, all the (Basic) examples use these as their sample business objects:
using System.Collections.ObjectModel;
namespace Demo
{
public sealed class User
{
public User(int id, string name)
{
this.Id = id;
this.Name = name;
}
Examples
Exporting a Type (Basic)
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
namespace Demo
{
[Export(typeof(IUserProvider))]
public sealed class UserProvider : IUserProvider
{
public ReadOnlyCollection<User> GetAllUsers()
{
https://riptutorial.com/ 119
return new List<User>
{
new User(0, "admin"),
new User(1, "Dennis"),
new User(2, "Samantha"),
}.AsReadOnly();
}
}
}
This could be defined virtually anywhere; all that matters is that the application knows where to
look for it (via the ComposablePartCatalogs it creates).
Importing (Basic)
using System;
using System.ComponentModel.Composition;
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).
Connecting (Basic)
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))
https://riptutorial.com/ 120
{
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.
https://riptutorial.com/ 121
Chapter 26: Memory management
Remarks
Performance-critical applications in managed .NET applications can be severely impacted by the
GC. When the GC runs, all other threads are suspended until it completes. For this reason, it is
recommended to carefully evaluate the GC processes and determine how to minimize when it
runs.
Examples
Unmanaged Resources
When we talk about the GC and the "heap", we're really talking about what's called the managed
heap. Objects on the managed heap can access resources not on the managed heap, for
example, when writing to or reading from a file. Unexpected behavior can occur when, a file is
opened for reading and then an exception occurs, preventing the file handle from closing as it
normally would. For this reason, .NET requires that unmanaged resources implement the
IDisposable interface. This interface has a single method called Dispose with no parameters:
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
{
sr = new StreamReader(filename);
textFromFile = sr.ReadToEnd();
}
finally
{
if (sr != null) sr.Dispose();
}
or
string textFromFile;
string filename = "SomeFile.txt";
https://riptutorial.com/ 122
}
The latter is the preferred method, and is automatically expanded to the former during compilation.
When writing wrappers for unmanaged resources, you should subclass SafeHandle rather than
trying to implement IDisposable and a finalizer yourself. Your SafeHandle subclass should be as
small and simple as possible to minimize the chance of a handle leak. This likely means that your
SafeHandle implementation would an internal implementation detail of a class which wraps it to
provide a usable API. This class ensures that, even if a program leaks your SafeHandle instance,
your unmanaged handle is released.
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.
https://riptutorial.com/ 123
Chapter 27: Networking
Remarks
See also: HTTP Clients
Examples
Basic TCP chat (TcpListener, TcpClient, NetworkStream)
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
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);
https://riptutorial.com/ 124
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);
https://riptutorial.com/ 125
Console.WriteLine("(append .5 for an extra half an hour)");
return;
}
double localTimeZoneInHours = 0;
if(args.Length > 1)
localTimeZoneInHours = double.Parse(args[1], CultureInfo.InvariantCulture);
udpClient.Send(
dgram: sntpRequest,
bytes: sntpRequest.Length,
hostname: args[0],
port: SntpPort);
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.#;.}");
}
}
https://riptutorial.com/ 126
Chapter 28: NuGet packaging system
Remarks
NuGet.org:
NuGet is the package manager for the Microsoft development platform including .NET.
The NuGet client tools provide the ability to produce and consume packages. The
NuGet Gallery is the central package repository used by all package authors and
consumers.
Examples
Installing the NuGet Package Manager
In order to be able to manage your projects' packages, you need the NuGet Package Manager.
This is a Visual Studio Extension, explained in the official docs: Installing and Updating NuGet
Client.
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:
https://riptutorial.com/ 127
This installs both the GUI:
• Available through clicking "Manage NuGet Packages..." on a project or its References folder
When you right-click a project (or its References folder), you can click the "Manage NuGet
Packages..." option. This shows the Package Manager Dialog.
https://riptutorial.com/ 128
Managing Packages through the console
Click the menus Tools -> NuGet Package Manager -> Package Manager Console to show the
console in your IDE. Official documentation here.
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:
Updating a package
https://riptutorial.com/ 129
To update a package use the following command:
where EntityFramework is the name of the package to be updated. Note that update will run for all
projects, and so is different from Install-Package EntityFramework which would install to "Default
project" only.
Uninstalling a package
It is common for company to set up it's own nuget server for distribution of packages across
different teams.
1. Go to Solution Explorer and click Right Mouse button then choose Manage NuGet Packages for
Solution
https://riptutorial.com/ 130
2. In window that opens click on Settings
3. Click on + in top right corner then add name and url that points to your local nuget server.
https://riptutorial.com/ 131
uninstall a specific version of package
https://riptutorial.com/ 132
Chapter 29: Parallel processing using .Net
framework
Introduction
This Topic is about Multi core programming using Task Parallel Library with .NET framework. The
task parallel library allows you to write code which is human readable and adjusts itself with the
number of Cores available. So you can be sure that your software would auto-upgrade itself with
the upgrading environment.
Examples
Parallel Extensions
Parallel extensions have been introduced along with the Task Parallel Library to achieve data
Parallelism. Data parallelism refers to scenarios in which the same operation is performed
concurrently (that is, in parallel) on elements in a source collection or array. The .NET provides
new constructs to achieve data parallelism by using Parallel.For and Parallel.Foreach constructs.
//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.
https://riptutorial.com/ 133
Chapter 30: Platform Invoke
Syntax
• [DllImport("Example.dll")] static extern void SetText(string inString);
• [DllImport("Example.dll")] static extern void GetText(StringBuilder outString);
• [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] string text;
• [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] byte[] byteArr;
• [StructLayout(LayoutKind.Sequential)] public struct PERSON {...}
• [StructLayout(LayoutKind.Explicit)] public struct MarshaledUnion { [FieldOffset(0)]... }
Examples
Calling a Win32 dll function
using System.Runtime.InteropServices;
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).
Use pinvoke.net.
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.
Marshalling arrays
https://riptutorial.com/ 134
Arrays of simple type
[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);
Marshaling structs
Simple struct
C++ signature:
C# definition
C++ signature
typedef struct
{
int length;
int *data;
} VECTOR;
https://riptutorial.com/ 135
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
{
https://riptutorial.com/ 136
IntPtr nameBuffer;
public string name { get { return Marshal.PtrToStringAnsi(nameBuffer); } }
}
[DllImport("users.dll")]
public static extern bool GetCurrentUser(out USER user);
Marshaling unions
C++ declaration
typedef union
{
char c;
int i;
} CharOrInt;
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); } }
}
https://riptutorial.com/ 137
Chapter 31: Process and Thread affinity
setting
Parameters
Parameter Details
integer that describes the set of processors on which the process is allowed to
run. For example, on a 8 processor system if you want your process to be
affinity
executed only on processors 3 and 4 than you choose affinity like this :
00001100 which equals 12
Remarks
The processor affinity of a thread is the set of processors it has a relationship to. In other words,
those it can be scheduled to run on.
Processor affinity represents each processor as a bit. Bit 0 represents processor one, bit 1
represents processor two, and so on.
Examples
Get process affinity mask
return processorAffinity;
}
https://riptutorial.com/ 138
return myProcess;
}
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
https://riptutorial.com/ 139
Chapter 32: Reading and writing Zip files
Introduction
The ZipFile class lives in the System.IO.Compression namespace. It can be used to read from,
and write to Zip files.
Remarks
• You can also use a MemoryStream instead of a FileStream.
• Exceptions
Exception Condition
Examples
Listing ZIP contents
This snippet will list all the filenames of a zip archive. The filenames are relative to the zip root.
https://riptutorial.com/ 140
Extracting files from ZIP files
To update a ZIP file, the file has to be opened with ZipArchiveMode.Update instead.
There is also the option to write directly to a file within the archive:
https://riptutorial.com/ 141
Read Reading and writing Zip files online: https://riptutorial.com/dot-net/topic/9943/reading-and-
writing-zip-files
https://riptutorial.com/ 142
Chapter 33: ReadOnlyCollections
Remarks
A ReadOnlyCollection provides a read-only view to an existing collection (the 'source collection').
Items are not directly added to or removed from a ReadOnlyCollection. Instead, they are added and
removed from the source collection and the ReadOnlyCollection will reflect these changes to the
source.
The number and order of elements inside a ReadOnlyCollection cannot be modified, but the
properties of the elements can be and the methods can be called, assuming they are in scope.
Use a ReadOnlyCollection when you want to allow external code to view your collection without
being able to modify it, but still be able to modify the collection yourself.
See Also
• ObservableCollection<T>
• ReadOnlyObservableCollection<T>
ReadOnlyCollections vs ImmutableCollection
A ReadOnlyCollection differs from an ImmutableCollection in that you cannot edit an
ImmutableCollection once you created it - it will always contain n elements, and they cannot be
replaced or reordered. A ReadOnlyCollection, on the other hand, cannot be edited directly, but
elements can still be added/removed/reordered using the source collection.
Examples
Creating a ReadOnlyCollection
Using LINQ
Additionaly, LINQ provides an AsReadOnly() extension method for IList objects:
https://riptutorial.com/ 143
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.
Updating a ReadOnlyCollection
A ReadOnlyCollection cannot be edited directly. Instead, the source collection is updated and the
ReadOnlyCollection will reflect these changes. This is the key feature of the ReadOnlyCollection.
View Demo
If the source collection is of a type that is not immutable, elements accessed through a
ReadOnlyCollection can be modified.
https://riptutorial.com/ 144
new Item { Name = "Banana", Price = 0.75m },
new Item { Name = "Vitamins", Price = 5.50m }
};
// 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
https://riptutorial.com/ 145
Chapter 34: Reflection
Examples
What is an Assembly?
Assemblies are the building block of any Common Language Runtime (CLR) application. Every
type you define, together with its methods, properties and their bytecode, is compiled and
packaged inside an Assembly.
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"
T variable = Activator.CreateInstance(typeof(T));
https://riptutorial.com/ 146
Creating Object and setting properties using reflection
Attributes can be useful for denoting metadata on enums. Getting the value of this can be slow, so
it is important to cache results.
// Get the custom attributes of the type desired found on the struct.
T[] attribs = (T[])fieldInfo.GetCustomAttributes(typeof(T), false);
return result;
}
}
https://riptutorial.com/ 147
public class Equatable
{
public string field1;
return true;
}
return accumulator;
}
}
Note: this example do a field based comparasion (ignore static fields and properties) for simplicity
https://riptutorial.com/ 148
Chapter 35: Regular Expressions
(System.Text.RegularExpressions)
Examples
Check if pattern matches input
// true
return Regex.IsMatch(input, pattern);
}
Passing Options
// true
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
}
// World
return match.Groups["Subject"].Value;
https://riptutorial.com/ 149
}
Using
using System.Text.RegularExpressions;
Code
static void Main(string[] args)
{
string input = "Carrot Banana Apple Cherry Clementine Grape";
// Find words that start with uppercase 'C'
string pattern = @"\bC\w*\b";
Output
Carrot
Cherry
Clementine
https://riptutorial.com/ 150
Chapter 36: Serial Ports
Examples
Basic operation
Asynchronous read
using System.IO.Ports;
namespace TextEchoService
{
class Program
{
static void Main(string[] args)
{
https://riptutorial.com/ 151
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
string message = "";
while (message != "quit")
{
message = serialPort.ReadLine();
serialPort.WriteLine(message);
}
serialPort.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
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;
https://riptutorial.com/ 152
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
ProcessBuffer(buffer, bytesRead);
break;
case SerialData.Eof:
terminateService.Set();
break;
}
}
}
static void ErrorReceivedHandler(object sender, SerialErrorReceivedEventArgs e)
{
lock (eventLock)
if (e.EventType == SerialError.TXFull)
{
Console.WriteLine("Error: TXFull. Can't handle this!");
terminateService.Set();
}
else
{
Console.WriteLine("Error: {0}. Resetting everything", e.EventType);
var port = (SerialPort)sender;
port.DiscardInBuffer();
port.DiscardOutBuffer();
unprocessedBuffer = null;
port.Write(new byte[] { NAK }, 0, 1);
}
}
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.
https://riptutorial.com/ 153
• Asynchronous serial port reading (see SerialPort.DataReceived usage).
• Serial port error processing (see SerialPort.ErrorReceived usage).
• Non-text message-based protocol implementation.
• Partial message reading.
○The SerialPort.DataReceived event may happen earlier than entire message (up to ETX)
comes. The entire message may also not be available in the input buffer
(SerialPort.Read(..., ..., port.BytesToRead) reads only a part of the message). In this
case we stash the received part (unprocessedBuffer) and carry on waiting for further
data.
• Dealing with several messages coming in one go.
○The SerialPort.DataReceived event may happen only after several messages have been
sent by the other end.
https://riptutorial.com/ 154
Chapter 37: Settings
Examples
AppSettings from ConfigurationSettings in .NET 1.x
Deprecated usage
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();
}
}
}
https://riptutorial.com/ 155
The ConfigurationManager class supports the AppSettings property, which allows you to continue
reading settings from the appSettings section of a configuration file the same way as .NET 1.x
supported.
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();
}
}
}
Visual Studio helps manage user and application settings. Using this approach has these benefits
over using the appSettings section of the configuration file.
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).
https://riptutorial.com/ 156
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 item will open the Settings tab.
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.
https://riptutorial.com/ 157
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
using System;
using System.Diagnostics;
using ConsoleApplication1.Properties;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
TimeSpan exampleTimeout = Settings.Default.ExampleTimeout;
Debug.Assert(TimeSpan.FromMinutes(1).Equals(exampleTimeout));
Console.ReadKey();
}
}
}
https://riptutorial.com/ 158
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.
https://riptutorial.com/ 159
Chapter 38: SpeechRecognitionEngine class
to recognize speech
Syntax
• SpeechRecognitionEngine()
• SpeechRecognitionEngine.LoadGrammar(Grammar grammar)
• SpeechRecognitionEngine.SetInputToDefaultAudioDevice()
• SpeechRecognitionEngine.RecognizeAsync(RecognizeMode mode)
• GrammarBuilder()
• GrammarBuilder.Append(Choices choices)
• Choices(params string[] choices)
• Grammar(GrammarBuilder builder)
Parameters
RecognizeAsync:
Details
Parameters
The RecognizeMode for the current recognition: Single for just one
mode
recognition, Multiple to allow multiple.
GrammarBuilder.Append:
Details
Parameters
constructor:
Choices
Details
Parameters
constructor:
Grammar
Details
Parameter
https://riptutorial.com/ 160
Remarks
To use SpeechRecognitionEngine, your Windows version needs to have speech recognition enabled.
You have to add a reference to System.Speech.dll before you can use the speech classes.
Examples
Asynchronously recognizing speech for free text dictation
using System.Speech.Recognition;
// ...
https://riptutorial.com/ 161
Chapter 39: Stack and Heap
Remarks
It's worth noting that on declaring a reference type, its initial value will be null. This is because it
does not yet point to a location in memory, and is a perfectly valid state.
However, with the exception of nullable types, value types must typically always have a value.
Examples
Value types in use
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";
https://riptutorial.com/ 162
personB));
Reference types are comprised of both a reference to a memory area, and a value stored within
that area.
This is analogous to pointers in C/C++.
In addition to the memory space required for the instance itself, additional space is required to
store the reference itself, along with additional temporary information required by the .NET CLR.
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";
https://riptutorial.com/ 163
Console.WriteLine(personA.Name); // Outputs 'Linda'
Console.WriteLine(personB.Name); // Outputs 'Linda'
}
https://riptutorial.com/ 164
Chapter 40: Strings
Remarks
In .NET strings System.String are sequence of characters System.Char, each character is an UTF-
16 encoded code-unit. This distinction is important because spoken language definition of
character and .NET (and many other languages) definition of character are different.
One character, which should be correctly called grapheme, it's displayed as a glyph and it is
defined by one or more Unicode code-points. Each code-point is then encoded in a sequence of
code-units. Now it should be clear why a single System.Char does not always represent a
grapheme, let's see in real world how they're different:
• One grapheme, because of combining characters, may result in two or more code-points: à
is composed by two code-points: U+0061 LATIN SMALL LETTER A and U+0300
COMBINING GRAVE ACCENT. This is the most common mistake because "à".Length == 2
while you may expect 1.
• There are duplicated characters, for example à may be a single code-point U+00E0 LATIN
SMALL LETTER A WITH GRAVE or two code-points as explained above. Obviously they
must compare the same: "\u00e0" == "\u0061\u0300" (even if "\u00e0".Length !=
"\u0061\u0300".Length). This is possible because of string normalization performed by
String.Normalize() method.
• An Unicode sequence may contain a composed or decomposed sequence, for example
character U+D55C HAN CHARACTER may be a single code-point (encoded as a single
code-unit in UTF-16) or a decomposed sequence of its syllables , and . They must be
compared equal.
• One code-point may be encoded to more than one code-units: character U+2008A HAN
CHARACTER is encoded as two System.Char ("\ud840\udc8a") even if it is just one code-point:
UTF-16 encoding is not fixed size! This is a source of countless bugs (also serious security
bugs), if for example your application applies a maximum length and blindly truncates string
at that then you may create an invalid string.
• Some languages have digraph and trigraphs, for example in Czech ch is a standalone letter
(after h and before i then when ordering a list of strings you will have fyzika before chemie.
There are much more issues about text handling, see for example How can I perform a Unicode
aware character by character comparison? for a broader introduction and more links to related
arguments.
In general when dealing with international text you may use this simple function to enumerate text
elements in a string (avoiding to break Unicode surrogates and encoding):
https://riptutorial.com/ 165
var enumerator = StringInfo.GetTextElementEnumerator(s.Normalize());
while (enumerator.MoveNext())
yield return (string)enumerator.Value;
}
}
Examples
Count distinct characters
If you need to count distinct characters then, for the reasons explained in Remarks section, you
can't simply use Length property because it's the length of the array of System.Char which are not
characters but code-units (not Unicode code-points nor graphemes). If, for example, you simply
write text.Distinct().Count() you will get incorrect results, correct code:
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):
Count characters
If you need to count characters then, for the reasons explained in Remarks section, you can't
simply use Length property because it's the length of the array of System.Char which are not
characters but code-units (not Unicode code-points nor graphemes). Correct code is then:
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;
}
}
https://riptutorial.com/ 166
Count occurrences of a character
Because of the reasons explained in Remarks section you can't simply do this (unless you want to
count occurrences of a specific code-unit):
Note that string comparison (in contrast to character comparison which is culture invariant) must
always be performed according to rules to a specific culture.
We cannot break a string into arbitrary points (because a System.Char may not be valid alone
because it's a combining character or part of a surrogate) then code must take that into account
(note that with length I mean the number of graphemes not the number of code-units):
if (!enumerator.MoveNext())
yield break;
}
}
.NET strings contain System.Char (UTF-16 code-units). If you want to save (or manage) text with
another encoding you have to work with an array of System.Byte.
https://riptutorial.com/ 167
Because the encoder/decoder usually works very close to each other they're grouped together in a
class derived from System.Text.Encoding, derived classes offer conversions to/from popular
encodings (UTF-8, UTF-16 and so on).
Examples:
Convert a string to UTF-8
Everything in .NET is an object, hence every type has ToString() method defined in Object class
which can be overridden. Default implementation of this method just returns the name of the type:
https://riptutorial.com/ 168
Console.WriteLine("I am bar and "+foo);// outputs I am bar and I am Foo
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):
Immutability of strings
Strings are immutable. You just cannot change existing string. Any operation on the string crates a
new instance of the string having new value. It means that if you need to replace a single
character in a very long string, memory will be allocated for a new value.
If you need to perform many operations with string value, use StringBuilder class which is
designed for efficient strings manipulation:
Сomparing strings
Despite String is a reference type == operator compares string values rather than references.
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!
https://riptutorial.com/ 169
Read Strings online: https://riptutorial.com/dot-net/topic/2227/strings
https://riptutorial.com/ 170
Chapter 41: Synchronization Contexts
Remarks
A Synchronization Context is an abstraction that allows consuming to code to pass units of work to
a scheduler, without requiring awareness of how the work will be scheduled.
Synchronization contexts are traditionally used to ensure that code is run on a specific thread. In
WPF and Winforms applications, a SynchronizationContext representing the UI thread is provided
by the presentation framework. In this way SynchronizationContext can be thought of as a
producer-consumer pattern for delegates. A worker thread will produce executable code (the
delegate) and queue it or consumption by the UI message loop.
The Task Parallel Library provides features for automatically capturing and using synchronization
contexts.
Examples
Execute code on the UI thread after performing background work
This example shows how to update a UI component from a background thread by using a
SynchronizationContext
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.
https://riptutorial.com/ 171
Read Synchronization Contexts online: https://riptutorial.com/dot-net/topic/5407/synchronization-
contexts
https://riptutorial.com/ 172
Chapter 42: System.Diagnostics
Examples
Stopwatch
This example shows how Stopwatch can be used to benchmark a block of code.
using System;
using System.Diagnostics;
public Benchmark()
{
sw = Stopwatch.StartNew();
}
https://riptutorial.com/ 173
Send Command to CMD and Receive Output
This method allows a command to be sent to Cmd.exe, and returns the standard output (including
standard error) as a string:
p.Start();
Usage
Output
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:
https://riptutorial.com/ 174
var startInfo = new ProcessStartInfo("cmd", command)
{
WorkingDirectory = @"C:\Windows\System32",
WindowStyle = ProcessWindowStyle.Hidden, // This does not actually work in
conjunction with "runas" - the console window will still appear!
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
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.
https://riptutorial.com/ 175
Chapter 43: System.IO
Examples
Reading a text file using StreamReader
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).
First, let's see three different ways of extracting data from a file.
• 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.
https://riptutorial.com/ 176
• 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.
using System.IO.Ports;
string[] ports = SerialPort.GetPortNames();
for (int i = 0; i < ports.Length; i++)
{
Console.WriteLine(ports[i]);
}
using System.IO.Ports;
SerialPort port = new SerialPort();
SerialPort port = new SerialPort("COM 1"); ;
SerialPort port = new SerialPort("COM 1", 9600);
NOTE: Those are just three of the seven overloads of the constructor for the SerialPort type.
Reading
https://riptutorial.com/ 177
//Note that you can swap out a byte-array for a char-array if you prefer.
byte[] buffer = new byte[length];
port.Read(buffer, 0, length);
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);
https://riptutorial.com/ 178
Chapter 44: System.IO.File class
Syntax
• string source;
• string destination;
Parameters
Parameter Details
The directory in which you would like to move source to (this variable should
destination
also contain the name (and file extension) of the file.
Examples
Delete a file
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
{
https://riptutorial.com/ 179
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.
To change a text file is not easy because its content must be moved around. For small files
https://riptutorial.com/ 180
easiest method is to read its content in memory and then write back modified text.
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)));
Text is saved encoded (see also Strings topic) then sometimes you may need to change its
encoding, this example assumes (for simplicity) that file is not too big and it can be entirely read in
memory:
When performing conversions do not forget that file may contain BOM (Byte Order Mark), to better
understand how it's managed refer to Encoding.UTF8.GetString doesn't take into account the
Preamble/BOM.
This example updates last write time of a huge number of files (using
System.IO.Directory.EnumerateFiles instead of System.IO.Directory.GetFiles()). Optionally you can
specify a search pattern (default is "*.*" and eventually search through a directory tree (not only
the specified directory):
This snippet is an helper function to enumerate all files older than a specified age, it's useful - for
https://riptutorial.com/ 181
example - when you have to delete old log files or old cached data.
File.Move
In order to move a file from one location to another, one simple line of code can achieve this:
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:
https://riptutorial.com/ 182
This will ensure that at that very moment, the file does exist, and can be moved to another
location. There may be times where a simple call to File.Exists won't be enough. If it isn't, check
again, convey to the user that the operation failed - or handle the exception.
IOException The file already exists or the source file could not be found.
https://riptutorial.com/ 183
Chapter 45: System.Net.Mail
Remarks
It is important to Dispose a System.Net.MailMessage because every single attachment contains a
Stream and these Streams need to be freed as soon as possible. The using statement ensures
that the Disposable object is Disposed also in case of Exceptions
Examples
MailMessage
Here is the example of creating of mail message with attachments. After creating we send this
message with the help of SmtpClient class. Default 25 port is used here.
MyMail.Subject = subject;
MyMail.IsBodyHtml = true;
MyMail.Body = body;
MyMail.Priority = MailPriority.Normal;
https://riptutorial.com/ 184
{
System.Net.Mail.Attachment attachment;
foreach (var item in Attachment)
{
attachment = new System.Net.Mail.Attachment(item);
MyMail.Attachments.Add(attachment);
}
}
smtpMailObj.Send(MyMail);
return true;
}
}
catch
{
return false;
}
}
}
MailMessagerepresents mail message which can be sent further using SmtpClient class. Several
attachments (files) can be added to mail message.
using System.Net.Mail;
https://riptutorial.com/ 185
Chapter 46: System.Reflection.Emit
namespace
Examples
Creating an assembly dynamically
using System;
using System.Reflection;
using System.Reflection.Emit;
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;
https://riptutorial.com/ 186
ModuleBuilder mb =
ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
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
https://riptutorial.com/ 187
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
}
}
https://riptutorial.com/ 188
Chapter 47:
System.Runtime.Caching.MemoryCache
(ObjectCache)
Examples
Adding Item to Cache (Set)
Set function inserts a cache entry into the cache by using a CacheItem instance to supply the key
and value for the cache entry.
System.Runtime.Caching.MemoryCache (ObjectCache)
This function gets existing item form cache, and if the item don't exist in cache, it will fetch item
based on the valueFetchFactory function.
//returns existing item form cache or add the new value if it does not exist.
https://riptutorial.com/ 189
var cachedItem = _cacheContainer.AddOrGetExisting(key, newValue, policy) as
Lazy<TValue>;
https://riptutorial.com/ 190
Chapter 48: Task Parallel Library (TPL)
Remarks
*Code should be considered on a case by case basis for multithreading. For example, if a loop
only has a few iterations or only does a small amount of the work, the overhead for parallelism
may outweigh the benefits.
The TPL is also available for .Net 3.5 included in a NuGet package, it is called Task Parallel
Library.
Examples
Basic producer-consumer loop (BlockingCollection)
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
https://riptutorial.com/ 191
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!");
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.
https://riptutorial.com/ 192
return n;
})).ToArray();
Task: WaitAny
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);
}
https://riptutorial.com/ 193
Task: handling exceptions (without using Wait)
Console.WriteLine("Starting tasks...");
while(tasks.All(task => !task.IsCompleted));
cancellationTokenSource.Cancel();
try
{
task.Wait();
}
catch(AggregateException ex)
https://riptutorial.com/ 194
{
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.
Task.WhenAny
await Task.WhenAll(tasks);
Console.WriteLine("All tasks finished!");
Task.WhenAll
https://riptutorial.com/ 195
Console.WriteLine(string.Join(",", results.Select(n => n.ToString())));
// Output: 1,2,3,4,5
Parallel.Invoke
try
{
Parallel.Invoke(actions);
}
catch(AggregateException ex)
{
foreach(var inner in ex.InnerExceptions)
Console.WriteLine("Task failed: " + inner.Message);
}
Parallel.ForEach
This example uses Parallel.ForEach to calculate the sum of the numbers between 1 and 10000 by
using multiple threads. To achieve thread-safety, Interlocked.Add is used to sum the numbers.
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
}
Parallel.For
This example uses Parallel.For to calculate the sum of the numbers between 1 and 10000 by
using multiple threads. To achieve thread-safety, Interlocked.Add is used to sum the numbers.
using System.Threading;
int Foo()
{
int total = 0;
Parallel.For(1, 10001,
() => 0, // initial value,
(num, state, localSum) => num + localSum,
https://riptutorial.com/ 196
localSum => Interlocked.Add(ref total, localSum));
return total; // total = 50005000
}
When you need to pass some data from the parent task to its children tasks, so it logically flows
with the execution, use AsyncLocal class:
void Main()
{
AsyncLocal<string> user = new AsyncLocal<string>();
user.Value = "initial user";
// 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();
// ouputs "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.
Parallel.ForEach in VB.NET
https://riptutorial.com/ 197
Parallel.ForEach(RowsToProcess, myOptions, Sub(currentRow, state)
ProcessRowParallel(currentRow, state)
End Sub)
Task that return a value has return type of Task< TResult > where TResult is the type of value that
needs to be returned. You can query the outcome of a Task by its Result property.
return sum;
});
If the Task execute asynchronously than awaiting the Task returns it's result.
https://riptutorial.com/ 198
Chapter 49: Task Parallel Library (TPL) API
Overviews
Remarks
The Task Parallel Library is set of public types and APIs that dramatically simplify the process of
adding parallelism and concurrency to an application. .Net. TPL was introduced in .Net 4 and is
the recommended way to write multi threaded and parallel code.
TPL takes care of work scheduling, thread affinity, cancellation support, state management, and
load balancing so that the programmer can focus on solving problems rather than spending time
on common low level details.
Examples
Perform work in response to a button click and update the UI
This example demonstrates how you can respond to a button click by performing some work on a
worker thread and then update the user interface to indicate completion
https://riptutorial.com/ 199
Chapter 50: Threading
Examples
Accessing form controls from other threads
If you want to change an attribute of a control such as a textbox or label from another thread than
the GUI thread that created the control, you will have to invoke it or else you might get an error
message stating:
"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:
https://riptutorial.com/ 200
}
And updating the textbox from any thread becomes a bit simpler:
Be aware that Control.BeginInvoke as used in this example is asynchronous, meaning that code
coming after a call to Control.BeginInvoke can be run immedeately after, whether or not the
passed delegate has been executed yet.
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.
https://riptutorial.com/ 201
Chapter 51: TPL Dataflow
Remarks
System.Threading.Tasks
System.Net.Http
System.Net
Post will try to add the item synchronously and return a bool saying whether it succeeded or not. It
may not succeed when, for example, a block has reached its BoundedCapcity and has no more
room for new items yet. SendAsync on the other hand will return an uncompleted Task<bool> that you
can await. That task will complete in the future with a true result when the block cleared its internal
queue and can accept more items or with a false result if it's declining permanently (e.g. as a
result of cancellation).
Examples
Posting to an ActionBlock and waiting for completion
block.Complete(); // Tell the block to complete and stop accepting new items
await block.Completion; // Asynchronously wait until all items completed processingu
https://riptutorial.com/ 202
// Create a block the accepts a uri and returns its contents as a string
var downloaderBlock = new TransformBlock<string, string>(
async uri => await httpClient.GetStringAsync(uri));
// 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(() =>
https://riptutorial.com/ 203
{
var consumer = new Consumer();
while(true)
{
consumer.Consume(buffer.Receive());
}
});
while (!cancellationToken.IsCancellationRequested)
{
var value = random.Next();
await bufferBlock.SendAsync(value, cancellationToken);
}
});
https://riptutorial.com/ 204
Chapter 52: Unit testing
Examples
Adding MSTest unit testing project to an existing solution
MSTest (the default testing framework) requires you to have your test classes decorated by a
[TestClass] attribute, and the test methods with a [TestMethod] attribute, and to be public.
[TestClass]
public class FizzBuzzFixture
{
[TestMethod]
public void Test1()
{
//arrange
var solver = new FizzBuzzSolver();
//act
var result = solver.FizzBuzz(1);
//assert
Assert.AreEqual("1",result);
}
}
https://riptutorial.com/ 205
Chapter 53: Upload file and POST data to
webserver
Examples
Upload file with WebRequest
To send a file and form data in single request, content should have multipart/form-data type.
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:
https://riptutorial.com/ 206
var response = await uploader.UploadFile("< YOUR URL >", "< PATH TO YOUR FILE >",
new Dictionary<string, object>
{
{"Comment", "test"},
{"Modified", DateTime.Now }
});
https://riptutorial.com/ 207
Chapter 54: Using Progress and IProgress
Examples
Simple Progress reporting
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 IProgress
It's important to note that the System.Progress<T> class does not have the Report() method available
on it. This method was implemented explicitly from the IProgress<T> interface, and therefore must
be called on a Progress<T> when it's cast to an IProgress<T>.
https://riptutorial.com/ 208
p1.Report(1); //compiler error, Progress does not contain method 'Report'
https://riptutorial.com/ 209
Chapter 55: VB Forms
Examples
Hello World in VB.NET Forms
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.
For Beginners
Some things all beginners should know / do that will help them have a good start with VB .Net:
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
https://riptutorial.com/ 210
seems like something you must use, ask.
Forms Timer
The Windows.Forms.Timer component can be used to provide the user information that is not
time critical. Create a form with one button, one label, and a Timer component.
For example it could be used to show the user the time of day periodically.
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.
https://riptutorial.com/ 211
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
ctSecs += 1
If ctSecs = 180 Then 'about 2.5 seconds off on my PC!
'stop timing
stpw.Stop()
Timer1.Stop()
'show actual elapsed time
'Is it near 180?
Label1.Text = stpw.Elapsed.TotalSeconds.ToString("n1")
End If
End Sub
End Class
After button1 is clicked, about three minutes pass and label1 shows the results. Does label1 show
180? Probably not. On my machine it showed 182.5!
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.
https://riptutorial.com/ 212
Read VB Forms online: https://riptutorial.com/dot-net/topic/2197/vb-forms
https://riptutorial.com/ 213
Chapter 56: Work with SHA1 in C#
Introduction
in this project you see how to work with SHA1 cryptographic hash function. for example get hash
from string and how to crack SHA1 hash. source on git hub:
https://github.com/mahdiabasi/SHA1Tool
Examples
#Generate SHA1 checksum of a file function
https://riptutorial.com/ 214
Chapter 57: Work with SHA1 in C#
Introduction
in this project you see how to work with SHA1 cryptographic hash function. for example get hash
from string and how to crack SHA1 hash.
Examples
#Generate SHA1 checksum of a file
https://riptutorial.com/ 215
Chapter 58: Write to and read from StdErr
stream
Examples
Write to standard error output using Console
};
process.ErrorDataReceived += (s, e) => errors.AppendLine(e.Data);
process.Start();
process.BeginErrorReadLine();
process.WaitForExit();
https://riptutorial.com/ 216
Chapter 59: XmlSerializer
Remarks
Do not use the XmlSerializer to parse HTML. For this, special libraries are available like the HTML
Agility Pack
Examples
Serialize object
Deserialize object
<Foo>
<Dog/>
</Foo>
https://riptutorial.com/ 217
<Store>
<Articles>
<Product/>
<Product/>
</Articles>
</Store>
[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); }
}
}
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:
https://riptutorial.com/ 218
var serializerDictionary = Enumerable.Range(0, allTypes.Length)
.ToDictionary (i => allTypes[i], i => allSerializers[i])
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:
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Linq;
using System.Linq;
https://riptutorial.com/ 219
catch (InvalidOperationException e)
{
Console.WriteLine();
Console.WriteLine("This error was anticipated,");
Console.WriteLine("we have not supplied a derived class.");
Console.WriteLine(e);
}
Console.WriteLine("Now trying to serialize with all of the type information:");
SetupSerializers(allTypes);
Serialize(sampleObject);
Console.WriteLine();
Console.WriteLine("Slides down well this time!");
}
Output:
https://riptutorial.com/ 220
<?xml version="1.0" encoding="utf-16"?>
<Container xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Base xsi:type="Derived">
<JustSomePropInBase>0</JustSomePropInBase>
<JustSomePropInDerived>0</JustSomePropInDerived>
</Base>
</Container>
Slides down well this time!
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.
https://riptutorial.com/ 221
Credits
S.
Chapters Contributors
No
https://riptutorial.com/ 222
Ringil, Robert Columbia, Stephen Byrne, the
berserker, Tomáš Hübelbauer
https://riptutorial.com/ 223
25 Managed Extensibility Framework Joe Amenta, Kirk Broadhurst, RamenChef
27 Networking Konamiman
33 ReadOnlyCollections tehDorf
Regular Expressions
35 BrunoLM, Denuath, Matt dc, tehDorf
(System.Text.RegularExpressions)
SpeechRecognitionEngine class to
38 ProgramFOX, RamenChef
recognize speech
https://riptutorial.com/ 224
44 System.IO.File class Adriano Repetti, delete me
System.Runtime.Caching.MemoryCache
47 Guanxi, RamenChef
(ObjectCache)
https://riptutorial.com/ 225