<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>CodingOnWheels.com</title><description>Dixin&apos;s blog</description><link>https://dixin.github.io/</link><language>en</language><item><title>C# Functional Programming In-Depth (14) Asynchronous Function</title><link>https://dixin.github.io/posts/functional-csharp-asynchronous-function/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-asynchronous-function/</guid><description>Asynchronous function can improve the responsiveness and scalability of the application and service. C# 5.0 introduces asynchronous function to greatly simplify the async programming model.</description><pubDate>Tue, 04 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Asynchronous function can improve the responsiveness and scalability of the application and service. C# 5.0 introduces asynchronous function to greatly simplify the async programming model.&lt;/p&gt;
&lt;h2&gt;Task, Task&amp;lt;TResult&amp;gt; and asynchrony&lt;/h2&gt;
&lt;p&gt;The C# async programming model uses System.Threading.Tasks.Task to represent async operation without output, and uses System.Threading.Tasks.Task&amp;lt;TResult&amp;gt; to represent async operation with TResult output:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public partial class Task : IAsyncResult
{
public Task(Action action); // Wraps () –&amp;gt; void function.

public void Start();

public void Wait();

public TaskStatus Status { get; } // Created, WaitingForActivation, WaitingToRun, Running, WaitingForChildrenToComplete, RanToCompletion, Canceled, Faulted.

public bool IsCanceled { get; }

public bool IsCompleted { get; }

public bool IsFaulted { get; }

public AggregateException Exception { get; }

Task ContinueWith(Action&amp;lt;Task&amp;gt; continuationAction);

Task&amp;lt;TResult&amp;gt; ContinueWith&amp;lt;TResult&amp;gt;(Func&amp;lt;Task, TResult&amp;gt; continuationFunction);

// Other members.
}

public partial class Task&amp;lt;TResult&amp;gt; : Task
{
public Task(Func&amp;lt;TResult&amp;gt; function); // Wraps () –&amp;gt; TResult function.

public TResult Result { get; }

public Task ContinueWith(Action&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; continuationAction);

public Task&amp;lt;TNewResult&amp;gt; ContinueWith&amp;lt;TNewResult&amp;gt;(
Func&amp;lt;Task&amp;lt;TResult&amp;gt;, TNewResult&amp;gt; continuationFunction);

// Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Task can be constructed with () –&amp;gt;void function, and Task&amp;lt;TResult&amp;gt; can be constructed with () –&amp;gt; TResult function. They can be started by calling the Start method. A () –&amp;gt; void function or () –&amp;gt; TResult function runs synchronously on the thread. In contrast, a task runs asynchronously, and does not block the current thread. Its status can be queried by the Status, IsCanceled, IsCompleted, IsFaulted properties. A task can be waited by calling its Wait method, which blocks the current thread until the task is completed successfully, or fails, or is cancelled. For Task&amp;lt;TResult&amp;gt;, when the underlying async operation is completed successfully, the result is available through Result property. For Task or Task&amp;lt;TResult&amp;gt;, if the underlying async operation fails with exception, the exception is available through the Exception property. A task can be chained with another async continuation operation by calling the ContinueWith methods. When the task finishes running, the specified continuation starts running asynchronously. If the task already finishes running when its ContinueWith method is called, then the specified continuation immediately starts running. The following example constructs and starts a task to read a file, and chains another continuation task to write the contents to another file:&lt;/p&gt;
&lt;p&gt;internal static partial class Functions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
internal static void ConstructTask(string readPath, string writePath)
{
Thread.CurrentThread.ManagedThreadId.WriteLine(); // 10
Task&amp;lt;string&amp;gt; task = new Task&amp;lt;string&amp;gt;(() =&amp;gt;
{
Thread.CurrentThread.ManagedThreadId.WriteLine(); // 8
return File.ReadAllText(readPath);
});
task.Start();
Task continuationTask = task.ContinueWith(antecedentTask =&amp;gt;
{
Thread.CurrentThread.ManagedThreadId.WriteLine(); // 9
object.ReferenceEquals(antecedentTask, task).WriteLine(); // True
if (antecedentTask.IsFaulted)
{
antecedentTask.Exception.WriteLine();
}
else
{
File.WriteAllText(writePath, antecedentTask.Result);
}
});
continuationTask.Wait();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As async operations, when tasks are started, the wrapped functions are by default scheduled to runtime’s thread pool to execute, so that their thread ids are different from the caller thread id.&lt;/p&gt;
&lt;p&gt;In .NET Framework, Task also implements System.Threading.IThreadPoolWorkItem and IDisposable interfaces. Its usage is the same as in .NET Core. Do not bother disposing tasks.&lt;/p&gt;
&lt;p&gt;Task also provides Run methods to construct and automatically start tasks:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public partial class Task : IAsyncResult
{
public static Task Run(Action action);

public static Task&amp;lt;TResult&amp;gt; Run&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; function);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now compare the following functions:&lt;/p&gt;
&lt;p&gt;internal static void Write(string path, string contents) =&amp;gt; File.WriteAllText(path, contents);&lt;/p&gt;
&lt;p&gt;internal static Task&amp;lt;string&amp;gt;ReadAsync(string path) =&amp;gt; Task.Run(() =&amp;gt; File.ReadAllText(path));&lt;/p&gt;
&lt;p&gt;Write without output and Read with string output run synchronously. WriteAsync with Task output and ReadAsync with Task&amp;lt;string&amp;gt; output run asynchronously, where Task can be viewed as future void, and Task&amp;lt;TResult&amp;gt; can be viewed as future TResult result. Here WriteAsync and ReadAsync become async by simply offloading the operations to thread pool. This is for demonstration purpose, and does not bring any scalability improvement. A better implementation is discussed later.&lt;/p&gt;
&lt;p&gt;internal static void CallReadWrite(string path, string contents)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Write(path, contents); // Blocking.
// When the underlying write operation is done, the call is completed with no result.
string result = Read(path); // Blocking.
// When the underlying read operation is done, the call is completed with result available.

Task writeTask = WriteAsync(path, contents); // Non-blocking.
// When the task is constructed and started, the call is completed immediately.
// The underlying write operation is scheduled, and will be completed in the future with no result.
Task&amp;lt;string&amp;gt; readTask = ReadAsync(path); // Non-blocking.
// When the task is constructed and started, the call is completed immediately.
// The underlying read operation is scheduled, and will be completed in the future with result available.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When Write is called, its execution blocks the current thread. When the writing operation is done synchronously, it does not output any result, and then the caller thread can continue execution. Similarly, when Read is called, its execution blocks the current thread too. When the reading operation is done synchronously, it outputs the result, so that the result is available to the caller and the caller can continue execution. When WriteAsync is called, it calls Task.Run to construct a Task instance with the writing operation, start the task, then immediately outputs the task to the caller. Then the caller can continue without being blocked by the writing operation execution. By default, the writing operation is scheduled to thread pool, when it is done, the writing operation outputs no result, and the task’s Status is updated. Similarly, when ReadAsync is called, it also calls Task.Run to construct a Task&amp;lt;string&amp;gt; instance with the reading operation, start the task, then immediately outputs the task to the caller. Then the caller can continue without being blocked by the reading operation execution. By default, the reading operation is also scheduled to thread pool, when it is done, the reading operation has a result, and the task’s Status is updated, with the result available through the Result property.&lt;/p&gt;
&lt;h2&gt;Named async function&lt;/h2&gt;
&lt;p&gt;By default, named async function’s output type is Task or Task&amp;lt;TResult&amp;gt;, and has an Async or AsyncTask postfix in the name as the convention. The following example is a file read and write workflow of sync function calls:&lt;/p&gt;
&lt;p&gt;internal static void ReadWrite(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
string contents = Read(readPath);
Write(writePath, contents);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The same logic can be implemented by calling the async version of functions:&lt;/p&gt;
&lt;p&gt;internal static async Task ReadWriteAsync(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
string contents = await ReadAsync(readPath);
await WriteAsync(writePath, contents);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here await keyword is used for each async function call, and the code structure remains the same as the sync workflow. When await keyword is used in function body, the async modifier is required for that function’s signature. Regarding the workflow outputs no result, the async function outputs Task (future void). This ReadWriteAsync function calls async functions, itself is also async function, since it has the async modifier and Task output. When ReadWriteAsync is called, it works the same way as ReadAsync and WriteAsync. it does not block its caller, and immediately outputs a task to represent the scheduled read and write workflow.&lt;/p&gt;
&lt;p&gt;So the await keyword can be viewed as virtually waiting for the task’s underlying async operation to finish. If the task fails, exception is thrown. If the task is completed successfully, the continuation right after the await expression is called back. If the task has a result, await expression can extract the result. Therefore, the async workflow keeps the same looking of sync workflow. There is no ContinueWith call needed to build the continuation. The following example is a more complex database query workflow of sync function calls, with an int value as the query result:&lt;/p&gt;
&lt;p&gt;internal static int Query(DbConnection connection, StreamWriter logWriter) // Output int.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
try
{
connection.Open(); // Output void.
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = &quot;SELECT 1;&quot;;
using (DbDataReader reader = command.ExecuteReader()) // Output DbDataReader.
{
if (reader.Read()) // Output bool.
{
return (int)reader[0];
}
throw new InvalidOperationException(&quot;Failed to call sync functions.&quot;);
}
}
}
catch (SqlException exception)
{
logWriter.WriteLine(exception.ToString()); // Output void.
throw new InvalidOperationException(&quot;Failed to call sync functions.&quot;, exception);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the DbConnection.Open, DbCommand.ExecuteReader, DbDataReader.Read, StreamWriter.WriteLine functions have async version provided as DbConnection.OpenAsync, DbCommand.ExecuteReaderAsync, DbDataReader.ReadAsync, StreamWriter.WriteLineAsync. They output either Task or Task&amp;lt;TResult&amp;gt;. With the async and await keywords, it easy to call these async functions:&lt;/p&gt;
&lt;p&gt;internal static async Task&amp;lt;int&amp;gt; QueryAsync(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbConnection connection, StreamWriter logWriter) // Output Task&amp;lt;int&amp;gt; instead of int.
{
try
{
await connection.OpenAsync(); // Output Task instead of void.
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = &quot;SELECT 1;&quot;;
using (DbDataReader reader = await command.ExecuteReaderAsync()) // Output Task&amp;lt;DbDataReader&amp;gt; instead of DbDataReader.
{
if (await reader.ReadAsync()) // Output Task&amp;lt;bool&amp;gt; instead of bool.
{
return (int)reader[0];
}
throw new InvalidOperationException(&quot;Failed to call async functions.&quot;);
}
}
}
catch (SqlException exception)
{
await logWriter.WriteLineAsync(exception.ToString()); // Output Task instead of void.
throw new InvalidOperationException(&quot;Failed to call async functions.&quot;, exception);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, the async workflow persists the same code structure as the sync workflow, including try-catch, using, if statements, etc. Without this syntax, it is a lot more complex to call ContinueWith and manually build above workflow. Regarding the async function has an int result, its output type is Task&amp;lt;int&amp;gt; (future int).&lt;/p&gt;
&lt;p&gt;The above Write and Read functions calls File.WriteAllText and File.ReadAllText to execute sync I/O operation, which are internally implemented by calling StreamWriter.Write and StreamReader.ReadToEnd. Now with the async and await keywords, WriteAsync and ReadAsync can be reimplemented as real async I/O (assuming async I/O is actually supported by the underlying operating system) by calling StreamWriter.WriteAsync and StreamReader.ReadToEndAsync:&lt;/p&gt;
&lt;p&gt;internal static async Task WriteAsync(string path, string contents)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
// File.WriteAllText implementation:
// using (StreamWriter writer = new StreamWriter(new FileStream(
// path: path, mode: FileMode.Create, access: FileAccess.Write,
// share: FileShare.Read, bufferSize: 4096, useAsync: false)))
// {
// writer.Write(contents);
// }
using (StreamWriter writer = new StreamWriter(new FileStream(
path: path, mode: FileMode.Create, access: FileAccess.Write,
share: FileShare.Read, bufferSize: 4096, useAsync: true)))
{
await writer.WriteAsync(contents);
}
}

internal static async Task&amp;lt;string&amp;gt;ReadAsync(string path)
{
// File.ReadAllText implementation:
// using (StreamReader reader = new StreamReader(new FileStream(
// path: path, mode: FileMode.Open, access: FileAccess.Read,
// share: FileShare.Read, bufferSize: 4096, useAsync: false)))
// {
// return reader.ReadToEnd();
// }
using (StreamReader reader = new StreamReader(new FileStream(
path: path, mode: FileMode.Open, access: FileAccess.Read,
share: FileShare.Read, bufferSize: 4096, useAsync: true)))
{
return await reader.ReadToEndAsync();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There is one special scenario where async function has void output – async function as event handler. For example, ObservableCollection&amp;lt;T&amp;gt; has a CollectionChanged event:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.ObjectModel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public class ObservableCollection&amp;lt;T&amp;gt; : Collection&amp;lt;T&amp;gt;, INotifyCollectionChanged, INotifyPropertyChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;

// Other members.
}
}

namespace System.Collections.Specialized
{
// (object, NotifyCollectionChangedEventArgs) –&amp;gt; void.
public delegate void NotifyCollectionChangedEventHandler(
object sender, NotifyCollectionChangedEventArgs e);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This event requires its handler to be a function of type (object, NotifyCollectionChangedEventArgs) –&amp;gt; void. So, when defining an async function as the above event’s handler, that async function has void output instead of Task:&lt;/p&gt;
&lt;p&gt;private static readonly StringBuilder Logs = new StringBuilder();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The await keyword works with task from async function as well as any Task and Task&amp;lt;TResult&amp;gt; instance:&lt;/p&gt;
&lt;p&gt;internal static async Task AwaitTasks(string path)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Task&amp;lt;string&amp;gt; task1 = ReadAsync(path);
string contents = await task1;
// Equivalent to: string contents = await ReadAsync(path);

Task task2 = WriteAsync(path, contents);
await task2;
// Equivalent to: await WriteAsync(path, contents);

Task task3 = Task.Run(() =&amp;gt; { });
await task3;
// Equivalent to: await Task.Run(() =&amp;gt; { });

Task&amp;lt;int&amp;gt; task4 = Task.Run(() =&amp;gt; 0);
int result = await task4;
// Equivalent to: int result = await Task.Run(() =&amp;gt; 0);

Task task5 = Task.Delay(TimeSpan.FromSeconds(10));
await task5;
// Equivalent to: await Task.Delay(TimeSpan.FromSeconds(10));

Task&amp;lt;int&amp;gt; task6 = Task.FromResult(result);
result = await task6;
// Equivalent to: result = await Task.FromResult(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a task is never started, apparently it never finishes running. The code after its await expression is never called back:&lt;/p&gt;
&lt;p&gt;internal static async Task HotColdTasks(string path)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Task hotTask = new Task(() =&amp;gt; { });
hotTask.Start();
await hotTask;
hotTask.Status.WriteLine();

Task coldTask = new Task(() =&amp;gt; { });
await coldTask;
coldTask.Status.WriteLine(); // Never execute.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Task not started yet is called cold task, and task already started is called hot task. As a convention, any function with task output should always output a hot task. All APIs in .NET Standard follow this convention.&lt;/p&gt;
&lt;h2&gt;Awaitable-awaiter pattern&lt;/h2&gt;
&lt;p&gt;C# compiles the await expression with the awaitable-awaiter pattern. Besides Task and Task&amp;lt;TResult&amp;gt;, the await keyword can be used with any awaitable type. An awaitable type has a GetAwaiter instance or extension method to output an awaiter. An awaiter type implements System.Runtime.CompilerServices.INotifyCompletion interface, also has an IsCompleted property with bool output, and a GetResult instance method with or without output. The following IAwaitable and IAwaiter interfaces demonstrate the awaitable-awaiter pattern for operation with no result:&lt;/p&gt;
&lt;p&gt;public interface IAwaitable&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
IAwaiter GetAwaiter();
}

public interface IAwaiter : INotifyCompletion
{
bool IsCompleted { get; }

void GetResult(); // No result.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following IAwaitable&amp;lt;TResult&amp;gt; and IAwaiter&amp;lt;TResult&amp;gt; interfaces demonstrate the awaitable-awaiter pattern for operations with a result:&lt;/p&gt;
&lt;p&gt;public interface IAwaitable&amp;lt;TResult&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
IAwaiter&amp;lt;TResult&amp;gt;GetAwaiter();
}

public interface IAwaiter&amp;lt;TResult&amp;gt;: INotifyCompletion
{
bool IsCompleted { get; }

TResult GetResult(); // TResult result.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And INotifyCompletion interface has a single OnCompleted method to chain a continuation:&lt;/p&gt;
&lt;p&gt;namespace System.Runtime.CompilerServices&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public interface INotifyCompletion
{
void OnCompleted(Action continuation);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here is how Task and Task&amp;lt;TResult&amp;gt; implement the awaitable-awaiter pattern. Task can be virtually viewed as implementation of IAwaitable, it has a GetAwaiter instance method outputting System.Runtime.CompilerServices.TaskAwaiter, which can be virtually viewed as implementation of IAwaiter; Similarly, Task&amp;lt;TResult&amp;gt; can be virtually viewed as implementation of IAwaitable&amp;lt;TResult&amp;gt;, it has a GetAwaiter method outputting System.Runtime.CompilerServices.TaskAwaiter&amp;lt;TResult&amp;gt;, which can be virtually viewed as implementation of IAwaiter&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public partial class Task : IAsyncResult
{
public TaskAwaiter GetAwaiter();
}

public partial class Task&amp;lt;TResult&amp;gt; : Task
{
public TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();
}
}

namespace System.Runtime.CompilerServices
{
public struct TaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
{
public bool IsCompleted { get; }

public void GetResult(); // No result.

public void OnCompleted(Action continuation);

// Other members.
}

public struct TaskAwaiter&amp;lt;TResult&amp;gt; : ICriticalNotifyCompletion, INotifyCompletion
{
public bool IsCompleted { get; }

public TResult GetResult(); // TResult result.

public void OnCompleted(Action continuation);

// Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Any other type can be used with the await keyword, as long as the awaitable-awaiter pattern is implemented. Take delegate type Action as example, a GetAwaiter method can be easily implemented as its extension method, by reusing above TaskAwaiter:&lt;/p&gt;
&lt;p&gt;public static TaskAwaiter GetAwaiter(this Action action) =&amp;gt; Task.Run(action).GetAwaiter();&lt;/p&gt;
&lt;p&gt;Similarly, this pattern can be implemented for Func&amp;lt;TResult&amp;gt;, by reusing TaskAwaiter&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;p&gt;public static TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function) =&amp;gt;&lt;/p&gt;
&lt;p&gt;Task.Run(function).GetAwaiter();&lt;/p&gt;
&lt;p&gt;Now the await keyword can be directly used with a function of Action type or Func&amp;lt;TResult&amp;gt; type:&lt;/p&gt;
&lt;p&gt;internal static async Task AwaitFunctions(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Func&amp;lt;string&amp;gt;read = () =&amp;gt; File.ReadAllText(readPath);
string contents = await read;

Action write = () =&amp;gt; File.WriteAllText(writePath, contents);
await write;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Async state machine&lt;/h2&gt;
&lt;p&gt;As fore mentioned, with async and await keywords, an async function outputs a task immediately, so it is non-blocking. At compile time, the workflow of an async function is compiled to an async state machine. At runtime, when this async function is called, it just starts that generated async state machine , and immediately outputs a task representing the workflow in the async state machine. To demonstrate this, define the following async methods:&lt;/p&gt;
&lt;p&gt;internal static async Task&amp;lt;T&amp;gt; Async&amp;lt;T&amp;gt;(T value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
T value1 = Start(value);
T result1 = await Async1(value1);
T value2 = Continuation1(result1);
T result2 = await Async2(value2);
T value3 = Continuation2(result2);
T result3 = await Async3(value3);
T result = Continuation3(result3);
return result;
}

internal static T Start&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async1&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.Run(() =&amp;gt; value);

internal static T Continuation1&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async2&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.FromResult(value);

internal static T Continuation2&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async3&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.Run(() =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal static T Continuation3&amp;lt;T&amp;gt;(T value) =&amp;gt; value;&lt;/p&gt;
&lt;p&gt;After compilation, the async modifier is gone. The async function becomes a normal function to start an async state machine:&lt;/p&gt;
&lt;p&gt;[AsyncStateMachine(typeof(AsyncStateMachine&amp;lt;&amp;gt;))]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task&amp;lt;T&amp;gt; CompiledAsync&amp;lt;T&amp;gt;(T value)
{
AsyncStateMachine&amp;lt;T&amp;gt;asyncStateMachine = new AsyncStateMachine&amp;lt;T&amp;gt;()
{
Value = value,
Builder = AsyncTaskMethodBuilder&amp;lt;T&amp;gt;.Create(),
State = -1 // -1 means start.
};
asyncStateMachine.Builder.Start(ref asyncStateMachine);
return asyncStateMachine.Builder.Task;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the generated async state machine is a structure in release build, and a class in debug build:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[StructLayout(LayoutKind.Auto)]
private struct AsyncStateMachine&amp;lt;TResult&amp;gt;: IAsyncStateMachine
{
public int State;

public AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; Builder;

public TResult Value;

private TaskAwaiter&amp;lt;TResult&amp;gt; awaiter;

void IAsyncStateMachine.MoveNext()
{
TResult result;
try
{
switch (this.State)
{
case -1: // Start code from the beginning to the 1st await.
// Workflow begins.
TResult value1 = Start(this.Value);
this.awaiter = Async1(value1).GetAwaiter();
if (this.awaiter.IsCompleted)
{
// If the task returned by Async1 is already completed, immediately execute the continuation.
goto case 0;
}
else
{
this.State = 0;
// If the task returned by Async1 is not completed, specify the continuation as its callback.
this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
// Later when the task returned by Async1 is completed, it calls back MoveNext, where State is 0.
return;
}
case 0: // Continuation code from after the 1st await to the 2nd await.
// The task returned by Async1 is completed. The result is available immediately through GetResult.
TResult result1 = this.awaiter.GetResult();
TResult value2 = Continuation1(result1);
this.awaiter = Async2(value2).GetAwaiter();
if (this.awaiter.IsCompleted)
{
// If the task returned by Async2 is already completed, immediately execute the continuation.
goto case 1;
}
else
{
this.State = 1;
// If the task returned by Async2 is not completed, specify the continuation as its callback.
this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
// Later when the task returned by Async2 is completed, it calls back MoveNext, where State is 1.
return;
}
case 1: // Continuation code from after the 2nd await to the 3rd await.
// The task returned by Async2 is completed. The result is available immediately through GetResult.
TResult result2 = this.awaiter.GetResult();
TResult value3 = Continuation2(result2);
this.awaiter = Async3(value3).GetAwaiter();
if (this.awaiter.IsCompleted)
{
// If the task returned by Async3 is already completed, immediately execute the continuation.
goto case 2;
}
else
{
this.State = 2;
// If the task returned by Async3 is not completed, specify the continuation as its callback.
this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
// Later when the task returned by Async3 is completed, it calls back MoveNext, where State is 1.
return;
}
case 2: // Continuation code from after the 3rd await to the end.
// The task returned by Async3 is completed. The result is available immediately through GetResult.
TResult result3 = this.awaiter.GetResult();
result = Continuation3(result3);
this.State = -2; // -2 means end.
this.Builder.SetResult(result);
// Workflow ends.
return;
}
}
catch (Exception exception)
{
this.State = -2; // -2 means end.
this.Builder.SetException(exception);
}
}

[DebuggerHidden]
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine asyncStateMachine) =&amp;gt;
this.Builder.SetStateMachine(asyncStateMachine);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The generated async state machine is a finite state machine:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-C-13-Pure-Function_F89E/clip_image002_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-C-13-Pure-Function_F89E/clip_image002_thumb.gif&quot; alt=&quot;clip_image002&quot; title=&quot;clip_image002&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The workflow is compiled into a switch statement in its MoveNext method. The original workflow is split to 4 parts by the 3 await keywords, and compiled to 4 cases of the switch statement. The parameter of the workflow is compiled as a field of the state machine, so it can be accessed by the workflow inside MoveNext. When the state machine is initialized, its initial state is –1, which means to start. Once the state machine is started, MoveNext is called, and the case –1 block is executed, which has the code from the beginning of the workflow to the first await expression, which is compiled to a GetAwaiter call. If the awaiter is already completed, then the continuation should immediate be executed by going to case 0 block directly; If the awaiter is not completed, the continuation (MoveNext call with next state 0) is specified as the awaiter’s callback when it is completed in the future. In either case, when code in case 0 block is executed, the previous awaiter is already completed, and its result is immediately available through its GetResult method. The execution goes on in the same pattern, until the last block of case 2 is executed.&lt;/p&gt;
&lt;h2&gt;Runtime context capture&lt;/h2&gt;
&lt;p&gt;At runtime, when executing an await expression, if the awaited task is not completed yet, the continuation is scheduled as callback. As a result, the continuation can be executed by a thread different from initial caller thread. By default, the initial thread’s runtime context information is captured, and are reused by the callback thread to execute the continuation. To demonstrate this, the above awaitable-awaiter pattern for Action can be re-implemented with the following custom awaiter:&lt;/p&gt;
&lt;p&gt;public static IAwaiter GetAwaiter(this Action action) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new ActionAwaiter(Task.Run(action));

public class ActionAwaiter : IAwaiter
{
private readonly (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext;

private readonly Task task;

public ActionAwaiter(Task task) =&amp;gt;
(this.task, this.runtimeContext) = (task, RuntimeContext.Capture()); // Capture runtime context when initialized.

public bool IsCompleted =&amp;gt; this.task.IsCompleted;

public void GetResult() =&amp;gt; this.task.Wait();

public void OnCompleted(Action continuation) =&amp;gt; this.task.ContinueWith(task =&amp;gt;
this.runtimeContext.Execute(continuation));// Execute continuation on captured runtime context.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the awaiter is constructed, it captures the runtime context information, including System.Threading.SynchronizationContext, System.Threading.Tasks.TaskScheduler, and System.Threading.ExecutionContext of current thread. Then in OnCompleted, when the continuation is called back, it is executed with the previously captured runtime context information. The custom awaiter can be implemented for Func&amp;lt;TResult&amp;gt; in the same pattern:&lt;/p&gt;
&lt;p&gt;public static IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new FuncAwaiter&amp;lt;TResult&amp;gt;(Task.Run(function));

public class FuncAwaiter&amp;lt;TResult&amp;gt; : IAwaiter&amp;lt;TResult&amp;gt;
{
private readonly (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext =
RuntimeContext.Capture();

private readonly Task&amp;lt;TResult&amp;gt; task;

public FuncAwaiter(Task&amp;lt;TResult&amp;gt; task) =&amp;gt; (this.task, this.runtimeContext) = (task, RuntimeContext.Capture()); // Capture runtime context when initialized.

public bool IsCompleted =&amp;gt; this.task.IsCompleted;

public TResult GetResult() =&amp;gt; this.task.Result;

public void OnCompleted(Action continuation) =&amp;gt; this.task.ContinueWith(task =&amp;gt;
this.runtimeContext.Execute(continuation)); // Execute continuation on captured runtime context.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following is a basic implementation of runtime context capture and resume:&lt;/p&gt;
&lt;p&gt;public static class RuntimeContext&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public static (SynchronizationContext, TaskScheduler, ExecutionContext) Capture() =&amp;gt;
(SynchronizationContext.Current, TaskScheduler.Current, ExecutionContext.Capture());

public static void Execute(
this (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext, Action continuation)
{
var (synchronizationContext, taskScheduler, executionContext) = runtimeContext;
if (synchronizationContext != null &amp;amp;&amp;amp; synchronizationContext.GetType() != typeof(SynchronizationContext))
{
if (synchronizationContext == SynchronizationContext.Current)
{
executionContext.Run(continuation);
}
else
{
executionContext.Run(() =&amp;gt; synchronizationContext.Post(
d: state =&amp;gt; continuation(), state: null));
}
return;
}
if (taskScheduler != null &amp;amp;&amp;amp; taskScheduler != TaskScheduler.Default)
{
Task continuationTask = new Task(continuation);
continuationTask.Start(taskScheduler);
return;
}
executionContext.Run(continuation);
}

private static void Run(this ExecutionContext executionContext, Action continuation)
{
if (executionContext != null)
{
ExecutionContext.Run(
executionContext: executionContext, callback: state =&amp;gt; continuation(), state: null);
}
else
{
continuation();
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When Capture is called, it captures a 3-tuple of SynchronizationContext, TaskScheduler, and ExecutionContext When the continuation is executed, first the previously captured SynchronizationContext is checked. If a specialized SynchronizationContext is captured and it is different from current SynchronizationContext, then the continuation is executed with the captured SynchronizationContext and ExecutionContext. When there is no specialized SynchronizationContext captured, then the TaskScheduler is checked. If a specialized TaskScheduler is captured, it is used to schedule the continuation as a task. For all the other cases, the continuation is executed with the captured ExecutionContext.&lt;/p&gt;
&lt;p&gt;Task and Task&amp;lt;TResult&amp;gt; provides a ConfigureAwait method to specify whether the continuation is marshalled to the previously captured runtime context:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public partial class Task : IAsyncResult
{
public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext);
}

public partial class Task&amp;lt;TResult&amp;gt; : Task
{
public ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt; ConfigureAwait(bool continueOnCapturedContext);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To demonstrate the runtime context capture, define a custom task scheduler, which simply start a background thread to execute each task:&lt;/p&gt;
&lt;p&gt;public class BackgroundThreadTaskScheduler : TaskScheduler&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
protected override IEnumerable&amp;lt;Task&amp;gt; GetScheduledTasks() =&amp;gt;
throw new NotImplementedException();

protected override void QueueTask(Task task) =&amp;gt;
new Thread(() =&amp;gt; this.TryExecuteTask(task)) { IsBackground = true }.Start();

protected override bool TryExecuteTaskInline(
Task task, bool taskWasPreviouslyQueued) =&amp;gt;
this.TryExecuteTask(task);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following async function has 2 await expressions, where ConfigureAwait is called with different bool values:&lt;/p&gt;
&lt;p&gt;internal static async Task ConfigureRuntimeContextCapture(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string readPath, string writePath)
{
TaskScheduler taskScheduler1 = TaskScheduler.Current;
string contents = await ReadAsync(readPath).ConfigureAwait(
continueOnCapturedContext: true);
// Equivalent to: await ReadAsync(readPath);

// Continuation is executed with captured runtime context.
TaskScheduler taskScheduler2 = TaskScheduler.Current;
object.ReferenceEquals(taskScheduler1, taskScheduler2).WriteLine(); // True
await WriteAsync(writePath, contents).ConfigureAwait(
continueOnCapturedContext: false);

// Continuation is executed without captured runtime context.
TaskScheduler taskScheduler3 = TaskScheduler.Current;
object.ReferenceEquals(taskScheduler1, taskScheduler3).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To demonstrate the task scheduler capture, call the above async function by specifying the custom task scheduler:&lt;/p&gt;
&lt;p&gt;internal static async Task CallConfigureContextCapture(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Task&amp;lt;Task&amp;gt; task = new Task&amp;lt;Task&amp;gt;(() =&amp;gt;
ConfigureRuntimeContextCapture(readPath, writePath));
task.Start(new BackgroundThreadTaskScheduler());
await task.Unwrap(); // Equivalent to: await await task;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here since async function ConfigureRuntimeContextCapture outputs Task, so the task constructed with () -&amp;gt; Task function is of type Task&amp;lt;Task&amp;gt;. Similarly, if task is constructed with () -&amp;gt; Task&amp;lt;TResult&amp;gt; function, the constructed task is of type Task&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt;. For this scenario, Unwrap extension methods are provided to convert nested task to normal task:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public static class TaskExtensions
{
public static Task Unwrap(this Task&amp;lt;Task&amp;gt; task);

public static Task&amp;lt;TResult&amp;gt; Unwrap&amp;lt;TResult&amp;gt;(this Task&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; task);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When start executing ConfigureRuntimeContextCapture, the initial task scheduler is specified to be the custom task scheduler, BackgroundThreadTaskScheduler. In the first await expression, ConfigureAwait is called with true, so that the runtime context information is captured and the continuation is executed with the captured runtime context information. This is the default behaviour, so calling ConfigureAwait with true is equivalent to not calling ConfigureAwait at all. As a result, the first continuation is executed with the same custom task scheduler. In the second await expression, ConfigureAwait is called with false, so the runtime context information is not captured. As a result, the second continuation is executed with the default task scheduler, System.Threading.Tasks.ThreadPoolTaskScheduler.&lt;/p&gt;
&lt;p&gt;The runtime context capture can be also demonstrated by SynchronizationContext. SynchronizationContext is inherited by different implementations in different application models, for example:&lt;/p&gt;
&lt;p&gt;· ASP.NET: System.Web.AspNetSynchronizationContext&lt;/p&gt;
&lt;p&gt;· WPF: System.Windows.Threading.DispatcherSynchronizationContext&lt;/p&gt;
&lt;p&gt;· WinForms: System.Windows.Forms.WindowsFormsSynchronizationContext&lt;/p&gt;
&lt;p&gt;· Windows Universal: System.Threading.WinRTCoreDispatcherBasedSynchronizationContext&lt;/p&gt;
&lt;p&gt;· Xamarin.Android: Android.App.SyncContext&lt;/p&gt;
&lt;p&gt;· Xamarin.iOS: UIKit.UIKitSynchronizationContext&lt;/p&gt;
&lt;p&gt;Take Windows Universal application as example. In Visual Studio on Windows, create a Windows Universal application, add a button to its UI:&lt;/p&gt;
&lt;p&gt;&amp;lt;Button x:Name=&quot;Button&quot; Content=&quot;Button&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Click=&quot;ButtonClick&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;In the code behind, implement the Click event handler as an async function:&lt;/p&gt;
&lt;p&gt;private async void ButtonClick(object sender, RoutedEventArgs e)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
SynchronizationContext synchronizationContext1 = SynchronizationContext.Current;
ExecutionContext executionContext1 = ExecutionContext.Capture();
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(
continueOnCapturedContext: true);
// Equivalent to: await Task.Delay(TimeSpan.FromSeconds(1));

// Continuation is executed with captured runtime context.
SynchronizationContext synchronizationContext2 = SynchronizationContext.Current;
Debug.WriteLine(synchronizationContext1 == synchronizationContext2); // True
this.Button.Background = new SolidColorBrush(Colors.Blue); // UI update works.
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(
continueOnCapturedContext: false);

// Continuation is executed without captured runtime context.
SynchronizationContext synchronizationContext3 = SynchronizationContext.Current;
Debug.WriteLine(synchronizationContext1 == synchronizationContext3); // False
this.Button.Background = new SolidColorBrush(Colors.Yellow); // UI update fails.
// Exception: The application called an interface that was marshalled for a different thread.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For Windows Universal application, the SynchronizationContext is only available for the UI thread, and application UI can only be updated with UI thread’s SynchronizationContext. When the button is clicked, the UI thread calls the async function ButtonClick, so the UI thread’s SynchronizationContext is captured. Similar to the previous example, when ConfigureAwait is called with true, the continuation is executed with the previously captured SynchronizationContext, so the continuation can update the UI successfully. When ConfigureAwait is called with true, the continuation is not executed with the SynchronizationContext captured from UI thread, and it fails to update the UI and throws exception.&lt;/p&gt;
&lt;h2&gt;Generalized async function output type and async method builder&lt;/h2&gt;
&lt;p&gt;Since C# 7, async function is supported to have any awaitable output type, as long as it has an async method builder specified. Take Func&amp;lt;TResult&amp;gt; is already awaitable with the previously defined GetAwaiter extension method as example, it is already awaitable with the previously defined GetAwaiter extension method, and can be used in await expression just like task. However, it cannot be used with async modifier to be async function output type just like task. To make Func&amp;lt;TResult&amp;gt; output type of async function, the following FuncAwaitable&amp;lt;TResult&amp;gt; type is defined as a wrapper of Func&amp;lt;TResult&amp;gt;. This wrapper is an awaitable type, its GetAwaiter instance method reuses previously defined FuncAwater&amp;lt;TResult&amp;gt; as its awaiter:&lt;/p&gt;
&lt;p&gt;[AsyncMethodBuilder(typeof(AsyncFuncAwaitableMethodBuilder&amp;lt;&amp;gt;))]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class FuncAwaitable&amp;lt;TResult&amp;gt;: IAwaitable&amp;lt;TResult&amp;gt;
{
private readonly Func&amp;lt;TResult&amp;gt; function;

public FuncAwaitable(Func&amp;lt;TResult&amp;gt; function) =&amp;gt; this.function = function;

public IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter() =&amp;gt;
new FuncAwaiter&amp;lt;TResult&amp;gt;(Task.Run(this.function));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This wrapper type is associated with its async method builder with System.Runtime.CompilerServices.AsyncMethodBuilderAttribute. The async method builder for FuncAwaitable&amp;lt;TResult&amp;gt; is implemented as:&lt;/p&gt;
&lt;p&gt;public class AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
private AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; taskMethodBuilder;

private TResult result;

private bool hasResult;

private bool useBuilder;

public static AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt; Create() =&amp;gt;
new AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;()
{
taskMethodBuilder = AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt;.Create()
};

public void Start&amp;lt;TStateMachine&amp;gt;(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine =&amp;gt;
this.taskMethodBuilder.Start(ref stateMachine);

public void SetStateMachine(IAsyncStateMachine stateMachine) =&amp;gt;
this.taskMethodBuilder.SetStateMachine(stateMachine);

public void SetResult(TResult result)
{
if (this.useBuilder)
{
this.taskMethodBuilder.SetResult(result);
}
else
{
this.result = result;
this.hasResult = true;
}
}

public void SetException(Exception exception) =&amp;gt;
this.taskMethodBuilder.SetException(exception);

public FuncAwaitable&amp;lt;TResult&amp;gt; Task
{
get
{
if (this.hasResult)
{
TResult result = this.result;
return new FuncAwaitable&amp;lt;TResult&amp;gt;(() =&amp;gt; result);
}

this.useBuilder = true;
Task&amp;lt;TResult&amp;gt;task = this.taskMethodBuilder.Task;
return new FuncAwaitable&amp;lt;TResult&amp;gt;(() =&amp;gt; task.Result);
}
}

public void AwaitOnCompleted&amp;lt;TAwaiter, TStateMachine&amp;gt;(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
{
this.useBuilder = true;
this.taskMethodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
}

public void AwaitUnsafeOnCompleted&amp;lt;TAwaiter, TStateMachine&amp;gt;(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
{
this.useBuilder = true;
this.taskMethodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the FuncAwaitable&amp;lt;TResult&amp;gt; type can be output type of async function, just like task:&lt;/p&gt;
&lt;p&gt;internal static async FuncAwaitable&amp;lt;T&amp;gt; AsyncFunctionWithFuncAwaitable&amp;lt;T&amp;gt;(T value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
await Task.Delay(TimeSpan.FromSeconds(1));
return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is in the same pattern as async function with task output. The only difference is, in the generated async state machine, the builder field become the specified AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;, instead of the AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; for task. And apparently, this async function can be called in the await expression since its output type FuncAwaitable&amp;lt;TResult&amp;gt; is awaitable:&lt;/p&gt;
&lt;p&gt;internal static async Task CallAsyncFunctionWithFuncAwaitable&amp;lt;T&amp;gt;(T value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
T result = await AsyncFunctionWithFuncAwaitable(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;ValueTask&amp;lt;TResult&amp;gt; and performance&lt;/h3&gt;
&lt;p&gt;With the generalized async function output type support, Microsoft also provides a System.Threading.Tasks.ValueTask&amp;lt;TResult&amp;gt; awaitable structure in the System.Threading.Tasks.Extensions NuGet package:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder&amp;lt;&amp;gt;))]
[StructLayout(LayoutKind.Auto)]
public struct ValueTask&amp;lt;TResult&amp;gt; : IEquatable&amp;lt;ValueTask&amp;lt;TResult&amp;gt;&amp;gt;
{
public ValueTask(TResult result);

public ValueTask(Task&amp;lt;TResult&amp;gt; task);

public ValueTaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();

// Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its awaiter is System.Threading.Tasks.ValueTaskAwaiter&amp;lt;TResult&amp;gt;, and its async method builder is System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder&amp;lt;TResult&amp;gt;, which are provided in the same NuGet package. So ValueTask&amp;lt;TResult&amp;gt; can be used with both await expression and async function. As a value type, it can be allocated and deallocated on stack, with better performance than reference type Task&amp;lt;TResult&amp;gt;. Also, unlike Task&amp;lt;TResult&amp;gt; as a wrapper of Func&amp;lt;TResult&amp;gt; operation, ValueTask&amp;lt;TResult&amp;gt; can be a wrapper of either Func&amp;lt;TResult&amp;gt; operation or TResult result. So ValueTask&amp;lt;TResult&amp;gt; can improve the performance for async function that may have result available before any async operation. The following example downloads data from the specified URI:&lt;/p&gt;
&lt;p&gt;private static readonly Dictionary&amp;lt;string, byte[]&amp;gt; Cache =&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new Dictionary&amp;lt;string, byte[]&amp;gt;(StringComparer.OrdinalIgnoreCase);

internal static async Task&amp;lt;byte[]&amp;gt; DownloadAsyncTask(string uri)
{
// All code compiled to async state machine. When URI is cached, async state machine is still started.
if (Cache.TryGetValue(uri, out byte[] cachedResult))
{
return cachedResult;
}
using (HttpClient httpClient = new HttpClient())
{
byte[] result = await httpClient.GetByteArrayAsync(uri);
Cache.Add(uri, result);
return result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It first checks the cache, if the data is already cached for the specified URI, then it outputs the cached data directly, no async operation is needed. However, at compile time, since the function has the async modifier, the entire function body, including the if statement, is compiled into an async state machine. At runtime, a task is always allocated on the heap and should be garbage collected, and the async state machine is always started, even when the result is available in the cache and no async operation is needed. With ValueTask&amp;lt;TResult&amp;gt;, this can be easily optimized:&lt;/p&gt;
&lt;p&gt;internal static ValueTask&amp;lt;byte[]&amp;gt; DownloadAsyncValueTask(string uri)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
// Not compiled to async state machine. When URI is cached, no async state machine is started.
return Cache.TryGetValue(uri, out byte[] cachedResult)
? new ValueTask&amp;lt;byte[]&amp;gt;(cachedResult)
: new ValueTask&amp;lt;byte[]&amp;gt;(DownloadAsync());

async Task&amp;lt;byte[]&amp;gt; DownloadAsync()
{
// Compiled to async state machine. When URI is not cached, async state machine is started.
using (HttpClient httpClient = new HttpClient())
{
byte[] result = await httpClient.GetByteArrayAsync(uri);
Cache.Add(uri, result);
return result;
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the function becomes a sync function with awaitable ValueTask&amp;lt;TResult&amp;gt; output. When the result is available in the cache, the async local function is not called, so there is no async operation or async state machine involved, and there is no task allocated on heap. The async operation is encapsulated in the async local function, which is compiled to async state machine, and is only involved when the result is not available in the cache. As a result, the performance can be improved, especially when the cache is hit frequently.&lt;/p&gt;
&lt;h2&gt;Anonymous async function&lt;/h2&gt;
&lt;p&gt;The async and await keywords can be used with the lambda expression syntax for anonymous function. Just like named async function, anonymous async function’s output type is task:&lt;/p&gt;
&lt;p&gt;internal static async Task AsyncAnonymousFunction(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Func&amp;lt;string, Task&amp;lt;string&amp;gt;&amp;gt;readAsync = async path =&amp;gt;
{
using (StreamReader reader = new StreamReader(new FileStream(
path: path, mode: FileMode.Open, access: FileAccess.Read,
share: FileShare.Read, bufferSize: 4096, useAsync: true)))
{
return await reader.ReadToEndAsync();
}
};
Func&amp;lt;string, string, Task&amp;gt;writeAsync = async (path, contents) =&amp;gt;
{
using (StreamWriter writer = new StreamWriter(new FileStream(
path: path, mode: FileMode.Create, access: FileAccess.Write,
share: FileShare.Read, bufferSize: 4096, useAsync: true)))
{
await writer.WriteAsync(contents);
}
};

string result = await readAsync(readPath);
await writeAsync(writePath, result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above async lambda expressions are compiled as methods of closure class, in the same pattern as normal sync lambda expressions.&lt;/p&gt;
&lt;p&gt;Since task can be constructed with anonymous function with any output type, it can be constructed with anonymous async function with task output too:&lt;/p&gt;
&lt;p&gt;internal static async Task ConstructTaskWithAsyncAnonymousFunction(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string readPath, string writePath)
{
Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt; task1 = new Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt;(async () =&amp;gt;
await ReadAsync(readPath));
task1.Start(); // Cold task needs to be started.
string contents = await task1.Unwrap(); // Equivalent to: string contents = await await task1;

Task&amp;lt;Task&amp;gt; task2 = new Task&amp;lt;Task&amp;gt;(async () =&amp;gt; await WriteAsync(writePath, null));
task2.Start(); // Cold task needs to be started.
await task2.Unwrap(); // Equivalent to: await await task2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The first task is constructed with anonymous async function of type () –&amp;gt; Task&amp;lt;string&amp;gt;, so the constructed task is of type Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt;. Similarly, the second task is constructed with anonymous async function of type () –&amp;gt; Task, so the constructed task is of type Task&amp;lt;Task&amp;gt;. As fore mentioned, nested task can be unwrapped and awaited.&lt;/p&gt;
&lt;p&gt;internal static async Task RunAsyncWithAutoUnwrap(string readPath, string writePath)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
Task&amp;lt;string&amp;gt; task1 = Task.Run(async () =&amp;gt; await ReadAsync(readPath)); // Automatically unwrapped.
string contents = await task1; // Hot task.

Task task2 = Task.Run(async () =&amp;gt; await WriteAsync(writePath, contents)); // Automatically unwrapped.
await task2; // Hot task.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Asynchrnous sequence: IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;In C# 8.0, an async function can return a sequence of values using the return type IAsyncEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public interface IAsyncEnumerable&amp;lt;out T&amp;gt;
{
IAsyncEnumerator&amp;lt;T&amp;gt; GetAsyncEnumerator(CancellationToken cancellationToken = default);
}

public interface IAsyncEnumerator&amp;lt;out T&amp;gt; : IAsyncDisposable
{
T Current { get; }

ValueTask&amp;lt;bool&amp;gt; MoveNextAsync();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example define a async function that generates a sequence of values by using yield statement:&lt;/p&gt;
&lt;p&gt;internal static async IAsyncEnumerable&amp;lt;string&amp;gt;DownloadAsync(IEnumerable&amp;lt;Uri&amp;gt; uris)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
using WebClient webClient = new WebClient();
foreach (Uri uri in uris)
{
string webPage = await webClient.DownloadStringTaskAsync(uri);
yield return webPage;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example consumes an async sequence by pulling the values asynchronously using async foreach statement:&lt;/p&gt;
&lt;p&gt;internal static async void PrintDownloadAsync(IEnumerable&amp;lt;Uri&amp;gt; uris)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
IAsyncEnumerable&amp;lt;string&amp;gt; webPages = DownloadAsync(uris);
await foreach (string webPage in webPages)
{
Trace.WriteLine(webPage);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In above 2 async functions, the code are both compiled to a state macine similar to async functions returning a task.&lt;/p&gt;
&lt;h2&gt;async using declaration: IAsyncDispose&lt;/h2&gt;
&lt;p&gt;In C# 8.0, an instance can be decared with async using keywords, if its type implements System.IAsyncDispose interface:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For example, FileStream type implements IAsyncDispose:&lt;/p&gt;
&lt;p&gt;internalstaticasyncvoid AsyncUsing(string file)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
awaitusing FileStream fileStream = File.OpenRead(file);
Trace.WriteLine(fileStream.Length);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The code in the above async function is also compiled to a state machine.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;C# supports async function as a simplified asynchronous programming model. In C#, async operation is represented by Task or Task&amp;lt;TResult&amp;gt;. A task can be async function output type, and can be used in await expression. Besides task, any type following the awaitable-awaiter pattern can be used in await expression. Async function is compiled to async state machine. It can capture the caller’s runtime context, and execute the continuation code with the captured context. C# generalizes async function output type with async method builder support, and a ValueTask&amp;lt;TResult&amp;gt; type is provided to improve async function performance. C# also support async local function and async anonymous function.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ via C#</title><link>https://dixin.github.io/posts/fp-csharp/</link><guid isPermaLink="true">https://dixin.github.io/posts/fp-csharp/</guid><description>!</description><pubDate>Sun, 02 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/72436fc4c617_10FA4/ezgif-1-93576e9d87_3.jpg&quot; alt=&quot;ezgif-1-93576e9d87&quot; title=&quot;ezgif-1-93576e9d87&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#acclaim&quot;&gt;Acclaim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#contentsataglance&quot;&gt;Contents at a Glance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#contents&quot;&gt;Table of Contents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a book on functional programming and LINQ programming via C# language. It discusses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functional programming via C# in-depth&lt;/li&gt;
&lt;li&gt;Use functional LINQ to work with local data and cloud data&lt;/li&gt;
&lt;li&gt;The underlying mathematics theories of functional programming and LINQ, including Lambda Calculus and Category Theory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Acclaim&lt;/h3&gt;
&lt;p&gt;Microsoft:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“An excellent book for those of us who need to get in-depth understanding on LINQ and functional programming with latest C# language. The author made sure this book includes the latest and cross-platform knowledge for the language, the framework, as well as the underlying mathematical theories.” &lt;strong&gt;Hongfei Guo Partner Group Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This book explains practical and in-depth material clearly, concisely and accurately to the areas of the C# language, functional programming, and LINQ on .NET Framework and .NET Core. This is a great book for anyone wanting to understand the whys and hows behind these important technologies.” &lt;strong&gt;Samer Boshra Principal Software Development Engineer at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book for developers who want to go functional programming. It&apos;s one-stop shopping for serious developers who have to get up to speed with LINQ and functional programming quickly and in-depth. I&apos;ll keep this book on my desk not on my bookshelf.” &lt;strong&gt;Roshan Kommusetty Principal Software Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book for C# developers, it covers both basic C# programming concepts for the beginners new to the .NET world, and C# advanced constructs for experienced .NET programmers. The book is up to date, talks C# 7.0 new language features and demonstrates how you can use them for functional programming. Thanks for the awesome work!” &lt;strong&gt;Mark Zhou Principal Software Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“I like the way the author presented the detailed knowledge with a lot of examples. As a data scientist with statistics background in a number of industries, I can pick up C# programming and LINQ quickly when I followed the book. The book was concise and easy to read. It was a pleasant experience for me to spend my time emerging myself in the book in the sunshine weekday afternoon.” &lt;strong&gt;Xue Liu Senior Data Scientist at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“Functional Programming and LINQ in C# language, have been fully and clearly unraveled in this book, with many practical examples. The author has not saved any effort to go beyond scratching the surface of C# language and has successfully explained the magic behind the scene. This book is a must-have for anyone who wants to understand functional programming using C#.” &lt;strong&gt;Jie Mei Data &amp;amp; Applied Scientist at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Academy and more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“This book provides comprehensive and in-depth information about the C# functional programming and LINQ technologies to application developers on both .NET Framework and .NET Core. The detailed text and wealth of examples will give a developer a clear and solid understanding of C# language, functional programming and using LINQ to work with different data domains.” &lt;strong&gt;Dong Si Assistant Professor, Department of Computer Science, University of Washington, Bothell&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This book offers a comprehensive, in-depth, yet easy-to-understand tutorial to functional C# programming and LINQ. Filled with detailed explanations and real-world examples, this book is highly valuable for beginners and experienced developers alike.” &lt;strong&gt;Shuang Zhao Assistant Professor, Department of Computer Science, University of California, Irvine&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This excellent book is an in-depth and also readable exploration of C# functional programming and LINQ programming. It covers .NET Framework and .NET Core in great detail.” &lt;strong&gt;Yang Sha Engineering Manager at Google&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“Great book! It takes a hands-on approach to LINQ and functional programming in an easy to understand format. I would highly recommend this book to developers looking to develop expertise in C#, functional programming, and LINQ.” &lt;strong&gt;Himanshu Lal Software Engineering Manager at Facebook&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book that combines practical examples with in-depth analysis of LINQ and functional programming in C#. Dixin leverages his expertise in .NET to provide a well written tutorial on the effective use of LINQ and an overview of the theoretical principles behind it. A must read for anyone working on these technologies!” &lt;strong&gt;Dimitrios Soulios Director at Goldman Sachs&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Contents at a Glance&lt;/h3&gt;
&lt;p&gt;The contents are organized as the following chapters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1 Code&lt;/strong&gt; - covers functional programming via C#, and fundamentals of LINQ.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 1 Functional programming and LINQ paradigm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;What is LINQ, how LINQ uses language to work with many different data domains.&lt;/li&gt;
&lt;li&gt;Programming paradigm, imperative vs. declarative programming, object-oriented vs. functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 2 Functional programming in depth&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C# fundamentals for beginners.&lt;/li&gt;
&lt;li&gt;Aspects of functional programming via C#, including function type, named/anonymous/local function, closure, lambda, higher-order function, currying, partial application, first class function, function composition, query expression, covariance/contravariance, immutability, tuple, purity, async function, pattern matching, etc., including how C# is processed at compile time and runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 2 Data&lt;/strong&gt; - covers how to use functional LINQ to work with different data domains in the real world, and how LINQ works internally.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 3 LINQ to Objects&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use functional LINQ queries to work with objects, covering all LINQ and Ix.&lt;/li&gt;
&lt;li&gt;How the LINQ to Objects query methods are implemented, how to implement useful custom LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 4 LINQ to XML&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to modeling XML data, and use functional LINQ queries to work with XML data.&lt;/li&gt;
&lt;li&gt;How to use the other LINQ to XML APIs to manipulate XML data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 5 Parallel LINQ&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use parallelized functional LINQ queries to work with objects.&lt;/li&gt;
&lt;li&gt;Performance analysis for parallel/sequential LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 6 Entity Framework/Core and LINQ to Entities&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to model database with object-relational mapping, and use functional LINQ queries to work with relational data in database.&lt;/li&gt;
&lt;li&gt;How the C# LINQ to Entities queries are implemented to work with database.&lt;/li&gt;
&lt;li&gt;How to change data in database, and handle concurrent conflicts.&lt;/li&gt;
&lt;li&gt;Performance tips and asynchrony.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 3 Theories&lt;/strong&gt; - demystifies the abstract mathematics theories, which are the rationale and foundations of LINQ and functional programming.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 7 Lambda Calculus via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of lambda calculus, bound and free variables, reduction (α-conversion, β-reduction, η-conversion), etc.&lt;/li&gt;
&lt;li&gt;How to use lambda functions to represent values, data structures and computation, including Church Boolean, Church numbers, Church pair, Church list, and their operations.&lt;/li&gt;
&lt;li&gt;Combinators and combinatory logic, including SKI combinator calculus, fixed point combinator for function recursion, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 8 Category Theory via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of category theory, including category, object, morphism, monoid, functor, natural transformation, applicative functor, monad, and their laws.&lt;/li&gt;
&lt;li&gt;How these concepts are applied in functional programming and LINQ.&lt;/li&gt;
&lt;li&gt;How to manage I/O, state, exception handling, shared environment, logging, and continuation, etc., in functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial delivers highly reusable knowledge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It covers C# language in depth, which can be generally applied in any programming paradigms besides functional programming.&lt;/li&gt;
&lt;li&gt;It is a cross platform tutorial, covering both .NET Framework for Windows and .NET Core for Windows, Mac, Linux.&lt;/li&gt;
&lt;li&gt;It demonstrates both usage and implementation of LINQ for mainstream data domains, which also enables developer to use the LINQ technologies for other data domains, or build custom LINQ APIs for specific data scenarios.&lt;/li&gt;
&lt;li&gt;It also demystifies the abstract mathematics knowledge for functional programming, which applies to general functional programming, so it greatly helps developers understanding any other functional languages too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a fun of functional programming, LINQ, C#, and .NET technologies, hope this helps.&lt;/p&gt;
&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;p&gt;All code examples are available on GitHub: https://github.com/Dixin/CodeSnippets.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Introducing%20LINQ&quot;&gt;Functional programming and LINQ paradigm&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-via-csharp-introduction&quot;&gt;Cross platform C# and .NET&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Introducing cross platform .NET, C# and LINQ
&lt;ul&gt;
&lt;li&gt;.NET Framework, C#, and LINQ&lt;/li&gt;
&lt;li&gt;.NET Core, UWP, Mono, Xamarin and Unity&lt;/li&gt;
&lt;li&gt;.NET Standard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Introducing this book
&lt;ul&gt;
&lt;li&gt;Book structure&lt;/li&gt;
&lt;li&gt;Code examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Start coding
&lt;ul&gt;
&lt;li&gt;Start coding with Visual Studio (Windows)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio Code (Windows, macOS and Linux)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio for Mac (macOS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-3-waht-is-functional-programming&quot;&gt;Programming paradigms and functional programming&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Programming paradigms&lt;/li&gt;
&lt;li&gt;Imperative programming vs. declarative programming&lt;/li&gt;
&lt;li&gt;Object-oriented programming vs. functional programming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-2-what-is-linq&quot;&gt;LINQ to data sources&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One language for different data domains
&lt;ul&gt;
&lt;li&gt;LINQ to Objects&lt;/li&gt;
&lt;li&gt;Parallel LINQ&lt;/li&gt;
&lt;li&gt;LINQ to XML&lt;/li&gt;
&lt;li&gt;LINQ to DataSets&lt;/li&gt;
&lt;li&gt;LINQ to Entities&lt;/li&gt;
&lt;li&gt;LINQ to SQL&lt;/li&gt;
&lt;li&gt;LINQ to NoSQL (LINQ to CosmosDB)&lt;/li&gt;
&lt;li&gt;LINQ to JSON&lt;/li&gt;
&lt;li&gt;LINQ to Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequential query vs. parallel query&lt;/li&gt;
&lt;li&gt;Local query vs. remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;Functional programming in depth&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;C# language basics&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Types and members
&lt;ul&gt;
&lt;li&gt;Types and members&lt;/li&gt;
&lt;li&gt;Built-in types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reference type vs. value type
&lt;ul&gt;
&lt;li&gt;ref local variable and immutable ref local variable&lt;/li&gt;
&lt;li&gt;Array and stack-allocated array&lt;/li&gt;
&lt;li&gt;Default value&lt;/li&gt;
&lt;li&gt;ref structure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static class&lt;/li&gt;
&lt;li&gt;Partial type&lt;/li&gt;
&lt;li&gt;Interface and implementation
&lt;ul&gt;
&lt;li&gt;IDisposable interface and using declaration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generic type
&lt;ul&gt;
&lt;li&gt;Type parameter&lt;/li&gt;
&lt;li&gt;Type parameter constraints&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nullable value type&lt;/li&gt;
&lt;li&gt;Auto property&lt;/li&gt;
&lt;li&gt;Property initializer&lt;/li&gt;
&lt;li&gt;Object initializer&lt;/li&gt;
&lt;li&gt;Collection initializer&lt;/li&gt;
&lt;li&gt;Index initializer&lt;/li&gt;
&lt;li&gt;Null coalescing operator&lt;/li&gt;
&lt;li&gt;Null conditional operator&lt;/li&gt;
&lt;li&gt;throw expression&lt;/li&gt;
&lt;li&gt;Exception filter&lt;/li&gt;
&lt;li&gt;String interpolation&lt;/li&gt;
&lt;li&gt;nameof operator&lt;/li&gt;
&lt;li&gt;Digit separator and leading underscore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-type-and-delegate&quot;&gt;Named function and function polymorphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Constructor, static constructor and finalizer&lt;/li&gt;
&lt;li&gt;Static method and instance method&lt;/li&gt;
&lt;li&gt;Extension method&lt;/li&gt;
&lt;li&gt;More named functions&lt;/li&gt;
&lt;li&gt;Function polymorphisms
&lt;ul&gt;
&lt;li&gt;Ad hoc polymorphism: method overload&lt;/li&gt;
&lt;li&gt;Parametric polymorphism: generic method
&lt;ul&gt;
&lt;li&gt;Type argument inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static import&lt;/li&gt;
&lt;li&gt;Partial method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;Local function and closure&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Local function&lt;/li&gt;
&lt;li&gt;Closure
&lt;ul&gt;
&lt;li&gt;Outer variable&lt;/li&gt;
&lt;li&gt;Implicit reference&lt;/li&gt;
&lt;li&gt;Static local function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-parameter-and-return-value&quot;&gt;Function input and output&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Input by copy vs. input by alias (ref parameter)
&lt;ul&gt;
&lt;li&gt;Input by immutable alias (in parameter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Output parameter (out parameter) and out variable
&lt;ul&gt;
&lt;li&gt;Discarding out variable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Parameter array&lt;/li&gt;
&lt;li&gt;Positional argument vs. named argument&lt;/li&gt;
&lt;li&gt;Required parameter vs. optional parameter&lt;/li&gt;
&lt;li&gt;Caller information parameter&lt;/li&gt;
&lt;li&gt;Output by copy vs. output by alias
&lt;ul&gt;
&lt;li&gt;Output by immutable alias&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;Delegate: Function type, instance, and group&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Delegate type as function type
&lt;ul&gt;
&lt;li&gt;Function type&lt;/li&gt;
&lt;li&gt;Generic delegate type&lt;/li&gt;
&lt;li&gt;Unified built-in delegate types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delegate instance as function instance&lt;/li&gt;
&lt;li&gt;Delegate instance as function group
&lt;ul&gt;
&lt;li&gt;Event and event handler&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-anonymous-function-and-lambda-expression&quot;&gt;Anonymous function and lambda expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Anonymous method&lt;/li&gt;
&lt;li&gt;Lambda expression as anonymous function
&lt;ul&gt;
&lt;li&gt;IIFE (Immediately-invoked function expression)&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Expression bodied function member&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-as-data-and-expression-tree&quot;&gt;Expression tree: Function as data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lambda expression as expression tree
&lt;ul&gt;
&lt;li&gt;Metaprogramming: function as abstract syntax tree&lt;/li&gt;
&lt;li&gt;.NET expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Compile expression tree at runtime
&lt;ul&gt;
&lt;li&gt;Traverse expression tree&lt;/li&gt;
&lt;li&gt;Expression tree to CIL at runtime&lt;/li&gt;
&lt;li&gt;Expression tree to executable function at runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Expression tree and LINQ remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-higher-order-function-currying-and-first-class-function&quot;&gt;Higher-order function, currying and first class function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First order function vs. higher-order function
&lt;ul&gt;
&lt;li&gt;Convert first-order function to higher-order function&lt;/li&gt;
&lt;li&gt;Lambda operator =&amp;gt; associativity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Curry function
&lt;ul&gt;
&lt;li&gt;Uncurry function&lt;/li&gt;
&lt;li&gt;Partial applying function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;First-class function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-composition-and-method-chaining&quot;&gt;Function composition and chaining&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Forward composition vs. backward composition&lt;/li&gt;
&lt;li&gt;Forward piping&lt;/li&gt;
&lt;li&gt;Method chaining and fluent interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-query-expression&quot;&gt;LINQ query expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Syntax and compilation&lt;/li&gt;
&lt;li&gt;Query expression pattern&lt;/li&gt;
&lt;li&gt;LINQ query expression
&lt;ul&gt;
&lt;li&gt;Forward piping with LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query expression vs. query method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-covariance-and-contravariance&quot;&gt;Covariance and contravariance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Subtyping and type polymorphism&lt;/li&gt;
&lt;li&gt;Variances of non-generic function type&lt;/li&gt;
&lt;li&gt;Variances of generic function type&lt;/li&gt;
&lt;li&gt;Variances of generic interface&lt;/li&gt;
&lt;li&gt;Variances of generic higher-order function type&lt;/li&gt;
&lt;li&gt;Covariance of array&lt;/li&gt;
&lt;li&gt;Variances in .NET and LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-immutability-anonymous-type-and-tuple&quot;&gt;Immutability, anonymous type and tuple&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Immutable value
&lt;ul&gt;
&lt;li&gt;Constant local&lt;/li&gt;
&lt;li&gt;Enumeration&lt;/li&gt;
&lt;li&gt;using declaration and foreach statement&lt;/li&gt;
&lt;li&gt;Immutable alias (immutable ref local variable)&lt;/li&gt;
&lt;li&gt;Function’s immutable input and immutable output&lt;/li&gt;
&lt;li&gt;Range variable in LINQ query expression&lt;/li&gt;
&lt;li&gt;this reference for class&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable state (immutable type)
&lt;ul&gt;
&lt;li&gt;Constant field&lt;/li&gt;
&lt;li&gt;Immutable class with readonly instance field&lt;/li&gt;
&lt;li&gt;Immutable structure (readonly structure)&lt;/li&gt;
&lt;li&gt;Immutable anonymous type
&lt;ul&gt;
&lt;li&gt;Local variable type inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable tuple vs. mutable tuple
&lt;ul&gt;
&lt;li&gt;Construction, element name and element inference&lt;/li&gt;
&lt;li&gt;Deconstruction&lt;/li&gt;
&lt;li&gt;Tuple assignment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable collection vs. readonly collection&lt;/li&gt;
&lt;li&gt;Shallow immutability vs. deep immutability&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pure-function&quot;&gt;Pure function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pure function vs. impure function
&lt;ul&gt;
&lt;li&gt;Referential transparency and side effect free&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Purity in .NET&lt;/li&gt;
&lt;li&gt;Purity in LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-asynchronous-function&quot;&gt;Asynchronous function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Task, Task&amp;lt;TResult&amp;gt; and asynchrony&lt;/li&gt;
&lt;li&gt;Named async function&lt;/li&gt;
&lt;li&gt;Awaitable-awaiter pattern&lt;/li&gt;
&lt;li&gt;Async state machine&lt;/li&gt;
&lt;li&gt;Runtime context capture&lt;/li&gt;
&lt;li&gt;Generalized async return type and async method builder
&lt;ul&gt;
&lt;li&gt;ValueTask&amp;lt;TResult&amp;gt; and performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Anonymous async function&lt;/li&gt;
&lt;li&gt;Asynchronous sequence: IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;async using declaration: IAsyncDispose&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pattern-matching&quot;&gt;Pattern matching&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Is expression&lt;/li&gt;
&lt;li&gt;switch statement and switch expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects: Querying objects in memory&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-local-sequential-query&quot;&gt;Local sequential LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Iteration pattern and foreach statement&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;foreach loop vs. for loop&lt;/li&gt;
&lt;li&gt;Non-generic sequence vs. generic sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ to Objects queryable types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-operators-and-query-expressions&quot;&gt;LINQ to Objects standard queries and query expressions&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType, where&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany, from, let, select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy, group, by, into&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, join, on, equals&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, join, into, on, equals&lt;/li&gt;
&lt;li&gt;Cross join: SelectMany, Join, from select, join, on, equals&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse, orderby, ascending, descending, into&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queries in other languages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-generator&quot;&gt;Generator&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Implementing iterator pattern&lt;/li&gt;
&lt;li&gt;Generating sequence and iterator&lt;/li&gt;
&lt;li&gt;Yield statement and generator&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation&quot;&gt;Deferred execution, lazy evaluation and eager Evaluation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Immediate execution vs. Deferred execution
&lt;ul&gt;
&lt;li&gt;Cold IEnumerable&amp;lt;T&amp;gt; vs. hot IEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-implementation&quot;&gt;LINQ to Objects internals: Standard queries implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Argument check and deferred execution&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join: SelectMany, Join, GroupJoin&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-interactive-extensions-ix&quot;&gt;Advanced queries in Microsoft Interactive Extensions (Ix)&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: Defer, Create, Return, Repeat&lt;/li&gt;
&lt;li&gt;Filtering: IgnoreElements, DistinctUntilChanged&lt;/li&gt;
&lt;li&gt;Mapping: SelectMany, Scan, Expand&lt;/li&gt;
&lt;li&gt;Concatenation: Concat, StartWith&lt;/li&gt;
&lt;li&gt;Set: Distinct&lt;/li&gt;
&lt;li&gt;Partitioning: TakeLast, SkipLast&lt;/li&gt;
&lt;li&gt;Conversion: Hide&lt;/li&gt;
&lt;li&gt;Buffering: Buffer, Share, Publish, Memoize&lt;/li&gt;
&lt;li&gt;Exception: Throw, Catch, Finally, OnErrorResumeNext, Retry&lt;/li&gt;
&lt;li&gt;Imperative: If, Case, Using, While, DoWhile, Generate, For&lt;/li&gt;
&lt;li&gt;Iteration: Do&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Aggregation: Min, Max, MinBy, MaxBy&lt;/li&gt;
&lt;li&gt;Quantifiers: isEmpty&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Void queries
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-custom-query-methods&quot;&gt;Building custom queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries (deferred execution)
&lt;ul&gt;
&lt;li&gt;Generation: Create, RandomInt32, RandomDouble, FromValue, FromValues, EmptyIfNull&lt;/li&gt;
&lt;li&gt;Filtering: Timeout&lt;/li&gt;
&lt;li&gt;Concatenation: Join, Append, Prepend, AppendTo, PrependTo&lt;/li&gt;
&lt;li&gt;Partitioning: Subsequence&lt;/li&gt;
&lt;li&gt;Exception: Catch, Retry&lt;/li&gt;
&lt;li&gt;Comparison: OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;List: Insert, Remove, RemoveAll, RemoveAt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Comparison: ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;List: IndexOf, LastIndexOf&lt;/li&gt;
&lt;li&gt;Aggregation: PercentileExclusive, PercentileInclusive, Percentile&lt;/li&gt;
&lt;li&gt;Quantifiers: IsNullOrEmpty, IsNotNullOrEmpty&lt;/li&gt;
&lt;li&gt;Comparison: Contains, SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Void queries
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML: Querying XML&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-1-modeling-xml&quot;&gt;Modeling XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Imperative vs. declarative paradigm&lt;/li&gt;
&lt;li&gt;Types, conversions and operators&lt;/li&gt;
&lt;li&gt;Read and deserialize XML&lt;/li&gt;
&lt;li&gt;Serialize and write XML&lt;/li&gt;
&lt;li&gt;Deferred construction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-2-query-methods&quot;&gt;LINQ to XML standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;li&gt;Comparison&lt;/li&gt;
&lt;li&gt;More useful queries&lt;/li&gt;
&lt;li&gt;XPath
&lt;ul&gt;
&lt;li&gt;Generate XPath expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-3-manipulating-xml&quot;&gt;Manipulating XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Clone&lt;/li&gt;
&lt;li&gt;Adding, deleting, replacing, updating, and events&lt;/li&gt;
&lt;li&gt;Annotation&lt;/li&gt;
&lt;li&gt;Validating XML with XSD&lt;/li&gt;
&lt;li&gt;Transforming XML with XSL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ: Querying objects in parallel&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-1-local-parallel-query-and-visualization&quot;&gt;Parallel LINQ query and visualization&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Parallel query vs. sequential query&lt;/li&gt;
&lt;li&gt;Parallel query execution&lt;/li&gt;
&lt;li&gt;Visualizing parallel query execution
&lt;ul&gt;
&lt;li&gt;Using Concurrency Visualizer&lt;/li&gt;
&lt;li&gt;Visualizing sequential and parallel LINQ queries&lt;/li&gt;
&lt;li&gt;Visualizing chaining query methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-2-partitioning&quot;&gt;Parallel LINQ internals: data partitioning&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Partitioning and load balancing
&lt;ul&gt;
&lt;li&gt;Range partitioning&lt;/li&gt;
&lt;li&gt;Chunk partitioning&lt;/li&gt;
&lt;li&gt;Hash partitioning&lt;/li&gt;
&lt;li&gt;Stripped partitioning&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implement custom partitioner
&lt;ul&gt;
&lt;li&gt;Static partitioner&lt;/li&gt;
&lt;li&gt;Dynamic partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-3-query-methods&quot;&gt;Parallel LINQ standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Query settings
&lt;ul&gt;
&lt;li&gt;Cancellation&lt;/li&gt;
&lt;li&gt;Degree of parallelism&lt;/li&gt;
&lt;li&gt;Execution mode&lt;/li&gt;
&lt;li&gt;Merge the values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ordering
&lt;ul&gt;
&lt;li&gt;Preserving the order&lt;/li&gt;
&lt;li&gt;Order and correctness&lt;/li&gt;
&lt;li&gt;Orderable partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregation
&lt;ul&gt;
&lt;li&gt;Commutativity, associativity and correctness&lt;/li&gt;
&lt;li&gt;Partitioning and merging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-4-performance&quot;&gt;Parallel query performance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequential query vs. parallel query&lt;/li&gt;
&lt;li&gt;CPU bound operation vs. IO bound operation&lt;/li&gt;
&lt;li&gt;Factors to impact performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework/Core and LINQ to Entities: Querying relational data&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-1-remote-query&quot;&gt;Remote LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Entity Framework and Entity Framework Core&lt;/li&gt;
&lt;li&gt;SQL database&lt;/li&gt;
&lt;li&gt;Remote query vs. local query&lt;/li&gt;
&lt;li&gt;Function vs. expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&quot;&gt;Modeling database with object-relational mapping&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data types&lt;/li&gt;
&lt;li&gt;Database
&lt;ul&gt;
&lt;li&gt;Connection resiliency and execution retry strategy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Relationships
&lt;ul&gt;
&lt;li&gt;One-to-one&lt;/li&gt;
&lt;li&gt;One-to-many&lt;/li&gt;
&lt;li&gt;Many-to-many&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Views&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&quot;&gt;Logging and tracing LINQ to Entities queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Application side logging&lt;/li&gt;
&lt;li&gt;Database side tracing with Extended Events&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-4-query-methods&quot;&gt;LINQ to Entities standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, GroupJoin, Select&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, Select, SelectMany&lt;/li&gt;
&lt;li&gt;Cross join and self join: SelectMany, Join&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsQueryable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&quot;&gt;LINQ to Entities internals: Query translation implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Code to LINQ expression tree
&lt;ul&gt;
&lt;li&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/li&gt;
&lt;li&gt;Standard remote queries&lt;/li&gt;
&lt;li&gt;Building LINQ to Entities abstract syntax tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;.NET expression tree to database expression tree
&lt;ul&gt;
&lt;li&gt;Database query abstract syntax tree&lt;/li&gt;
&lt;li&gt;Compiling LINQ expressions to database expressions&lt;/li&gt;
&lt;li&gt;Compiling LINQ queries&lt;/li&gt;
&lt;li&gt;Compiling .NET API calls&lt;/li&gt;
&lt;li&gt;Remote API call vs. local API call&lt;/li&gt;
&lt;li&gt;Compile database functions and operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Database expression tree to database query language
&lt;ul&gt;
&lt;li&gt;SQL generator and SQL command&lt;/li&gt;
&lt;li&gt;Generating SQL from database expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading&quot;&gt;Loading query data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deferred execution
&lt;ul&gt;
&lt;li&gt;Iterator pattern&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Explicit loading&lt;/li&gt;
&lt;li&gt;Eager loading&lt;/li&gt;
&lt;li&gt;Lazy loading
&lt;ul&gt;
&lt;li&gt;The N + 1 problem&lt;/li&gt;
&lt;li&gt;Disabling lazy loading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&quot;&gt;Manipulating relational data: Data change and transaction&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repository pattern and unit of work pattern&lt;/li&gt;
&lt;li&gt;Tracking entities and changes
&lt;ul&gt;
&lt;li&gt;Tracking entities&lt;/li&gt;
&lt;li&gt;Tracking entity changes and property changes&lt;/li&gt;
&lt;li&gt;Tracking relationship changes&lt;/li&gt;
&lt;li&gt;Enabling and disabling tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Change data
&lt;ul&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Delete&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Transaction
&lt;ul&gt;
&lt;li&gt;Transaction with connection resiliency and execution strategy&lt;/li&gt;
&lt;li&gt;EF Core transaction&lt;/li&gt;
&lt;li&gt;ADO.NET transaction&lt;/li&gt;
&lt;li&gt;Transaction scope&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&quot;&gt;Resolving optimistic concurrency&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Detecting concurrent conflicts&lt;/li&gt;
&lt;li&gt;Resolving concurrent conflicts
&lt;ul&gt;
&lt;li&gt;Retaining database values (database wins)&lt;/li&gt;
&lt;li&gt;Overwriting database values (client wins)&lt;/li&gt;
&lt;li&gt;Merging with database values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Saving changes with concurrent conflict handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C#: The foundation of all functional programming&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-1-fundamentals&quot;&gt;Basics&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Expression
&lt;ul&gt;
&lt;li&gt;Bound variable vs. free variable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reductions
&lt;ul&gt;
&lt;li&gt;α-conversion (alpha-conversion)&lt;/li&gt;
&lt;li&gt;β-reduction (beta-reduction)&lt;/li&gt;
&lt;li&gt;η-conversion (eta-conversion)&lt;/li&gt;
&lt;li&gt;Normal order&lt;/li&gt;
&lt;li&gt;Applicative order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Function composition
&lt;ul&gt;
&lt;li&gt;Associativity&lt;/li&gt;
&lt;li&gt;Unit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-2-boolean-and-logic&quot;&gt;Church encoding: Function as boolean and logic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church encoding&lt;/li&gt;
&lt;li&gt;Church Boolean&lt;/li&gt;
&lt;li&gt;Logical operators&lt;/li&gt;
&lt;li&gt;Conversion between Church Boolean and System.Boolean&lt;/li&gt;
&lt;li&gt;If&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;Church encoding: Function as numeral, arithmetic and predicate&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church numerals&lt;/li&gt;
&lt;li&gt;Increase and decrease&lt;/li&gt;
&lt;li&gt;Arithmetic operators&lt;/li&gt;
&lt;li&gt;Predicate and relational operators
&lt;ul&gt;
&lt;li&gt;Attempt of recursion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conversion between Church numeral and System.UInt32&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&quot;&gt;Church encoding: Function as tuple and signed numeral&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church pair (2-tuple)
&lt;ul&gt;
&lt;li&gt;Tuple operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;N-tuple&lt;/li&gt;
&lt;li&gt;Signed numeral
&lt;ul&gt;
&lt;li&gt;Arithmetic operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-5-list&quot;&gt;Church encoding: Function as list&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tuple as list node
&lt;ul&gt;
&lt;li&gt;List operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregation function as list node
&lt;ul&gt;
&lt;li&gt;List operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Model everything&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-6-combinatory-logic&quot;&gt;Combinatory logic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Combinator&lt;/li&gt;
&lt;li&gt;SKI combinator calculus
&lt;ul&gt;
&lt;li&gt;SKI compiler: compile lambda calculus expression to SKI calculus combinator&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Iota combinator calculus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion&quot;&gt;Fixed point combinator and recursion&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Normal order fixed point combinator (Y combinator) and recursion&lt;/li&gt;
&lt;li&gt;Applicative order fixed point combinator (Z combinator) and recursion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-24-undecidability-of-equivalence&quot;&gt;Undecidability of equivalence&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Halting problem&lt;/li&gt;
&lt;li&gt;Equivalence problem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C#: The essentials and design of LINQ&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-1-fundamentals&quot;&gt;Basics: Category and morphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Category and category laws&lt;/li&gt;
&lt;li&gt;DotNet category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-2-monoid&quot;&gt;Monoid&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoid and monoid laws&lt;/li&gt;
&lt;li&gt;Monoid as category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;Functor and LINQ to Functors&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functor and functor laws
&lt;ul&gt;
&lt;li&gt;Endofunctor&lt;/li&gt;
&lt;li&gt;Type constructor and higher-kinded type&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ to Functors
&lt;ul&gt;
&lt;li&gt;Built-in IEnumerable&amp;lt;&amp;gt; functor&lt;/li&gt;
&lt;li&gt;Functor pattern of LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;More LINQ to Functors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-4-natural-transformation&quot;&gt;Natural transformation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Natural transformation and naturality&lt;/li&gt;
&lt;li&gt;Functor Category
&lt;ul&gt;
&lt;li&gt;Endofunctor category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-5-bifunctor&quot;&gt;Bifunctor&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bifunctor&lt;/li&gt;
&lt;li&gt;Monoidal category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;Monoidal functor and applicative functor&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoidal functor
&lt;ul&gt;
&lt;li&gt;IEnumeable&amp;lt;&amp;gt; monoidal functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Applicative functor
&lt;ul&gt;
&lt;li&gt;IEnumeable&amp;lt;&amp;gt; applicative functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monoidal functor vs. applicative functor&lt;/li&gt;
&lt;li&gt;More Monoidal functors and applicative functors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;Monad and LINQ to Monads&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monad&lt;/li&gt;
&lt;li&gt;LINQ to Monads and monad laws
&lt;ul&gt;
&lt;li&gt;Built-in IEnumerable&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Monad laws and Kleisli composition&lt;/li&gt;
&lt;li&gt;Kleisli category&lt;/li&gt;
&lt;li&gt;Monad pattern of LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monad vs. monoidal/applicative functor&lt;/li&gt;
&lt;li&gt;More LINQ to Monads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;Advanced LINQ to Monads&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IO monad&lt;/li&gt;
&lt;li&gt;State monad&lt;/li&gt;
&lt;li&gt;Try monad&lt;/li&gt;
&lt;li&gt;Reader monad&lt;/li&gt;
&lt;li&gt;Writer monad&lt;/li&gt;
&lt;li&gt;Continuation monad&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Understanding (all) JavaScript module formats and tools</title><link>https://dixin.github.io/posts/understanding-all-javascript-module-formats-and-tools/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-all-javascript-module-formats-and-tools/</guid><description>When you build an application with JavaScript, you always want to modularize your code. However, JavaScript language was initially invented for simple form manipulation, with no built-in features like module or namespace. In years, tons of technologies are invented to modularize JavaScript. This article discusses all mainstream terms, patterns, libraries, syntax, and tools for JavaScript modules.</description><pubDate>Sun, 09 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When you build an application with JavaScript, you always want to modularize your code. However, JavaScript language was initially invented for simple form manipulation, with no built-in features like module or namespace. In years, tons of technologies are invented to modularize JavaScript. This article discusses all mainstream terms, patterns, libraries, syntax, and tools for JavaScript modules.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#iife-module-javascript-module-pattern&quot;&gt;IIFE module: JavaScript module pattern&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#iife-immediately-invoked-function-expression&quot;&gt;IIFE: Immediately invoked function expression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#import-mixins&quot;&gt;Import mixins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#revealing-module-javascript-revealing-module-pattern&quot;&gt;Revealing module: JavaScript revealing module pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#cjs-module-commonjs-module-or-nodejs-module&quot;&gt;CJS module: CommonJS module, or Node.js module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#amd-module-asynchronous-module-definition-or-requirejs-module&quot;&gt;AMD module: Asynchronous Module Definition, or RequireJS module&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#dynamic-loading&quot;&gt;Dynamic loading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#amd-module-from-commonjs-module&quot;&gt;AMD module from CommonJS module&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#umd-module-universal-module-definition-or-umdjs-module&quot;&gt;UMD module: Universal Module Definition, or UmdJS module&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#umd-for-both-amd-requirejs-and-native-browser&quot;&gt;UMD for both AMD (RequireJS) and native browser&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#umd-for-both-amd-requirejs-and-commonjs-nodejs&quot;&gt;UMD for both AMD (RequireJS) and CommonJS (Node.js)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#es-module-ecmascript-2015-or-es6-module&quot;&gt;ES module: ECMAScript 2015, or ES6 module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#es-dynamic-module-ecmascript-2020-or-es11-dynamic-module&quot;&gt;ES dynamic module: ECMAScript 2020, or ES11 dynamic module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#system-module-systemjs-module&quot;&gt;System module: SystemJS module&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#dynamic-module-loading&quot;&gt;Dynamic module loading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#webpack-module-bundle-from-cjs-amd-es-modules&quot;&gt;Webpack module: bundle from CJS, AMD, ES modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#babel-module-transpile-from-es-module&quot;&gt;Babel module: transpile from ES module&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#babel-with-systemjs&quot;&gt;Babel with SystemJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#typescript-module-transpile-to-cjs-amd-es-system-modules&quot;&gt;TypeScript module: Transpile to CJS, AMD, ES, System modules&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#internal-module-and-namespace&quot;&gt;Internal module and namespace&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;IIFE module: JavaScript module pattern&lt;/h2&gt;
&lt;p&gt;In the browser, defining a JavaScript variable is defining a global variable, which causes pollution across all JavaScript files loaded by the current web page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define global variables.
let count = 0;
const increase = () =&amp;gt; ++count;
const reset = () =&amp;gt; {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};

// Use global variables.
increase();
reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To avoid global pollution, an anonymous function can be used to wrap the code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(() =&amp;gt; {
    let count = 0;
    // ...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, there is no longer any global variable. However, defining a function does not execute the code inside the function.&lt;/p&gt;
&lt;h3&gt;IIFE: Immediately invoked function expression&lt;/h3&gt;
&lt;p&gt;To execute the code inside a function &lt;code&gt;f&lt;/code&gt;, the syntax is function call &lt;code&gt;()&lt;/code&gt; as &lt;code&gt;f()&lt;/code&gt;. To execute the code inside an anonymous function &lt;code&gt;(() =&amp;gt; {})&lt;/code&gt;, the same function call syntax &lt;code&gt;()&lt;/code&gt; can be used as &lt;code&gt;(() =&amp;gt; {})()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(() =&amp;gt; {
    let count = 0;
    // ...
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is called an IIFE (Immediately invoked function expression). So a basic module can be defined in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define IIFE module.
const iifeCounterModule = (() =&amp;gt; {
    let count = 0;
    return {
        increase: () =&amp;gt; ++count,
        reset: () =&amp;gt; {
            count = 0;
            console.log(&quot;Count is reset.&quot;);
        }
    };
})();

// Use IIFE module.
iifeCounterModule.increase();
iifeCounterModule.reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It wraps the module code inside an IIFE. The anonymous function returns an object, which is the placeholder of exported APIs. Only 1 global variable is introduced, which is the module name (or namespace). Later the module name can be used to call the exported module APIs. This is called the module pattern of JavaScript.&lt;/p&gt;
&lt;h3&gt;Import mixins&lt;/h3&gt;
&lt;p&gt;When defining a module, some dependencies may be required. With IIFE module pattern, each dependent module is a global variable. The dependent modules can be directly accessed inside the anonymous function, or they can be passed as the anonymous function’s arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define IIFE module with dependencies.
const iifeCounterModule = ((dependencyModule1, dependencyModule2) =&amp;gt; {
    let count = 0;
    return {
        increase: () =&amp;gt; ++count,
        reset: () =&amp;gt; {
            count = 0;
            console.log(&quot;Count is reset.&quot;);
        }
    };
})(dependencyModule1, dependencyModule2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The early version of popular libraries, like jQuery, followed this pattern. (The latest version of jQuery follows the UMD module, which is explained later in this article.)&lt;/p&gt;
&lt;h2&gt;Revealing module: JavaScript revealing module pattern&lt;/h2&gt;
&lt;p&gt;The revealing module pattern is named by Christian Heilmann. This pattern is also an IIFE, but it emphasizes defining all APIs as local variables inside the anonymous function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define revealing module.
const revealingCounterModule = (() =&amp;gt; {
    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    return {
        increase,
        reset
    };
})();

// Use revealing module.
revealingCounterModule.increase();
revealingCounterModule.reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this syntax, it becomes easier when the APIs need to call each other.&lt;/p&gt;
&lt;h2&gt;CJS module: CommonJS module, or Node.js module&lt;/h2&gt;
&lt;p&gt;CommonJS, initially named ServerJS, is a pattern to define and consume modules. It is implemented by Node,js. By default, each &lt;code&gt;.js&lt;/code&gt; file is a CommonJS module. A &lt;code&gt;module&lt;/code&gt; variable and an &lt;code&gt;exports&lt;/code&gt; variable are provided for a module (a file) to expose APIs. And a &lt;code&gt;require&lt;/code&gt; function is provided to load and consume a module. The following code defines the counter module in CommonJS syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define CommonJS module: commonJSCounterModule.js.
const dependencyModule1 = require(&quot;./dependencyModule1&quot;);
const dependencyModule2 = require(&quot;./dependencyModule2&quot;);

let count = 0;
const increase = () =&amp;gt; ++count;
const reset = () =&amp;gt; {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};

exports.increase = increase;
exports.reset = reset;
// Or equivalently:
module.exports = {
    increase,
    reset
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example consumes the counter module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use CommonJS module.
const { increase, reset } = require(&quot;./commonJSCounterModule&quot;);
increase();
reset();
// Or equivelently:
const commonJSCounterModule = require(&quot;./commonJSCounterModule&quot;);
commonJSCounterModule.increase();
commonJSCounterModule.reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At runtime, Node.js implements this by wrapping the code inside the file into a function, then passes the &lt;code&gt;exports&lt;/code&gt; variable, &lt;code&gt;module&lt;/code&gt; variable, and &lt;code&gt;require&lt;/code&gt; function through arguments.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define CommonJS module: wrapped commonJSCounterModule.js.
(function (exports, require, module, __filename, __dirname) {
    const dependencyModule1 = require(&quot;./dependencyModule1&quot;);
    const dependencyModule2 = require(&quot;./dependencyModule2&quot;);

    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    module.exports = {
        increase,
        reset
    };

    return module.exports;
}).call(thisValue, exports, require, module, filename, dirname);

// Use CommonJS module.
(function (exports, require, module, __filename, __dirname) {
    const commonJSCounterModule = require(&quot;./commonJSCounterModule&quot;);
    commonJSCounterModule.increase();
    commonJSCounterModule.reset();
}).call(thisValue, exports, require, module, filename, dirname);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;AMD module: Asynchronous Module Definition, or RequireJS module&lt;/h2&gt;
&lt;p&gt;AMD (Asynchronous Module Definition &lt;a href=&quot;https://github.com/amdjs/amdjs-api&quot;&gt;https://github.com/amdjs/amdjs-api&lt;/a&gt;), is a pattern to define and consume module. It is implemented by RequireJS library &lt;a href=&quot;https://requirejs.org/&quot;&gt;https://requirejs.org/&lt;/a&gt;. AMD provides a &lt;code&gt;define&lt;/code&gt; function to define module, which accepts the module name, dependent modules’ names, and a factory function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define AMD module.
define(&quot;amdCounterModule&quot;, [&quot;dependencyModule1&quot;, &quot;dependencyModule2&quot;], (dependencyModule1, dependencyModule2) =&amp;gt; {
    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    return {
        increase,
        reset
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also provides a &lt;code&gt;require&lt;/code&gt; function to consume module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use AMD module.
require([&quot;amdCounterModule&quot;], amdCounterModule =&amp;gt; {
    amdCounterModule.increase();
    amdCounterModule.reset();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The AMD &lt;code&gt;require&lt;/code&gt; function is totally different from the CommonJS &lt;code&gt;require&lt;/code&gt; function. AMD &lt;code&gt;require&lt;/code&gt; accept the names of modules to be consumed, and pass the module to a function argument.&lt;/p&gt;
&lt;h3&gt;Dynamic loading&lt;/h3&gt;
&lt;p&gt;AMD’s &lt;code&gt;define&lt;/code&gt; function has another overload. It accepts a callback function, and pass a CommonJS-like &lt;code&gt;require&lt;/code&gt; function to that callback. Inside the callback function, &lt;code&gt;require&lt;/code&gt; can be called to dynamically load the module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use dynamic AMD module.
define(require =&amp;gt; {
    const dynamicDependencyModule1 = require(&quot;dependencyModule1&quot;);
    const dynamicDependencyModule2 = require(&quot;dependencyModule2&quot;);

    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    return {
        increase,
        reset
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;AMD module from CommonJS module&lt;/h3&gt;
&lt;p&gt;The above &lt;code&gt;define&lt;/code&gt; function overload can also passes the &lt;code&gt;require&lt;/code&gt; function as well as &lt;code&gt;exports&lt;/code&gt; variable and &lt;code&gt;module&lt;/code&gt; to its callback function. So inside the callback, CommonJS syntax code can work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define AMD module with CommonJS code.
define((require, exports, module) =&amp;gt; {
    // CommonJS code.
    const dependencyModule1 = require(&quot;dependencyModule1&quot;);
    const dependencyModule2 = require(&quot;dependencyModule2&quot;);

    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    exports.increase = increase;
    exports.reset = reset;
});

// Use AMD module with CommonJS code.
define(require =&amp;gt; {
    // CommonJS code.
    const counterModule = require(&quot;amdCounterModule&quot;);
    counterModule.increase();
    counterModule.reset();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;UMD module: Universal Module Definition, or UmdJS module&lt;/h2&gt;
&lt;p&gt;UMD (Universal Module Definition, &lt;a href=&quot;https://github.com/umdjs/umd&quot;&gt;https://github.com/umdjs/umd&lt;/a&gt;) is a set of tricky patterns to make your code file work in multiple environments.&lt;/p&gt;
&lt;h3&gt;UMD for both AMD (RequireJS) and native browser&lt;/h3&gt;
&lt;p&gt;For example, the following is a kind of UMD pattern to make module definition work with both AMD (RequireJS) and native browser:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define UMD module for both AMD and browser.
((root, factory) =&amp;gt; {
    // Detects AMD/RequireJS&quot;s define function.
    if (typeof define === &quot;function&quot; &amp;amp;&amp;amp; define.amd) {
        // Is AMD/RequireJS. Call factory with AMD/RequireJS&quot;s define function.
        define(&quot;umdCounterModule&quot;, [&quot;deependencyModule1&quot;, &quot;dependencyModule2&quot;], factory);
    } else {
        // Is Browser. Directly call factory.
        // Imported dependencies are global variables(properties of window object).
        // Exported module is also a global variable(property of window object)
        root.umdCounterModule = factory(root.deependencyModule1, root.dependencyModule2);
    }
})(typeof self !== &quot;undefined&quot; ? self : this, (deependencyModule1, dependencyModule2) =&amp;gt; {
    // Module code goes here.
    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    return {
        increase,
        reset
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is more complex but it is just an IIFE. The anonymous function detects if AMD’s &lt;code&gt;define&lt;/code&gt; function exists.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If yes, call the module factory with AMD’s &lt;code&gt;define&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;If not, it calls the module factory directly. At this moment,  the &lt;code&gt;root&lt;/code&gt; argument is actually the browser’s &lt;code&gt;window&lt;/code&gt; object. It gets dependency modules from global variables (properties of &lt;code&gt;window&lt;/code&gt; object). When &lt;code&gt;factory&lt;/code&gt; returns the module, the returned module is also assigned to a global variable (property of &lt;code&gt;window&lt;/code&gt; object).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;UMD for both AMD (RequireJS) and CommonJS (Node.js)&lt;/h3&gt;
&lt;p&gt;The following is another kind of UMD pattern to make module definition work with both AMD (RequireJS) and CommonJS (Node.js):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(define =&amp;gt; define((require, exports, module) =&amp;gt; {
    // Module code goes here.
    const dependencyModule1 = require(&quot;dependencyModule1&quot;);
    const dependencyModule2 = require(&quot;dependencyModule2&quot;);

    let count = 0;
    const increase = () =&amp;gt; ++count;
    const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };

    module.export = {
        increase,
        reset
    };
}))(// Detects module variable and exports variable of CommonJS/Node.js.
    // Also detect the define function of AMD/RequireJS.
    typeof module === &quot;object&quot; &amp;amp;&amp;amp; module.exports &amp;amp;&amp;amp; typeof define !== &quot;function&quot;
        ? // Is CommonJS/Node.js. Manually create a define function.
            factory =&amp;gt; module.exports = factory(require, exports, module)
        : // Is AMD/RequireJS. Directly use its define function.
            define);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, don’t be scared. It is just another IIFE. When the anonymous function is called, its argument is evaluated. The argument evaluation detects the environment (check the module variable and &lt;code&gt;exports&lt;/code&gt; variable of CommonJS/Node.js, as well as the &lt;code&gt;define&lt;/code&gt; function of AMD/RequireJS).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the environment is CommonJS/Node.js, the anonymous function’s argument is a manually created &lt;code&gt;define&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;If the environment is AMD/RequireJS, the anonymous function’s argument is just AMD’s &lt;code&gt;define&lt;/code&gt; function. So when the anonymous function is executed, it is guaranteed to have a working &lt;code&gt;define&lt;/code&gt; function. Inside the anonymous function, it simply calls the &lt;code&gt;define&lt;/code&gt; function to create the module.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ES module: ECMAScript 2015, or ES6 module&lt;/h2&gt;
&lt;p&gt;After all the module mess, in 2015, JavaScript’s spec version 6 introduces one more different module syntax. This spec is called ECMAScript 2015 (ES2015), or ECMAScript 6 (ES6). The main syntax is the import keyword and the export keyword. The following example uses new syntax to demonstrate ES module’s named import/export and default import/export:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define ES module: esCounterModule.js or esCounterModule.mjs.
import dependencyModule1 from &quot;./dependencyModule1.mjs&quot;;
import dependencyModule2 from &quot;./dependencyModule2.mjs&quot;;

let count = 0;
// Named export:
export const increase = () =&amp;gt; ++count;
export const reset = () =&amp;gt; {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};
// Or default export:
export default {
    increase,
    reset
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use this module file in browser, add a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag and specify it is a module: &lt;code&gt;&amp;lt;script type=&quot;module&quot; src=&quot;esCounterModule.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;. To use this module file in Node.js, rename its extension from &lt;code&gt;.js&lt;/code&gt; to &lt;code&gt;.mjs&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use ES module.
// Browser: &amp;lt;script type=&quot;module&quot; src=&quot;esCounterModule.js&quot;&amp;gt;&amp;lt;/script&amp;gt; or inline.
// Server: esCounterModule.mjs
// Import from named export.
import { increase, reset } from &quot;./esCounterModule.mjs&quot;;
increase();
reset();
// Or import from default export:
import esCounterModule from &quot;./esCounterModule.mjs&quot;;
esCounterModule.increase();
esCounterModule.reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For browser, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;’s &lt;code&gt;nomodule&lt;/code&gt; attribute can be used for fallback:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script nomodule&amp;gt;
    alert(&quot;Not supported.&quot;);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ES dynamic module: ECMAScript 2020, or ES11 dynamic module&lt;/h2&gt;
&lt;p&gt;In 2020, the latest JavaScript spec version 11 is introducing a built-in function &lt;code&gt;import&lt;/code&gt; to consume an ES module dynamically. The &lt;code&gt;import&lt;/code&gt; function returns a &lt;code&gt;promise&lt;/code&gt;, so its &lt;code&gt;then&lt;/code&gt; method can be called to consume the module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use dynamic ES module with promise APIs, import from named export:
import(&quot;./esCounterModule.js&quot;).then(({ increase, reset }) =&amp;gt; {
    increase();
    reset();
});
// Or import from default export:
import(&quot;./esCounterModule.js&quot;).then(dynamicESCounterModule =&amp;gt; {
    dynamicESCounterModule.increase();
    dynamicESCounterModule.reset();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By returning a &lt;code&gt;promise&lt;/code&gt;, apparently, &lt;code&gt;import&lt;/code&gt; function can also work with the &lt;code&gt;await&lt;/code&gt; keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use dynamic ES module with async/await.
(async () =&amp;gt; {

    // Import from named export:
    const { increase, reset } = await import(&quot;./esCounterModule.js&quot;);
    increase();
    reset();

    // Or import from default export:
    const dynamicESCounterModule = await import(&quot;./esCounterModule.js&quot;);
    dynamicESCounterModule.increase();
    dynamicESCounterModule.reset();

})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is the compatibility of import/dynamic import/export, from &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Open-Live-Writer/JavaScript-moduels_11325/image_2.png&quot; alt=&quot;import compatibility&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Open-Live-Writer/JavaScript-moduels_11325/image_4.png&quot; alt=&quot;export compatibility&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;System module: SystemJS module&lt;/h2&gt;
&lt;p&gt;SystemJS is a library that can enable ES module syntax for older ES. For example, the following module is defined in ES 6 syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define ES module.
import dependencyModule1 from &quot;./dependencyModule1.js&quot;;
import dependencyModule2 from &quot;./dependencyModule2.js&quot;;
dependencyModule1.api1();
dependencyModule2.api2();

let count = 0;
// Named export:
export const increase = function () { return ++count };
export const reset = function () {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};
// Or default export:
export default {
    increase,
    reset
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the current runtime, like an old browser, does not support ES6 syntax, the above code cannot work. One solution is to transpile the above module definition to a call of SystemJS library API, &lt;code&gt;System.register&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define SystemJS module.
System.register([&quot;./dependencyModule1.js&quot;, &quot;./dependencyModule2.js&quot;], function (exports_1, context_1) {
    &quot;use strict&quot;;
    var dependencyModule1_js_1, dependencyModule2_js_1, count, increase, reset;
    var __moduleName = context_1 &amp;amp;&amp;amp; context_1.id;
    return {
        setters: [
            function (dependencyModule1_js_1_1) {
                dependencyModule1_js_1 = dependencyModule1_js_1_1;
            },
            function (dependencyModule2_js_1_1) {
                dependencyModule2_js_1 = dependencyModule2_js_1_1;
            }
        ],
        execute: function () {
            dependencyModule1_js_1.default.api1();
            dependencyModule2_js_1.default.api2();
            count = 0;
            // Named export:
            exports_1(&quot;increase&quot;, increase = function () { return ++count };
            exports_1(&quot;reset&quot;, reset = function () {
                count = 0;
                console.log(&quot;Count is reset.&quot;);
            };);
            // Or default export:
            exports_1(&quot;default&quot;, {
                increase,
                reset
            });
        }
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the import/export new ES6 syntax is gone. The old API call syntax works for sure. This transpilation can be done automatically with Webpack, TypeScript, etc., which are explained later in this article.&lt;/p&gt;
&lt;h3&gt;Dynamic module loading&lt;/h3&gt;
&lt;p&gt;SystemJS also provides an import function for dynamic import:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use SystemJS module with promise APIs.
System.import(&quot;./esCounterModule.js&quot;).then(dynamicESCounterModule =&amp;gt; {
    dynamicESCounterModule.increase();
    dynamicESCounterModule.reset();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Webpack module: bundle from CJS, AMD, ES modules&lt;/h2&gt;
&lt;p&gt;Webpack is a bundler for modules. It transpiles combined CommonJS module, AMD module, and ES module into a single harmony module pattern, and bundle all code into a single file. For example, the following 3 files define 3 modules in 3 different syntaxes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Define AMD module: amdDependencyModule1.js
define(&quot;amdDependencyModule1&quot;, () =&amp;gt; {
    const api1 = () =&amp;gt; { };
    return {
        api1
    };
});

// Define CommonJS module: commonJSDependencyModule2.js
const dependencyModule1 = require(&quot;./amdDependencyModule1&quot;);
const api2 = () =&amp;gt; dependencyModule1.api1();
exports.api2 = api2;

// Define ES module: esCounterModule.js.
import dependencyModule1 from &quot;./amdDependencyModule1&quot;;
import dependencyModule2 from &quot;./commonJSDependencyModule2&quot;;
dependencyModule1.api1();
dependencyModule2.api2();

let count = 0;
const increase = () =&amp;gt; ++count;
const reset = () =&amp;gt; {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};

export default {
    increase,
    reset
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following file consumes the counter module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Use ES module: index.js
import counterModule from &quot;./esCounterModule&quot;;
counterModule.increase();
counterModule.reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Webpack can bundle all the above file, even they are in 3 different module systems, into a single file &lt;code&gt;main.js&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root
&lt;ul&gt;
&lt;li&gt;dist
&lt;ul&gt;
&lt;li&gt;main.js (Bundle of all files under src)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;src
&lt;ul&gt;
&lt;li&gt;amdDependencyModule1.js&lt;/li&gt;
&lt;li&gt;commonJSDependencyModule2.js&lt;/li&gt;
&lt;li&gt;esCounterModule.js&lt;/li&gt;
&lt;li&gt;index.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;webpack.config.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since Webpack is based on Node.js, Webpack uses CommonJS module syntax for itself. In &lt;code&gt;webpack.config.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const path = require(&apos;path&apos;);

module.exports = {
    entry: &apos;./src/index.js&apos;,
    mode: &quot;none&quot;, // Do not optimize or minimize the code for readability.
    output: {
        filename: &apos;main.js&apos;,
        path: path.resolve(__dirname, &apos;dist&apos;),
    },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run the following command to transpile and bundle all 4 files, which are in different syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install webpack webpack-cli --save-dev
npx webpack --config webpack.config.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AS a result, Webpack generates the bundle file &lt;code&gt;main.js&lt;/code&gt;. The following code in &lt;code&gt;main.js&lt;/code&gt; is reformatted, and variables are renamed, to improve readability:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function (modules) { // webpackBootstrap
    // The module cache
    var installedModules = {};
    // The require function
    function require(moduleId) {
        // Check if module is in cache
        if (installedModules[moduleId]) {
            return installedModules[moduleId].exports;

        }
        // Create a new module (and put it into the cache)
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}

        };
        // Execute the module function
        modules[moduleId].call(module.exports, module, module.exports, require);
        // Flag the module as loaded
        module.l = true;
        // Return the exports of the module
        return module.exports;
    }

    // expose the modules object (__webpack_modules__)
    require.m = modules;
    // expose the module cache
    require.c = installedModules;
    // define getter function for harmony exports
    require.d = function (exports, name, getter) {
        if (!require.o(exports, name)) {
            Object.defineProperty(exports, name, { enumerable: true, get: getter });

        }

    };
    // define __esModule on exports
    require.r = function (exports) {
        if (typeof Symbol !== &apos;undefined&apos; &amp;amp;&amp;amp; Symbol.toStringTag) {
            Object.defineProperty(exports, Symbol.toStringTag, { value: &apos;Module&apos; });

        }
        Object.defineProperty(exports, &apos;__esModule&apos;, { value: true });

    };
    // create a fake namespace object
    // mode &amp;amp; 1: value is a module id, require it
    // mode &amp;amp; 2: merge all properties of value into the ns
    // mode &amp;amp; 4: return value when already ns object
    // mode &amp;amp; 8|1: behave like require
    require.t = function (value, mode) {
        if (mode &amp;amp; 1) value = require(value);
        if (mode &amp;amp; 8) return value;
        if ((mode &amp;amp; 4) &amp;amp;&amp;amp; typeof value === &apos;object&apos; &amp;amp;&amp;amp; value &amp;amp;&amp;amp; value.__esModule) return value;
        var ns = Object.create(null);
        require.r(ns);
        Object.defineProperty(ns, &apos;default&apos;, { enumerable: true, value: value });
        if (mode &amp;amp; 2 &amp;amp;&amp;amp; typeof value != &apos;string&apos;) for (var key in value) require.d(ns, key, function (key) { return value[key]; }.bind(null, key));
        return ns;
    };
    // getDefaultExport function for compatibility with non-harmony modules
    require.n = function (module) {
        var getter = module &amp;amp;&amp;amp; module.__esModule ?
            function getDefault() { return module[&apos;default&apos;]; } :
            function getModuleExports() { return module; };
        require.d(getter, &apos;a&apos;, getter);
        return getter;
    };
    // Object.prototype.hasOwnProperty.call
    require.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    // __webpack_public_path__
    require.p = &quot;&quot;;
    // Load entry module and return exports
    return require(require.s = 0);
})([
    function (module, exports, require) {
        &quot;use strict&quot;;
        require.r(exports);
        // Use ES module: index.js.
        var esCounterModule = require(1);
        esCounterModule[&quot;default&quot;].increase();
        esCounterModule[&quot;default&quot;].reset();
    },
    function (module, exports, require) {
        &quot;use strict&quot;;
        require.r(exports);
        // Define ES module: esCounterModule.js.
        var amdDependencyModule1 = require.n(require(2));
        var commonJSDependencyModule2 = require.n(require(3));
        amdDependencyModule1.a.api1();
        commonJSDependencyModule2.a.api2();

        let count = 0;
        const increase = () =&amp;gt; ++count;
        const reset = () =&amp;gt; {
            count = 0;
            console.log(&quot;Count is reset.&quot;);
        };

        exports[&quot;default&quot;] = {
            increase,
            reset
        };
    },
    function (module, exports, require) {
        var result;
        !(result = (() =&amp;gt; {
            // Define AMD module: amdDependencyModule1.js
            const api1 = () =&amp;gt; { };
            return {
                api1
            };
        }).call(exports, require, exports, module),
            result !== undefined &amp;amp;&amp;amp; (module.exports = result));
    },
    function (module, exports, require) {
        // Define CommonJS module: commonJSDependencyModule2.js
        const dependencyModule1 = require(2);
        const api2 = () =&amp;gt; dependencyModule1.api1();
        exports.api2 = api2;
    }
]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, it is just another IIFE. The code of all 4 files is transpiled to the code in 4 functions in an array. And that array is passed to the anonymous function as an argument.&lt;/p&gt;
&lt;h2&gt;Babel module: transpile from ES module&lt;/h2&gt;
&lt;p&gt;Babel is another transpiler to convert ES6+ JavaScript code to the older syntax for the older environment like older browsers. The above counter module in ES6 import/export syntax can be converted to the following babel module with new syntax replaced:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Babel.
Object.defineProperty(exports, &quot;__esModule&quot;, {
    value: true
});
exports[&quot;default&quot;] = void 0;
function _interopRequireDefault(obj) { return obj &amp;amp;&amp;amp; obj.__esModule ? obj : { &quot;default&quot;: obj }; }

// Define ES module: esCounterModule.js.
var dependencyModule1 = _interopRequireDefault(require(&quot;./amdDependencyModule1&quot;));
var dependencyModule2 = _interopRequireDefault(require(&quot;./commonJSDependencyModule2&quot;));
dependencyModule1[&quot;default&quot;].api1();
dependencyModule2[&quot;default&quot;].api2();

var count = 0;
var increase = function () { return ++count; };
var reset = function () {
    count = 0;
    console.log(&quot;Count is reset.&quot;);
};

exports[&quot;default&quot;] = {
    increase: increase,
    reset: reset
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is the code in &lt;code&gt;index.js&lt;/code&gt; which consumes the counter module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Babel.
function _interopRequireDefault(obj) { return obj &amp;amp;&amp;amp; obj.__esModule ? obj : { &quot;default&quot;: obj }; }

// Use ES module: index.js
var esCounterModule = _interopRequireDefault(require(&quot;./esCounterModule.js&quot;));
esCounterModule[&quot;default&quot;].increase();
esCounterModule[&quot;default&quot;].reset();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the default transpilation. Babel can also work with other tools.&lt;/p&gt;
&lt;h3&gt;Babel with SystemJS&lt;/h3&gt;
&lt;p&gt;SystemJS can be used as a plugin for Babel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save-dev @babel/plugin-transform-modules-systemjs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it should be added to the Babel configuration &lt;code&gt;babel.config.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;plugins&quot;: [&quot;@babel/plugin-transform-modules-systemjs&quot;],
    &quot;presets&quot;: [
        [
            &quot;@babel/env&quot;,
            {
                &quot;targets&quot;: {
                    &quot;ie&quot;: &quot;11&quot;
                }
            }
        ]
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Babel can work with SystemJS to transpile CommonJS/Node.js module, AMD/RequireJS module, and ES module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx babel src --out-dir lib
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root
&lt;ul&gt;
&lt;li&gt;lib
&lt;ul&gt;
&lt;li&gt;amdDependencyModule1.js (Transpiled with SystemJS)&lt;/li&gt;
&lt;li&gt;commonJSDependencyModule2.js (Transpiled with SystemJS)&lt;/li&gt;
&lt;li&gt;esCounterModule.js (Transpiled with SystemJS)&lt;/li&gt;
&lt;li&gt;index.js (Transpiled with SystemJS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;src
&lt;ul&gt;
&lt;li&gt;amdDependencyModule1.js&lt;/li&gt;
&lt;li&gt;commonJSDependencyModule2.js&lt;/li&gt;
&lt;li&gt;esCounterModule.js&lt;/li&gt;
&lt;li&gt;index.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;babel.config.json&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now all the ADM, CommonJS, and ES module syntax are transpiled to SystemJS syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Transpile AMD/RequireJS module definition to SystemJS syntax: lib/amdDependencyModule1.js.
System.register([], function (_export, _context) {
    &quot;use strict&quot;;
    return {
        setters: [],
        execute: function () {
            // Define AMD module: src/amdDependencyModule1.js
            define(&quot;amdDependencyModule1&quot;, () =&amp;gt; {
                const api1 = () =&amp;gt; { };

                return {
                    api1
                };
            });
        }
    };
});

// Transpile CommonJS/Node.js module definition to SystemJS syntax: lib/commonJSDependencyModule2.js.
System.register([], function (_export, _context) {
    &quot;use strict&quot;;
    var dependencyModule1, api2;
    return {
        setters: [],
        execute: function () {
            // Define CommonJS module: src/commonJSDependencyModule2.js
            dependencyModule1 = require(&quot;./amdDependencyModule1&quot;);

            api2 = () =&amp;gt; dependencyModule1.api1();

            exports.api2 = api2;
        }
    };
});

// Transpile ES module definition to SystemJS syntax: lib/esCounterModule.js.
System.register([&quot;./amdDependencyModule1&quot;, &quot;./commonJSDependencyModule2&quot;], function (_export, _context) {
    &quot;use strict&quot;;
    var dependencyModule1, dependencyModule2, count, increase, reset;
    return {
        setters: [function (_amdDependencyModule) {
            dependencyModule1 = _amdDependencyModule.default;
        }, function (_commonJSDependencyModule) {
            dependencyModule2 = _commonJSDependencyModule.default;
        }],
        execute: function () {
            // Define ES module: src/esCounterModule.js.
            dependencyModule1.api1();
            dependencyModule2.api2();
            count = 0;

            increase = () =&amp;gt; ++count;

            reset = () =&amp;gt; {
                count = 0;
                console.log(&quot;Count is reset.&quot;);
            };

            _export(&quot;default&quot;, {
                increase,
                reset
            });
        }
    };
});

// Transpile ES module usage to SystemJS syntax: lib/index.js.
System.register([&quot;./esCounterModule&quot;], function (_export, _context) {
    &quot;use strict&quot;;
    var esCounterModule;
    return {
        setters: [function (_esCounterModuleJs) {
            esCounterModule = _esCounterModuleJs.default;
        }],
        execute: function () {
            // Use ES module: src/index.js
            esCounterModule.increase();
            esCounterModule.reset();
        }
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;TypeScript module: Transpile to CJS, AMD, ES, System modules&lt;/h2&gt;
&lt;p&gt;TypeScript supports all JavaScript syntax, including the ES6 module syntax &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/modules.html&quot;&gt;https://www.typescriptlang.org/docs/handbook/modules.html&lt;/a&gt;. When TypeScript transpiles, the ES module code can either be kept as ES6, or transpiled to other formats, including CommonJS/Node.js, AMD/RequireJS, UMD/UmdJS, or System/SystemJS, according to the specified transpiler options in &lt;code&gt;tsconfig.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;compilerOptions&quot;: {
        &quot;module&quot;: &quot;ES2020&quot;, // None, CommonJS, AMD, System, UMD, ES6, ES2015, ES2020, ESNext.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// TypeScript and ES module.
// With compilerOptions: { module: &quot;ES6&quot; }. Transpile to ES module with the same import/export syntax.
import dependencyModule from &quot;./dependencyModule&quot;;
dependencyModule.api();
let count = 0;
export const increase = function () { return ++count };


// With compilerOptions: { module: &quot;CommonJS&quot; }. Transpile to CommonJS/Node.js module:
var __importDefault = (this &amp;amp;&amp;amp; this.__importDefault) || function (mod) {
    return (mod &amp;amp;&amp;amp; mod.__esModule) ? mod : { &quot;default&quot;: mod };
};
exports.__esModule = true;

var dependencyModule_1 = __importDefault(require(&quot;./dependencyModule&quot;));
dependencyModule_1[&quot;default&quot;].api();
var count = 0;
exports.increase = function () { return ++count; };

// With compilerOptions: { module: &quot;AMD&quot; }. Transpile to AMD/RequireJS module:
var __importDefault = (this &amp;amp;&amp;amp; this.__importDefault) || function (mod) {
    return (mod &amp;amp;&amp;amp; mod.__esModule) ? mod : { &quot;default&quot;: mod };
};
define([&quot;require&quot;, &quot;exports&quot;, &quot;./dependencyModule&quot;], function (require, exports, dependencyModule_1) {
    &quot;use strict&quot;;
    exports.__esModule = true;

    dependencyModule_1 = __importDefault(dependencyModule_1);
    dependencyModule_1[&quot;default&quot;].api();
    var count = 0;
    exports.increase = function () { return ++count; };
});

// With compilerOptions: { module: &quot;UMD&quot; }. Transpile to UMD/UmdJS module:
var __importDefault = (this &amp;amp;&amp;amp; this.__importDefault) || function (mod) {
    return (mod &amp;amp;&amp;amp; mod.__esModule) ? mod : { &quot;default&quot;: mod };
};
(function (factory) {
    if (typeof module === &quot;object&quot; &amp;amp;&amp;amp; typeof module.exports === &quot;object&quot;) {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === &quot;function&quot; &amp;amp;&amp;amp; define.amd) {
        define([&quot;require&quot;, &quot;exports&quot;, &quot;./dependencyModule&quot;], factory);
    }
})(function (require, exports) {
    &quot;use strict&quot;;
    exports.__esModule = true;

    var dependencyModule_1 = __importDefault(require(&quot;./dependencyModule&quot;));
    dependencyModule_1[&quot;default&quot;].api();
    var count = 0;
    exports.increase = function () { return ++count; };
});

// With compilerOptions: { module: &quot;System&quot; }. Transpile to System/SystemJS module:
System.register([&quot;./dependencyModule&quot;], function (exports_1, context_1) {
    &quot;use strict&quot;;
    var dependencyModule_1, count, increase;
    var __moduleName = context_1 &amp;amp;&amp;amp; context_1.id;
    return {
        setters: [
            function (dependencyModule_1_1) {
                dependencyModule_1 = dependencyModule_1_1;
            }
        ],
        execute: function () {
            dependencyModule_1[&quot;default&quot;].api();
            count = 0;
            exports_1(&quot;increase&quot;, increase = function () { return ++count; });
        }
    };
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ES module syntax supported in TypeScript was called external modules.&lt;/p&gt;
&lt;h3&gt;Internal module and namespace&lt;/h3&gt;
&lt;p&gt;TypeScript also has a &lt;code&gt;module&lt;/code&gt; keyword and a &lt;code&gt;namespace&lt;/code&gt; keyword &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html#pitfalls-of-namespaces-and-modules&quot;&gt;https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html#pitfalls-of-namespaces-and-modules&lt;/a&gt;. They were called internal modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module Counter {
    let count = 0;
    export const increase = () =&amp;gt; ++count;
    export const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };
}

namespace Counter {
    let count = 0;
    export const increase = () =&amp;gt; ++count;
    export const reset = () =&amp;gt; {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are both transpiled to JavaScript objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Counter;
(function (Counter) {
    var count = 0;
    Counter.increase = function () { return ++count; };
    Counter.reset = function () {
        count = 0;
        console.log(&quot;Count is reset.&quot;);
    };
})(Counter || (Counter = {}));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript module and namespace can have multiple levels by supporting the &lt;code&gt;.&lt;/code&gt; separator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module Counter.Sub {
    let count = 0;
    export const increase = () =&amp;gt; ++count;
}

namespace Counter.Sub {
    let count = 0;
    export const increase = () =&amp;gt; ++count;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The the sub module and sub namespace are both transpiled to object’s property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Counter;
(function (Counter) {
    var Sub;
    (function (Sub) {
        var count = 0;
        Sub.increase = function () { return ++count; };
    })(Sub = Counter.Sub || (Counter.Sub = {}));
})(Counter|| (Counter = {}));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript module and namespace can also be used in the &lt;code&gt;export&lt;/code&gt; statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module Counter {
    let count = 0;
    export module Sub {
        export const increase = () =&amp;gt; ++count;
    }
}

module Counter {
    let count = 0;
    export namespace Sub {
        export const increase = () =&amp;gt; ++count;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The transpilation is the same as submodule and sub-namespace:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Counter;
(function (Counter) {
    var count = 0;
    var Sub;
    (function (Sub) {
        Sub.increase = function () { return ++count; };
    })(Sub = Counter.Sub || (Counter.Sub = {}));
})(Counter || (Counter = {}));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Welcome to JavaScript, which has so much drama - 10+ systems/formats just for modularization/namespace:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IIFE module: JavaScript &lt;strong&gt;module pattern&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Revealing module: JavaScript &lt;strong&gt;revealing module pattern&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CJS module&lt;/strong&gt;: CommonJS module, or Node.js module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AMD module&lt;/strong&gt;: Asynchronous Module Definition, or RequireJS module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UMD module&lt;/strong&gt;: Universal Module Definition, or UmdJS module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ES module&lt;/strong&gt;: ECMAScript 2015, or ES6 module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ES dynamic module&lt;/strong&gt;: ECMAScript 2020, or ES11 dynamic module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System module&lt;/strong&gt;: SystemJS module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Webpack module&lt;/strong&gt;: transpile and bundle of CJS, AMD, ES modules&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Babel module&lt;/strong&gt;: transpile ES module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript module&lt;/strong&gt; and namespace&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Fortunately, now JavaScript has standard built-in language features for modules, and it is supported by Node.js and all the latest modern browsers. For the older environments, you can still code with the new ES module syntax, then use Webpack/Babel/SystemJS/TypeScript to transpile to older or compatible syntax.&lt;/p&gt;
</content:encoded></item><item><title>Port Microsoft Concurrency Visualizer SDK to .NET Standard and NuGet</title><link>https://dixin.github.io/posts/port-microsoft-concurrency-visualizer-sdk-to-net-standard-and-nuget/</link><guid isPermaLink="true">https://dixin.github.io/posts/port-microsoft-concurrency-visualizer-sdk-to-net-standard-and-nuget/</guid><description>I uploaded a NuGet package of Microsoft Concurrency Visualizer SDK: . [Microsoft Concurrency Visualizer](https://docs.micr</description><pubDate>Fri, 24 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I uploaded a NuGet package of Microsoft Concurrency Visualizer SDK: &lt;a href=&quot;https://www.nuget.org/packages/ConcurrencyVisualizer/&quot;&gt;ConcurrencyVisualizer&lt;/a&gt;. &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/profiling/concurrency-visualizer&quot;&gt;Microsoft Concurrency Visualizer&lt;/a&gt; is an extension tool for Visual Studio. It is a great tool for performance profiling and multithreading execution visualization. It also has a &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/profiling/concurrency-visualizer-sdk&quot;&gt;SDK library&lt;/a&gt; to be invoked by code and draw markers and spans in the timeline. I used it to visualize sequential LINQ and Parallel LINQ (PLINQ) execution in my Functional Programming and LINQ tutorials. For example, array.Where(…).Select(…) sequential LINQ query and array.AsParallel().Where(…).Select(…) Parallel LINQ query can be visualized as following spans:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb11_thumb%5B6%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb11_thumb%5B6%5D_thumb.png&quot; alt=&quot;image_thumb11_thumb[6]&quot; title=&quot;image_thumb11_thumb[6]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Concurrency Visualizer is available in Visual Studio Marketplace:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb%5B4%5D_thumb.png&quot; alt=&quot;image_thumb[4]&quot; title=&quot;image_thumb[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the SDK library is available for .NET Framework, and can be installed from menu item:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb1%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb1%5B4%5D_thumb.png&quot; alt=&quot;image_thumb1[4]&quot; title=&quot;image_thumb1[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This adds a reference to local assembly C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\4hhyuhoo.ghy\SDK\Managed\4.0\Microsoft.ConcurrencyVisualizer.Markers.dll. For your convenience, I have made a NuGet package:&lt;/p&gt;
&lt;p&gt;Install-Package ConcurrencyVisualizer&lt;/p&gt;
&lt;p&gt;It makes your code more potable. I have also ported the code to .NET Standard, so now the SDK can work with .NET Framework, .NET Core, etc.:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb2%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb2%5B4%5D_thumb.png&quot; alt=&quot;image_thumb2[4]&quot; title=&quot;image_thumb2[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now the Concurrency Visualizer tool can visualize markers and spans of .NET Core correctly.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb4_thumb%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb4_thumb%5B4%5D_thumb.png&quot; alt=&quot;image_thumb4_thumb[4]&quot; title=&quot;image_thumb4_thumb[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>TransientFaultHandling.Core: Retry library for .NET Core/.NET Standard</title><link>https://dixin.github.io/posts/transientfaulthandling-core-retry-library-for-net-core-net-standard/</link><guid isPermaLink="true">https://dixin.github.io/posts/transientfaulthandling-core-retry-library-for-net-core-net-standard/</guid><description>TransientFaultHandling.Core is retry library for transient error handling. It is ported from Microsoft Enterprise Library’s TransientFaultHandling library, a library widely used with .NET Framework. T</description><pubDate>Wed, 22 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TransientFaultHandling.Core is retry library for transient error handling. It is ported from Microsoft Enterprise Library’s TransientFaultHandling library, a library widely used with .NET Framework. The retry pattern APIs are ported to .NET Core/.NET Standard, with outdated configuration API updated, and new retry APIs added for convenience.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;With this library, the old code of retry logic based on Microsoft Enterprise Library can be ported to .NET Core/.NET Standard without modification:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ITransientErrorDetectionStrategy transientExceptionDetection = new MyDetection();
RetryStrategy retryStrategy = new FixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(1));
RetryPolicy retryPolicy = new RetryPolicy(transientExceptionDetection, retryStrategy);
string result = retryPolicy.ExecuteAction(() =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this library, it is extremely easy to detect transient exception and implement retry logic. For example, the following code downloads a string, if the exception thrown is transient (a WebException), it retries up to 5 times, and it waits for 1 second between retries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry.FixedInterval(
    () =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;),
    isTransient: exception =&amp;gt; exception is WebException,
    retryCount: 5, retryInterval: TimeSpan.FromSeconds(1));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fluent APIs are also provided for even better readability:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry
    .WithIncremental(retryCount: 5, initialInterval: TimeSpan.FromSeconds(1),
        increment: TimeSpan.FromSeconds(1))
    .Catch&amp;lt;OperationCanceledException&amp;gt;()
    .Catch&amp;lt;WebException&amp;gt;(exception =&amp;gt;
        exception.Response is HttpWebResponse response &amp;amp;&amp;amp; response.StatusCode == HttpStatusCode.RequestTimeout)
    .ExecuteAction(() =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also supports JSON/XML/INI configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;retryStrategy&quot;: {
    &quot;name1&quot;: {
      &quot;fastFirstRetry&quot;: &quot;true&quot;,
      &quot;retryCount&quot;: 5,
      &quot;retryInterval&quot;: &quot;00:00:00.1&quot;
    },
    &quot;name2&quot;: {
      &quot;fastFirstRetry&quot;: &quot;true&quot;,
      &quot;retryCount&quot;: 55,
      &quot;initialInterval&quot;: &quot;00:00:00.2&quot;,
      &quot;increment&quot;: &quot;00:00:00.3&quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Document&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/transientfaulthandling-core-retry-library-for-net-core-net-standard&quot;&gt;https://weblogs.asp.net/dixin/transientfaulthandling-core-retry-library-for-net-core-net-standard&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Source&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Dixin/EnterpriseLibrary.TransientFaultHandling.Core&quot;&gt;https://github.com/Dixin/EnterpriseLibrary.TransientFaultHandling.Core&lt;/a&gt; (Partially ported from &lt;a href=&quot;https://github.com/MicrosoftArchive/transient-fault-handling-application-block&quot;&gt;Topaz&lt;/a&gt;, with additional new APIs and updated configuration APIs).&lt;/p&gt;
&lt;h2&gt;NuGet installation&lt;/h2&gt;
&lt;p&gt;It can be installed through &lt;a href=&quot;https://www.nuget.org/packages/EntityFramework.Functions&quot;&gt;NuGet&lt;/a&gt; using .NET CLI:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;dotnet add package EnterpriseLibrary.TransientFaultHandling.Core&lt;/p&gt;
&lt;p&gt;dotnet add package TransientFaultHandling.Caching&lt;/p&gt;
&lt;p&gt;dotnet add package TransientFaultHandling.Configuration&lt;/p&gt;
&lt;p&gt;dotnet add package TransientFaultHandling.Data&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or in Visual Studio NuGet Package Manager Console:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Install-Package EnterpriseLibrary.TransientFaultHandling.Core&lt;/p&gt;
&lt;p&gt;Install-Package TransientFaultHandling.Caching&lt;/p&gt;
&lt;p&gt;Install-Package TransientFaultHandling.Configuration&lt;/p&gt;
&lt;p&gt;Install-Package TransientFaultHandling.Data&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Backward compatibility with Enterprise Library&lt;/h2&gt;
&lt;p&gt;This library provides maximum backward compatibility with Microsoft Enterprise Library’s TransientFaultHandling (aka Topaz) for .NET Framework:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you have code using EnterpriseLibrary.TransientFaultHandling, you can port your code to use EnterpriseLibrary.TransientFaultHandling.Core, without any modification.&lt;/li&gt;
&lt;li&gt;If you have code using EnterpriseLibrary.TransientFaultHandling.Caching, you can port your code to use TransientFaultHandling.Caching, without any modification.&lt;/li&gt;
&lt;li&gt;If you have code using EnterpriseLibrary.TransientFaultHandling.Data, you can port your code to use TransientFaultHandling.Data, without any modification.&lt;/li&gt;
&lt;li&gt;If you have code and configuration based on EnterpriseLibrary.TransientFaultHandling.Configuration, you have to change your code and configuration to use TransientFaultHandling.Configuration. The old XML configuration infrastructure based on .NET Framework is outdated. You need to replace the old XML format with new XML/JSON/INI format configuration supported by .NET Core/.NET Standard.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How to use the APIs&lt;/h2&gt;
&lt;p&gt;For retry pattern, please read Microsoft’s &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/architecture/patterns/retry&quot;&gt;introduction in Cloud Design Patterns&lt;/a&gt;. For the introduction of transient fault handling, read Microsoft’s &lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn440719(v=pandp.60)&quot;&gt;Perseverance, Secret of All Triumphs: Using the Transient Fault Handling Application Block&lt;/a&gt; and Microsoft Azure Architecture Center’s &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/architecture/best-practices/transient-faults&quot;&gt;Best practice - Transient fault handling&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Object-oriented APIs from Enterprise Library&lt;/h3&gt;
&lt;p&gt;Enterprise Library existing APIs follows an object-oriented design. For the details, please see Microsoft’s &lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn170426(v=pandp.60)&quot;&gt;API reference&lt;/a&gt; and ebook &lt;a href=&quot;http://go.microsoft.com/fwlink/p/?linkid=290904&quot;&gt;Developer&apos;s Guide to Microsoft Enterprise Library&lt;/a&gt;‘s Chapter 4, Using the Transient Fault Handling Application Block. Here is a brief introduction.&lt;/p&gt;
&lt;p&gt;First, ITransientErrorDetectionStrategy interface must be implemented. It has a single method IsTransient to detected if the thrown exception is transient and retry should be executed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class MyDetection : ITransientErrorDetectionStrategy
{
    bool IsTransient(Exception exception) =&amp;gt; 
        exception is OperationCanceledException;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Second, a retry strategy must be defined to specify how the retry is executed, like retry count, retry interval, etc.. a retry strategy must inherit RetryStrategy abstract class. There are 3 built-in retry strategies: FixedInterval, Incremental, ExponentialBackoff.&lt;/p&gt;
&lt;p&gt;Then a retry policy (RetryPolicy class) must be instantiated with a retry strategy and an ITransientErrorDetectionStrategy interface. a retry policy has an ExecuteAction method to execute the specified synchronous function, and an ExecuteAsync method to execute a\the specified async function. It also has a Retrying event. When the executed sync/async function throws an exception, if the exception is detected to be transient and max retry count is not reached, then it waits for the specified retry interval, and then it fires the Retrying event, and execute the specified sync/async function again.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RetryStrategy retryStrategy = new FixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(1));

RetryPolicy retryPolicy = new RetryPolicy(new MyDetection(), retryStrategy);
retryPolicy.Retrying += (sender, args) =&amp;gt;
    Console.WriteLine($@&quot;{args.CurrentRetryCount}: {args.LastException}&quot;);

using (WebClient webClient = new WebClient())
{
    string result1 = retryPolicy.ExecuteAction(() =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;));
    string result2 = await retryPolicy.ExecuteAsync(() =&amp;gt; webClient.DownloadStringTaskAsync(&quot;https://DixinYan.com&quot;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;New functional APIs: single function call for retry&lt;/h3&gt;
&lt;p&gt;The above object-oriented API design is very inconvenient. New static functions Retry.FixedInterval, Retry.Incremental, Retry.ExponentialBackoff are added to implement retry with a single function call. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry.FixedInterval(
    () =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;),
    isTransient: exception =&amp;gt; exception is OperationCanceledException,
    retryCount: 5, retryInterval: TimeSpan.FromSeconds(1),
    retryingHandler: (sender, args) =&amp;gt;
        Console.WriteLine($@&quot;{args.CurrentRetryCount}: {args.LastException}&quot;));

await Retry.IncrementalAsync(
    () =&amp;gt; webClient.DownloadStringTaskAsync(&quot;https://DixinYan.com&quot;),
    isTransient: exception =&amp;gt; exception is OperationCanceledException,
    retryCount: 5, initialInterval: TimeSpan.FromSeconds(1), increment: TimeSpan.FromSeconds(2));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These sync and async functions are very convenient because only the first argument (action to execute) is required. All the other arguments are optional. And a function can be defined inline to detect transient exception, instead of defining a type to implement an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Treat any exception as transient. Use default retry count, default interval. No event handler.
Retry.FixedInterval(() =&amp;gt; webClient.DownloadString(&quot;https://DixinYan.com&quot;));

// Treat any exception as transient. Specify retry count. Use default initial interval, default increment. No event handler.
await Retry.IncrementalAsync(
    () =&amp;gt; webClient.DownloadStringTaskAsync(&quot;https://DixinYan.com&quot;),
    retryCount: 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;New fluent APIs for retry&lt;/h3&gt;
&lt;p&gt;For better readability, new fluent APIs are provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry
    .WithFixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(1))
    .Catch(exception =&amp;gt;
        exception is OperationCanceledException ||
        exception is HttpListenerException httpListenerException &amp;amp;&amp;amp; httpListenerException.ErrorCode == 404)
    .HandleWith((sender, args) =&amp;gt;
        Console.WriteLine($@&quot;{args.CurrentRetryCount}: {args.LastException}&quot;))
    .ExecuteAction(() =&amp;gt; MyTask());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The HandleWith call adds an event handler to the Retying event. It is optional:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry
    .WithFixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(1))
    .Catch(exception =&amp;gt;
        exception is OperationCanceledException ||
        exception is HttpListenerException httpListenerException &amp;amp;&amp;amp; httpListenerException.ErrorCode == 404)
    .ExecuteAction(() =&amp;gt; MyTask());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Catch method has a generic overload. The above code is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry
    .WithFixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(1))
    .Catch&amp;lt;OperationCanceledException&amp;gt;()
    .Catch&amp;lt;HttpListenerException&amp;gt;(exception =&amp;gt; exception.ErrorCode == 404)
    .ExecuteAction(() =&amp;gt; MyTask());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code “catches” any exception as transient:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Retry
    .WithIncremental(retryCount: 5, increment: TimeSpan.FromSeconds(1)) // Use default initial interval.
    .Catch() // Equivalent to: .Catch&amp;lt;Exception&amp;gt;()
    .ExecuteAction(() =&amp;gt; MyTask());
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Old XML configuration for retry&lt;/h3&gt;
&lt;p&gt;Ditched the following old XML format from .NET Framework:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;configSections&amp;gt;
    &amp;lt;section name=&quot;RetryPolicyConfiguration&quot; type=&quot;Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Configuration.RetryPolicyConfigurationSettings, Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Configuration&quot; /&amp;gt;
  &amp;lt;/configSections&amp;gt;
  &amp;lt;RetryPolicyConfiguration&amp;gt;
    &amp;lt;fixedInterval name=&quot;FixedIntervalDefault&quot; maxRetryCount=&quot;10&quot; retryInterval=&quot;00:00:00.1&quot; /&amp;gt;
    &amp;lt;incremental name=&quot;IncrementalIntervalDefault&quot; maxRetryCount=&quot;10&quot; initialInterval=&quot;00:00:00.01&quot; retryIncrement=&quot;00:00:00.05&quot; /&amp;gt;
    &amp;lt;exponentialBackoff name=&quot;ExponentialIntervalDefault&quot; maxRetryCount=&quot;10&quot; minBackoff=&quot;100&quot; maxBackoff=&quot;1000&quot; deltaBackoff=&quot;100&quot; /&amp;gt;
  &amp;lt;/RetryPolicyConfiguration&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These old XML infrastructures are outdated. Use new XML/JSON/INI format configuration supported by .NET Standard/.NET Core.&lt;/p&gt;
&lt;h3&gt;New XML/JSON/INI configuration for retry&lt;/h3&gt;
&lt;p&gt;Please install TransientFaultHandling.Configuration package. The following is an example JSON configuration file app.json. It has 3 retry strategies, a FixedInterval retry strategy, a Incremental retry strategy, and an ExponentialBackoff retry strategy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;retryStrategy&quot;: {
    &quot;name1&quot;: {
      &quot;fastFirstRetry&quot;: &quot;true&quot;,
      &quot;retryCount&quot;: 5,
      &quot;retryInterval&quot;: &quot;00:00:00.1&quot;
    },
    &quot;name2&quot;: {
      &quot;fastFirstRetry&quot;: &quot;true&quot;,
      &quot;retryCount&quot;: 55,
      &quot;initialInterval&quot;: &quot;00:00:00.2&quot;,
      &quot;increment&quot;: &quot;00:00:00.3&quot;
    },
    &quot;name3&quot;: {
      &quot;fastFirstRetry&quot;: &quot;true&quot;,
      &quot;retryCount&quot;: 555,
      &quot;minBackoff&quot;: &quot;00:00:00.4&quot;,
      &quot;maxBackoff&quot;: &quot;00:00:00.5&quot;,
      &quot;deltaBackoff&quot;: &quot;00:00:00.6&quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same configuration file app.xml in XML format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;retryStrategy name=&quot;name1&quot;&amp;gt;
    &amp;lt;fastFirstRetry&amp;gt;true&amp;lt;/fastFirstRetry&amp;gt;
    &amp;lt;retryCount&amp;gt;5&amp;lt;/retryCount&amp;gt;
    &amp;lt;retryInterval&amp;gt;00:00:00.1&amp;lt;/retryInterval&amp;gt;
  &amp;lt;/retryStrategy&amp;gt;
  &amp;lt;retryStrategy name=&quot;name2&quot;&amp;gt;
    &amp;lt;fastFirstRetry&amp;gt;true&amp;lt;/fastFirstRetry&amp;gt;
    &amp;lt;retryCount&amp;gt;55&amp;lt;/retryCount&amp;gt;
    &amp;lt;initialInterval&amp;gt;00:00:00.2&amp;lt;/initialInterval&amp;gt;
    &amp;lt;increment&amp;gt;00:00:00.3&amp;lt;/increment&amp;gt;
  &amp;lt;/retryStrategy&amp;gt;
  &amp;lt;retryStrategy name=&quot;name3&quot;&amp;gt;
    &amp;lt;fastFirstRetry&amp;gt;true&amp;lt;/fastFirstRetry&amp;gt;
    &amp;lt;retryCount&amp;gt;555&amp;lt;/retryCount&amp;gt;
    &amp;lt;minBackoff&amp;gt;00:00:00.4&amp;lt;/minBackoff&amp;gt;
    &amp;lt;maxBackoff&amp;gt;00:00:00.5&amp;lt;/maxBackoff&amp;gt;
    &amp;lt;deltaBackoff&amp;gt;00:00:00.6&amp;lt;/deltaBackoff&amp;gt;
  &amp;lt;/retryStrategy&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And app.ini file in INI format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[retryStrategy:name1]
fastFirstRetry=true
retryCount=5
retryInterval=00:00:00.1

[retryStrategy:name2]
fastFirstRetry=true
retryCount=55
initialInterval=00:00:00.2
increment=00:00:00.3

[retryStrategy:name3]
fastFirstRetry=true
retryCount=5555
minBackoff=00:00:00.4
maxBackoff=00:00:00.5
deltaBackoff=00:00:00.6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These configurations can be easily loaded and deserialized into retry strategy instances:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IConfiguration configuration = new ConfigurationBuilder()
    .AddJsonFile(&quot;app.json&quot;) // or AddXml(&quot;app.xml&quot;) or AddIni(&quot;app.ini&quot;)
    .Build();

IDictionary&amp;lt;string, RetryStrategy&amp;gt; retryStrategies = configuration.GetRetryStrategies();
// or retryStrategies = configuration.GetRetryStrategies(&quot;yourConfigurationSectionKey&quot;);
// The default configuration section key is &quot;retryStrategy&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The GetRetryStrategies extension method returns a dictionary of key value pairs, where each key is the specified name of retry strategy, and each value is the retry strategy instance. Here the first key is “name1”, the first value is a FixedInterval retry strategy instance. The second key is “anme2”, the second value is Incremental retry strategy instance. The third key is “name3”, the third value is ExponentialBackoff retry strategy instance. This extension method can also accept custom configuration section key, and a function to create instance of custom retry strategy type.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;retryStrategies = configuration.GetRetryStrategies(
    key: &quot;yourConfigurationSectionKey&quot;,
    getCustomRetryStrategy: configurationSection =&amp;gt; new MyRetryStrategyType(...));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other generic overload can filter the specified retry strategy type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FixedInterval retryStrategy = configuration.GetRetryStrategies&amp;lt;FixedInterval&amp;gt;().Single().Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It still returns a dictionary, which only has the specified type of retry strategies.&lt;/p&gt;
&lt;h2&gt;TransientFaultHandling.Data.Core: SQL Server support&lt;/h2&gt;
&lt;p&gt;Since 2.1.0, both Microsoft.Data.SqlClient and System.Data.SqlClient are supported. A API breaking change is introduced for this. If you are using the latest Microsoft.Data.SqlClient, no code change is needed. If you are using the legacy System.Data.SqlClient, the following types are renamed with a Legacy suffix:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReliableSqlConnection –&amp;gt; ReliableSqlConnection&lt;strong&gt;Legacy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;SqlDatabaseTransientErrorDetectionStrategy –&amp;gt; SqlDatabaseTransientErrorDetectionStrategy&lt;strong&gt;Legacy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;SqlAzureTransientErrorDetectionStrategy –&amp;gt; SqlAzureTransientErrorDetectionStrategy&lt;strong&gt;Legacy&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can either rename these types or add the using directives:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using ReliableSqlConnection = Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ReliableSqlConnectionLegacy;
using SqlDatabaseTransientErrorDetectionStrategy = Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.SqlDatabaseTransientErrorDetectionStrategyLegacy;
using SqlAzureTransientErrorDetectionStrategy = Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure.SqlAzureTransientErrorDetectionStrategyLegacy;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;p&gt;This library follows the &lt;a href=&quot;http://semver.org/&quot;&gt;http://semver.org&lt;/a&gt; standard for semantic versioning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.0.0: Initial release. Ported EnterpriseLibrary.TransientFaultHandling from .NET Framework to .NET Core/.NET Standard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.1.0: Add functional APIs for retry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.2.0: Add functional APIs for retry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.0.0: Add fluent APIs for retry. Ported EnterpriseLibrary.TransientFaultHandling.Caching from .NET Framework to .NET Core/.NET Standard. Ported EnterpriseLibrary.TransientFaultHandling.Data from .NET Framework to .NET Core/.NET Standard. Redesigned/reimplemented EnterpriseLibrary.TransientFaultHandling.Configuration with JSON in .NET Core/.NET Standard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.1.0: Add support for Microsoft.Data.SqlClient. Now both Microsoft.Data.SqlClient and System.Data.SqlClient are supported.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Category Theory via C# (8) Advanced LINQ to Monads</title><link>https://dixin.github.io/posts/category-theory-via-csharp-8-more-linq-to-monads/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-8-more-linq-to-monads/</guid><description>Monad is a powerful structure, with the LINQ support in C# language, monad enables chaining operations to build fluent workflow, which can be pure. With these features, monad can be used to manage I/O</description><pubDate>Tue, 31 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Monad is a powerful structure, with the LINQ support in C# language, monad enables chaining operations to build fluent workflow, which can be pure. With these features, monad can be used to manage I/O, state changes, exception handling, shared environment, logging/tracing, and continuation, etc., in the functional paradigm.&lt;/p&gt;
&lt;h2&gt;IO monad&lt;/h2&gt;
&lt;p&gt;IO is impure. As already demonstrated, the Lazy&amp;lt;&amp;gt; and Func&amp;lt;&amp;gt; monads can build purely function workflows consists of I/O operations. The I/O is produced only when the workflows is started. So the Func&amp;lt;&amp;gt; monad is also called IO monad (Again, Lazy&amp;lt;T&amp;gt; is just a wrapper of Func&amp;lt;T&amp;gt; factory function, so Lazy&amp;lt;&amp;gt; and Func&amp;lt;&amp;gt; can be viewed as equivalent.). Here, to be more intuitive, rename Func&amp;lt;&amp;gt; to IO&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// IO: () -&amp;gt; T
public delegate T IO&amp;lt;out T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;T&amp;gt; or IO&amp;lt;T&amp;gt; is just a wrapper of T. Generally, the difference is, if a value T is obtained, effect is already produced; and if a Func&amp;lt;T&amp;gt; or IO&amp;lt;T&amp;gt; function wrapper is obtained, the effect can be delayed to produce, until explicitly calling this function to pull the wrapped T value. The following example is a simple comparison:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class IOExtensions
{
    internal static string Impure()
    {
        string filePath = Console.ReadLine();
        string fileContent = File.ReadAllText(filePath);
        return fileContent;
    }

    internal static IO&amp;lt;string&amp;gt; Pure()
    {
        IO&amp;lt;string&amp;gt; filePath = () =&amp;gt; Console.ReadLine();
        IO&amp;lt;string&amp;gt; fileContent = () =&amp;gt; File.ReadAllText(filePath());
        return fileContent;
    }

    internal static void IO()
    {
        string ioResult1 = Impure(); // IO is produced.
        IO&amp;lt;string&amp;gt; ioResultWrapper = Pure(); // IO is not produced.

        string ioResult2 = ioResultWrapper(); // IO is produced.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IO&amp;lt;&amp;gt; monad is just Func&amp;lt;&amp;gt; monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class IOExtensions
{
    // SelectMany: (IO&amp;lt;TSource&amp;gt;, TSource -&amp;gt; IO&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; IO&amp;lt;TResult&amp;gt;
    public static IO&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this IO&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, IO&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            () =&amp;gt;
            {
                TSource value = source();
                return resultSelector(value, selector(value)());
            };

    // Wrap: TSource -&amp;gt; IO&amp;lt;TSource&amp;gt;
    public static IO&amp;lt;TSource&amp;gt; IO&amp;lt;TSource&amp;gt;(this TSource value) =&amp;gt; () =&amp;gt; value;

    // Select: (IO&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; IO&amp;lt;TResult&amp;gt;
    public static IO&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this IO&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).IO(), (value, result) =&amp;gt; result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The (SelectMany, Wrap, Select) operations are defined so that the LINQ functor syntax (single from clause) and monad syntax (multiple from clauses) are enabled. The let clause is also enabled by Select, which provides great convenience.&lt;/p&gt;
&lt;p&gt;Some I/O operations, like above Console.ReadLine: () –&amp;gt; string, and File.ReadAllText: string –&amp;gt; string, returns a value T that can be wrapped IO&amp;lt;T&amp;gt;. There are other I/O operations that return void, like Console.WriteLine: string –&amp;gt; void, etc. Since C# compiler does not allow void to be used as type argument of IO&amp;lt;void&amp;gt;, these operations can be viewed as returning a Unit value, which can be wrapped as IO&amp;lt;Uint&amp;gt;. The following methods help wrap IO&amp;lt;T&amp;gt; functions from I/O operations with or without return value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IO&amp;lt;TResult&amp;gt; IO&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; function) =&amp;gt;
    () =&amp;gt; function();

public static IO&amp;lt;Unit&amp;gt; IO(Action action) =&amp;gt;
    () =&amp;gt;
    {
        action();
        return default;
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the I/O workflow can be build as purely function LINQ query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    IO&amp;lt;int&amp;gt; query = from unit1 in IO(() =&amp;gt; Console.WriteLine(&quot;File path:&quot;)) // IO&amp;lt;Unit&amp;gt;.
                    from filePath in IO(Console.ReadLine) // IO&amp;lt;string&amp;gt;.
                    from unit2 in IO(() =&amp;gt; Console.WriteLine(&quot;File encoding:&quot;)) // IO&amp;lt;Unit&amp;gt;.
                    from encodingName in IO(Console.ReadLine) // IO&amp;lt;string&amp;gt;.
                    let encoding = Encoding.GetEncoding(encodingName)
                    from fileContent in IO(() =&amp;gt; File.ReadAllText(filePath, encoding)) // IO&amp;lt;string&amp;gt;.
                    from unit3 in IO(() =&amp;gt; Console.WriteLine(&quot;File content:&quot;)) // IO&amp;lt;Unit&amp;gt;.
                    from unit4 in IO(() =&amp;gt; Console.WriteLine(fileContent)) // IO&amp;lt;Unit&amp;gt;.
                    select fileContent.Length; // Define query.
    int result = query(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IO&amp;lt;&amp;gt; monad works with both synchronous and asynchronous I/O operations. The async version of IO&amp;lt;T&amp;gt; is just IO&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;, and the async version of IO&amp;lt;Unit&amp;gt; is just IO&amp;lt;Task&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task WorkflowAsync()
{
    using (HttpClient httpClient = new HttpClient())
    {
        IO&amp;lt;Task&amp;gt; query = from unit1 in IO(() =&amp;gt; Console.WriteLine(&quot;URI:&quot;)) // IO&amp;lt;Unit&amp;gt;. 
                            from uri in IO(Console.ReadLine) // IO&amp;lt;string&amp;gt;.
                            from unit2 in IO(() =&amp;gt; Console.WriteLine(&quot;File path:&quot;)) // IO&amp;lt;Unit&amp;gt;.
                            from filePath in IO(Console.ReadLine) // IO&amp;lt;string&amp;gt;.
                            from downloadStreamTask in IO(async () =&amp;gt;
                                await httpClient.GetStreamAsync(uri)) // IO&amp;lt;Task&amp;lt;Stream&amp;gt;&amp;gt;.
                            from writeFileTask in IO(async () =&amp;gt; 
                                await (await downloadStreamTask).CopyToAsync(File.Create(filePath))) // IO&amp;lt;Task&amp;gt;.
                            from messageTask in IO(async () =&amp;gt;
                                {
                                    await writeFileTask;
                                    Console.WriteLine($&quot;Downloaded {uri} to {filePath}&quot;);
                                }) // IO&amp;lt;Task&amp;gt;.
                            select messageTask; // Define query.
        await query(); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;State monad&lt;/h2&gt;
&lt;p&gt;In object-oriented programming, there is the state pattern to handle state changes. In functional programming, state change can be modeled with pure function. For pure function TSource –&amp;gt; TResult, its state-involved version can be represented as a Tuple&amp;lt;TSource, TState&amp;gt; –&amp;gt; Tuple&amp;lt;TResult, TState&amp;gt; function, which accepts some input value along with some input state, and returns some output value and some output state. This function can remains pure, because it can leave the input state unchanged, then either return the same old state, or create a new state and return it. To make this function monadic, break up the input tuple and curry the function to TSource –&amp;gt; (TState –&amp;gt; Tuple&amp;lt;TResult, TState&amp;gt;). Now the returned TState –&amp;gt; Tuple&amp;lt;TResult, TState&amp;gt; function type can be given an alias called State:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// State: TState -&amp;gt; ValueTuple&amp;lt;T, TState&amp;gt;
public delegate (T Value, TState State) State&amp;lt;TState, T&amp;gt;(TState state);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to fore mentioned Tuple&amp;lt;,&amp;gt; and Func&amp;lt;,&amp;gt; types, the above open generic type State&amp;lt;,&amp;gt; can be viewed as a type constructor of kind * –&amp;gt; * –&amp;gt; *. After partially applied with a first type argument TState, State&amp;lt;TState,&amp;gt; becomes a * –&amp;gt; * type constructor. If it can be a functor and monad, then above stateful function becomes a monadic selector TSource –&amp;gt; State&amp;lt;TState, TResult&amp;gt;. So the following (SelectMany, Wrap, Select) methods can be defined for State&amp;lt;TState,&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class StateExtensions
{
    // SelectMany: (State&amp;lt;TState, TSource&amp;gt;, TSource -&amp;gt; State&amp;lt;TState, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; State&amp;lt;TState, TResult&amp;gt;
    public static State&amp;lt;TState, TResult&amp;gt; SelectMany&amp;lt;TState, TSource, TSelector, TResult&amp;gt;(
        this State&amp;lt;TState, TSource&amp;gt; source,
        Func&amp;lt;TSource, State&amp;lt;TState, TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            oldState =&amp;gt;
            {
                (TSource Value, TState State) value = source(oldState);
                (TSelector Value, TState State) result = selector(value.Value)(value.State);
                TState newState = result.State;
                return (resultSelector(value.Value, result.Value), newState); // Output new state.
            };

    // Wrap: TSource -&amp;gt; State&amp;lt;TState, TSource&amp;gt;
    public static State&amp;lt;TState, TSource&amp;gt; State&amp;lt;TState, TSource&amp;gt;(this TSource value) =&amp;gt;
        oldState =&amp;gt; (value, oldState); // Output old state.

    // Select: (State&amp;lt;TState, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; State&amp;lt;TState, TResult&amp;gt;
    public static State&amp;lt;TState, TResult&amp;gt; Select&amp;lt;TState, TSource, TResult&amp;gt;(
        this State&amp;lt;TState, TSource&amp;gt; source,
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            oldState =&amp;gt;
            {
                (TSource Value, TState State) value = source(oldState);
                TState newState = value.State;
                return (selector(value.Value), newState); // Output new state.
            };
            // Equivalent to:            
            // source.SelectMany(value =&amp;gt; selector(value).State&amp;lt;TState, TResult&amp;gt;(), (value, result) =&amp;gt; result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SelectMany and Select return a function that accepts an old state and outputs new state, State method returns a function that outputs the old state. Now this State&amp;lt;TState,&amp;gt; delegate type is the state monad, so a State&amp;lt;TState, T&amp;gt; function can be viewed as a wrapper of a T value, and this T value can be unwrapped in the monad workflow, with the from value in source syntax. State&amp;lt;TState, T&amp;gt; function also wraps the state information. To get/set the TState state in the monad workflow, the following GetState/SetState functions can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// GetState: () -&amp;gt; State&amp;lt;TState, TState&amp;gt;
public static State&amp;lt;TState, TState&amp;gt; GetState&amp;lt;TState&amp;gt;() =&amp;gt;
    oldState =&amp;gt; (oldState, oldState); // Output old state.

// SetState: TState -&amp;gt; State&amp;lt;TState, Unit&amp;gt;
public static State&amp;lt;TState, Unit&amp;gt; SetState&amp;lt;TState&amp;gt;(TState newState) =&amp;gt;
    oldState =&amp;gt; (default, newState); // Output new state.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here GetState returns a State&amp;lt;TState, TState&amp;gt; function wrapping the state as value, so that the state can be extracted in the monad workflow with the same syntax that unwraps the value. SetState returns a State&amp;lt;TState, Unit&amp;gt; function, which ignores the old state, and wrap no value (represented by Unit) and outputs the the specified new value to the monad workflow. Generally, the state monad workflow can be demonstrated as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    string initialState = nameof(initialState);
    string newState = nameof(newState);
    string resetState = nameof(resetState);
    State&amp;lt;string, int&amp;gt; source1 = oldState =&amp;gt; (1, oldState);
    State&amp;lt;string, bool&amp;gt; source2 = oldState =&amp;gt; (true, newState);
    State&amp;lt;string, char&amp;gt; source3 = &apos;@&apos;.State&amp;lt;string, char&amp;gt;(); // oldState =&amp;gt; 2, oldState).

    State&amp;lt;string, string[]&amp;gt; query =
        from value1 in source1 // source1: State&amp;lt;string, int&amp;gt; = initialState =&amp;gt; (1, initialState).
        from state1 in GetState&amp;lt;string&amp;gt;() // GetState&amp;lt;int&amp;gt;(): State&amp;lt;string, string&amp;gt; = initialState =&amp;gt; (initialState, initialState).
        from value2 in source2 // source2: State&amp;lt;string, bool&amp;gt;3 = initialState =&amp;gt; (true, newState).
        from state2 in GetState&amp;lt;string&amp;gt;() // GetState&amp;lt;int&amp;gt;(): State&amp;lt;string, string&amp;gt; = newState =&amp;gt; (newState, newState).
        from unit in SetState(resetState) // SetState(resetState): State&amp;lt;string, Unit&amp;gt; = newState =&amp;gt; (default, resetState).
        from state3 in GetState&amp;lt;string&amp;gt;() // GetState(): State&amp;lt;string, string&amp;gt; = resetState =&amp;gt; (resetState, resetState).
        from value3 in source3 // source3: State&amp;lt;string, char&amp;gt; = resetState =&amp;gt; (@, resetState).
        select new string[] { state1, state2, state3 }; // Define query.
    (string[] Value, string State) result = query(initialState); // Execute query with initial state.
    result.Value.WriteLines(); // initialState newState resetState
    result.State.WriteLine(); // Final state: resetState
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The state monad workflow is a State&amp;lt;TState, T&amp;gt; function, which is of type TState –&amp;gt; Tuple&amp;lt;T, TState&amp;gt;. To execute the workflow, it must be called with a TState initial state. At runtime, when the workflow executes, the first operation in the workflow, also a TState –&amp;gt; Tuple&amp;lt;T, TState&amp;gt; function, is called with the workflow’s initial state, and returns a output value and a output state; then the second operation, once again another TState –&amp;gt; Tuple&amp;lt;T, TState&amp;gt; function, is called with the first operation’s output state, and outputs another output value and another output state; and so on. In this chaining, each operation function can wither return its original input state, or return a new state. This is how state changes through a workflow of pure functions.&lt;/p&gt;
&lt;p&gt;Take the factorial function as example. The factorial function can be viewed as a recursive function with a state – the current product of the current recursion step, and apparently take the initial state (product) is 1. To calculate the factorial of 5, the recursive steps can be modeled as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(Value: 5, State: 1) =&amp;gt; (Value: 4, State: 1 * 5)&lt;/li&gt;
&lt;li&gt;(Value: 4, State: 1 * 5) =&amp;gt; (Value: 3, State: 1 * 5 * 4)&lt;/li&gt;
&lt;li&gt;(Value: 3, State: 1 * 5 * 4) =&amp;gt; (Value: 3, State: 1 * 5 * 4)&lt;/li&gt;
&lt;li&gt;(Value: 2, State: 1 * 5 * 4 * 3) =&amp;gt; (Value: 2, State: 1 * 5 * 4 * 3)&lt;/li&gt;
&lt;li&gt;(Value: 1, State: 1 * 5 * 4 * 3 * 2) =&amp;gt; (Value: 1, State: 1 * 5 * 4 * 3 * 2)&lt;/li&gt;
&lt;li&gt;(Value: 0, State: 1 * 5 * 4 * 3 * 2 * 1) =&amp;gt; (Value: 0, State: 1 * 5 * 4 * 3 * 2 * 1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the current integer becomes 0, the recursion terminates, and the final state (product) is the factorial result. So this recursive function is of type Tuple&amp;lt;int, int&amp;gt; –&amp;gt; Tuple&amp;lt;int, int&amp;gt;. As fore mentioned, it can be curried to int –&amp;gt; (int –&amp;gt; Tuple&amp;lt;int, int&amp;gt;), which is equivalent to int –&amp;gt; State&amp;lt;int, int&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// FactorialState: uint -&amp;gt; (uint -&amp;gt; (uint, uint))
// FactorialState: uint -&amp;gt; State&amp;lt;unit, uint&amp;gt;
private static State&amp;lt;uint, uint&amp;gt; FactorialState(uint current) =&amp;gt;
    from state in GetState&amp;lt;uint&amp;gt;() // State&amp;lt;uint, uint&amp;gt;.
    let product = state
    let next = current - 1U
    from result in current &amp;gt; 0U
        ? (from unit in SetState(product * current) // State&amp;lt;unit, Unit&amp;gt;.
            from value in FactorialState(next) // State&amp;lt;uint, uint&amp;gt;.
            select next)
        : next.State&amp;lt;uint, uint&amp;gt;() // State&amp;lt;uint, uint&amp;gt;.
    select result;

public static uint Factorial(uint uInt32)
{
    State&amp;lt;uint, uint&amp;gt; query = FactorialState(uInt32); // Define query.
    return query(1).State; // Execute query, with initial state: 1.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is Enumerable.Aggregate query method, which accepts an IEnumerable&amp;lt;TSource&amp;gt; sequence, a TAccumulate seed, and a TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate function. Aggregate calls the accumulation function over the seed and all the values in the sequence. The aggregation steps can also be modeled as recursive steps, where each step’s state is the current accumulate result and the unused source values. Take source sequence { 1, 2, 3, 4, 5 }, seed 0, and function + as example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(Value: +, State: (0, { 1, 2, 3, 4 })) =&amp;gt; (Value: +, State: (0 + 1, { 2, 3, 4 }))&lt;/li&gt;
&lt;li&gt;(Value: +, State: (0 + 1, { 2, 3, 4 })) =&amp;gt; (Value: +, State: (0 + 1 + 2, { 3, 4 }))&lt;/li&gt;
&lt;li&gt;(Value: +, State: (0 + 1 + 2, { 3, 4 })) =&amp;gt; (Value: +, State: (0 + 1 + 2 + 3, { 4 }))&lt;/li&gt;
&lt;li&gt;(Value: +, State: (0 + 1 + 2 + 3, { 4 })) =&amp;gt; (Value: +, State: (0 + 1 + 2 + 3 + 4, { }))&lt;/li&gt;
&lt;li&gt;(Value: +, State: (0 + 1 + 2 + 3 + 4, { })) =&amp;gt; (Value: +, State: (0 + 1 + 2 + 3 + 4, { }))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the current source sequence in the state is empty, all source values are applied to the accumulate function, the recursion terminates, and the aggregation result in in the final state. So the recursive function is of type Tuple&amp;lt;TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate, Tuple&amp;lt;TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;&amp;gt; –&amp;gt; Tuple&amp;lt;TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate, Tuple&amp;lt;TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;&amp;gt;. Again, it can be curried to (TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate) –&amp;gt; (Tuple&amp;lt;TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; –&amp;gt; Tuple&amp;lt;TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate, Tuple&amp;lt;TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;&amp;gt;), which is equivalent to (TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate) –&amp;gt; State&amp;lt;Tuple&amp;lt;TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;, TAccumulate –&amp;gt; TSource –&amp;gt; TAccumulate&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// AggregateState: (TAccumulate -&amp;gt; TSource -&amp;gt; TAccumulate) -&amp;gt; ((TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;) -&amp;gt; (TAccumulate -&amp;gt; TSource -&amp;gt; TAccumulate, (TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;)))
// AggregateState: TAccumulate -&amp;gt; TSource -&amp;gt; TAccumulate -&amp;gt; State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), TAccumulate -&amp;gt; TSource -&amp;gt; TAccumulate&amp;gt;
private static State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;&amp;gt; AggregateState&amp;lt;TSource, TAccumulate&amp;gt;(
    Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func) =&amp;gt;
        from state in GetState&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;)&amp;gt;() // State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), (TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;)&amp;gt;.
        let accumulate = state.Item1 // TAccumulate.
        let source = state.Item2.Share() // IBuffer&amp;lt;TSource&amp;gt;.
        let sourceIterator = source.GetEnumerator() // IEnumerator&amp;lt;TSource&amp;gt;.
        from result in sourceIterator.MoveNext()
            ? (from unit in SetState((func(accumulate, sourceIterator.Current), source.AsEnumerable())) // State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Unit&amp;gt;.
                from value in AggregateState(func) // State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;&amp;gt;.
                select func)
            : func.State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;&amp;gt;() // State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;&amp;gt;.
        select result;

public static TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func)
{
    State&amp;lt;(TAccumulate, IEnumerable&amp;lt;TSource&amp;gt;), Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;&amp;gt; query =
        AggregateState(func); // Define query.
    return query((seed, source)).State.Item1; // Execute query, with initial state (seed, source).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In each recursion step, if the source sequence in the current state in not empty, the source sequence needs to be split. The first value is used to call the accumulation function, and the other values are put into output state, which is passed to the next recursion step. So there are multiple pulling operations for the source sequence: detecting if it is empty detection, pulling first value, and pulling the rest values. To avoid multiple iterations for the same source sequence, here the Share query method from Microsoft Ix (Interactive Extensions) library is called, so that all the pulling operations share the same iterator.&lt;/p&gt;
&lt;p&gt;The stack’s Pop and Push operation can be also viewed as state processing. The Pop method of stack requires no input, and out put the stack’s top value T, So Pop can be viewed of type Unit –&amp;gt; T. In contrast, stack’s Push method accepts a value, set the value to the top of the stack, and returns no output, so Push can be viewed of type T –&amp;gt; Unit. The stack’s values are different before and after the Pop and Push operations, so the stack itself can be viewed as the state of the Pop and Push operation. If the values in a stack is represented as a IEnumerable&amp;lt;T&amp;gt; sequence, then Pop can be remodeled as Tuple&amp;lt;Unit, IEnumerable&amp;lt;T&amp;gt;&amp;gt; –&amp;gt; Tuple&amp;lt;Unit, IEnumerable&amp;lt;T&amp;gt;&amp;gt;, which can be curried to Unit –&amp;gt; State&amp;lt;IEnumerable&amp;lt;T&amp;gt;, T&amp;gt;; and Push can be remodeled as Tuple&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; –&amp;gt; Tuple&amp;lt;Unit, IEnumerable&amp;lt;T&amp;gt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// PopState: Unit -&amp;gt; (IEnumerable&amp;lt;T&amp;gt; -&amp;gt; (T, IEnumerable&amp;lt;T&amp;gt;))
// PopState: Unit -&amp;gt; State&amp;lt;IEnumerable&amp;lt;T&amp;gt;, T&amp;gt;
internal static State&amp;lt;IEnumerable&amp;lt;T&amp;gt;, T&amp;gt; PopState&amp;lt;T&amp;gt;(Unit unit = null) =&amp;gt;
    oldStack =&amp;gt;
    {
        IEnumerable&amp;lt;T&amp;gt; newStack = oldStack.Share();
        return (newStack.First(), newStack); // Output new state.
    };

// PushState: T -&amp;gt; (IEnumerable&amp;lt;T&amp;gt; -&amp;gt; (Unit, IEnumerable&amp;lt;T&amp;gt;))
// PushState: T -&amp;gt; State&amp;lt;IEnumerable&amp;lt;T&amp;gt;, Unit&amp;gt;
internal static State&amp;lt;IEnumerable&amp;lt;T&amp;gt;, Unit&amp;gt; PushState&amp;lt;T&amp;gt;(T value) =&amp;gt;
    oldStack =&amp;gt;
    {
        IEnumerable&amp;lt;T&amp;gt; newStack = oldStack.Concat(value.Enumerable());
        return (default, newStack); // Output new state.
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the stack operations can be a state monad workflow. Also, GetState can get the current values of the stack, and SetState can reset the values of stack:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Stack()
{
    IEnumerable&amp;lt;int&amp;gt; initialStack = Enumerable.Repeat(0, 5);
    State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; query =
        from value1 in PopState&amp;lt;int&amp;gt;() // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, int&amp;gt;.
        from unit1 in PushState(1) // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, Unit&amp;gt;.
        from unit2 in PushState(2) // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, Unit&amp;gt;.
        from stack in GetState&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt;() // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt;.
        from unit3 in SetState(Enumerable.Range(0, 5)) // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, Unit&amp;gt;.
        from value2 in PopState&amp;lt;int&amp;gt;() // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, int&amp;gt;.
        from value3 in PopState&amp;lt;int&amp;gt;() // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, int&amp;gt;.
        from unit4 in PushState(5) // State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, Unit&amp;gt;.
        select stack; // Define query.
    (IEnumerable&amp;lt;int&amp;gt; Value, IEnumerable&amp;lt;int&amp;gt; State) result = query(initialStack); // Execute query with initial state.
    result.Value.WriteLines(); // 0 0 0 0 1 2
    result.State.WriteLines(); // 0 1 2 5
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Exception monad&lt;/h2&gt;
&lt;p&gt;As previously demonstrated, the Optional&amp;lt;&amp;gt; monad can handle the case that any operation of the workflow may not produce a valid result, in a . When an operation succeeds to return a valid result, the next operation executes. If all operations succeed, the entire workflow has a valid result. Option&amp;lt;&amp;gt; monad’s handling is based on operation’s return result. What if the operation fails with exception? To work with operation exceptions in a purely functional paradigm, the following Try&amp;lt;&amp;gt; structure can be defined, which is just Optional&amp;lt;&amp;gt; plus exception handling and store:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public readonly struct Try&amp;lt;T&amp;gt;
{
    private readonly Lazy&amp;lt;(T, Exception)&amp;gt; factory;

    public Try(Func&amp;lt;(T, Exception)&amp;gt; factory) =&amp;gt;
        this.factory = new Lazy&amp;lt;(T, Exception)&amp;gt;(() =&amp;gt;
        {
            try
            {
                return factory();
            }
            catch (Exception exception)
            {
                return (default, exception);
            }
        });

    public T Value
    {
        get
        {
            if (this.HasException)
            {
                throw new InvalidOperationException($&quot;{nameof(Try&amp;lt;T&amp;gt;)} object must have a value.&quot;);
            }
            return this.factory.Value.Item1;
        }
    }

    public Exception Exception =&amp;gt; this.factory.Value.Item2;

    public bool HasException =&amp;gt; this.Exception != null;

    public static implicit operator Try&amp;lt;T&amp;gt;(T value) =&amp;gt; new Try&amp;lt;T&amp;gt;(() =&amp;gt; (value, (Exception)null));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Try&amp;lt;T&amp;gt; represents an operation, which either succeeds with a result, or fail with an exception. Its SelectMany method is also in the same pattern as Optional&amp;lt;&amp;gt;’s SelectMany, so that when an operation (source) succeeds without exception, the next operation (returned by selector) executes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TryExtensions
{
    // SelectMany: (Try&amp;lt;TSource&amp;gt;, TSource -&amp;gt; Try&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Try&amp;lt;TResult&amp;gt;
    public static Try&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this Try&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, Try&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            new Try&amp;lt;TResult&amp;gt;(() =&amp;gt;
            {
                if (source.HasException)
                {
                    return (default, source.Exception);
                }
                Try&amp;lt;TSelector&amp;gt; result = selector(source.Value);
                if (result.HasException)
                {
                    return (default, result.Exception);
                }
                return (resultSelector(source.Value, result.Value), (Exception)null);
            });

    // Wrap: TSource -&amp;gt; Try&amp;lt;TSource&amp;gt;
    public static Try&amp;lt;TSource&amp;gt; Try&amp;lt;TSource&amp;gt;(this TSource value) =&amp;gt; value;

    // Select: (Try&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Try&amp;lt;TResult&amp;gt;
    public static Try&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this Try&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).Try(), (value, result) =&amp;gt; result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The operation of throwing an exception can be represented with a Try&amp;lt;T&amp;gt; with the specified exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Try&amp;lt;T&amp;gt; Throw&amp;lt;T&amp;gt;(this Exception exception) =&amp;gt; new Try&amp;lt;T&amp;gt;(() =&amp;gt; (default, exception));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For convenience, Try&amp;lt;T&amp;gt; instance can be implicitly wrapped from a T value. And the following method also helps wrap a Func&amp;lt;T&amp;gt; operation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Try&amp;lt;T&amp;gt; Try&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; function) =&amp;gt;
    new Try&amp;lt;T&amp;gt;(() =&amp;gt; (function(), (Exception)null));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to IO&amp;lt;&amp;gt; monad, an function operation (() –&amp;gt; void) without return result can be viewed as a function returning Unit (() –&amp;gt; Unit):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Try&amp;lt;Unit&amp;gt; Try(Action action) =&amp;gt;
    new Try&amp;lt;Unit&amp;gt;(() =&amp;gt;
    {
        action();
        return (default, (Exception)null);
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To handle the exception from an operation represented by Try&amp;lt;T&amp;gt;, just check the HasException property, filter the exception, and process it. The following Catch method handles the specified exception type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Try&amp;lt;T&amp;gt; Catch&amp;lt;T, TException&amp;gt;(
    this Try&amp;lt;T&amp;gt; source, Func&amp;lt;TException, Try&amp;lt;T&amp;gt;&amp;gt; handler, Func&amp;lt;TException, bool&amp;gt; when = null)
    where TException : Exception =&amp;gt; 
        new Try&amp;lt;T&amp;gt;(() =&amp;gt;
        {
            if (source.HasException &amp;amp;&amp;amp; source.Exception is TException exception &amp;amp;&amp;amp; exception != null
                &amp;amp;&amp;amp; (when == null || when(exception)))
            {
                source = handler(exception);
            }
            return source.HasException ? (default, source.Exception) : (source.Value, (Exception)null);
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The evaluation of the Try&amp;lt;T&amp;gt; source, and the execution of handler, are both deferred. And the following Catch overload handles all exception types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Try&amp;lt;T&amp;gt; Catch&amp;lt;T&amp;gt;(
    this Try&amp;lt;T&amp;gt; source, Func&amp;lt;Exception, Try&amp;lt;T&amp;gt;&amp;gt; handler, Func&amp;lt;Exception, bool&amp;gt; when = null) =&amp;gt;
        Catch&amp;lt;T, Exception&amp;gt;(source, handler, when);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the Finally method just call a function to process the Try&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TResult Finally&amp;lt;T, TResult&amp;gt;(
    this Try&amp;lt;T&amp;gt; source, Func&amp;lt;Try&amp;lt;T&amp;gt;, TResult&amp;gt; finally) =&amp;gt; finally(source);

public static void Finally&amp;lt;T&amp;gt;(
    this Try&amp;lt;T&amp;gt; source, Action&amp;lt;Try&amp;lt;T&amp;gt;&amp;gt; finally) =&amp;gt; finally(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The operation of throwing an exception can be represented with a Try&amp;lt;T&amp;gt; instance wrapping the specified exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TryExtensions
{
    public static Try&amp;lt;T&amp;gt; Throw&amp;lt;T&amp;gt;(this Exception exception) =&amp;gt; new Try&amp;lt;T&amp;gt;(() =&amp;gt; (default, exception));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is an example of throwing exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Try&amp;lt;int&amp;gt; TryStrictFactorial(int? value)
{
    if (value == null)
    {
        return Throw&amp;lt;int&amp;gt;(new ArgumentNullException(nameof(value)));
    }
    if (value &amp;lt;= 0)
    {
        return Throw&amp;lt;int&amp;gt;(new ArgumentOutOfRangeException(nameof(value), value, &quot;Argument should be positive.&quot;));
    }

    if (value == 1)
    {
        return 1;
    }
    return value.Value * TryStrictFactorial(value - 1).Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the the following is an example of handling exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static string Factorial(string value)
{
    Func&amp;lt;string, int?&amp;gt; stringToNullableInt32 = @string =&amp;gt;
        string.IsNullOrEmpty(@string) ? default : Convert.ToInt32(@string);
    Try&amp;lt;int&amp;gt; query = from nullableInt32 in Try(() =&amp;gt; stringToNullableInt32(value)) // Try&amp;lt;int32?&amp;gt;
                        from result in TryStrictFactorial(nullableInt32) // Try&amp;lt;int&amp;gt;.
                        from unit in Try(() =&amp;gt; result.WriteLine()) // Try&amp;lt;Unit&amp;gt;.
                        select result; // Define query.
    return query
        .Catch(exception =&amp;gt; // Catch all and rethrow.
        {
            exception.WriteLine();
            return Throw&amp;lt;int&amp;gt;(exception);
        })
        .Catch&amp;lt;int, ArgumentNullException&amp;gt;(exception =&amp;gt; 1) // When argument is null, factorial is 1.
        .Catch&amp;lt;int, ArgumentOutOfRangeException&amp;gt;(
            when: exception =&amp;gt; object.Equals(exception.ActualValue, 0),
            handler: exception =&amp;gt; 1) // When argument is 0, factorial is 1.
        .Finally(result =&amp;gt; result.HasException // Execute query.
            ? result.Exception.Message : result.Value.ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reader monad&lt;/h2&gt;
&lt;p&gt;The Func&amp;lt;T,&amp;gt; functor is also monad. In contrast to Func&amp;lt;&amp;gt; monad, a factory function that only outputs a value, Func&amp;lt;T,&amp;gt; can also read input value from the environment. So Fun&amp;lt;T,&amp;gt; monad is also called reader monad, or environment monad. To be intuitive, rename Func&amp;lt;T,&amp;gt; to Reader&amp;lt;TEnvironment,&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Reader: TEnvironment -&amp;gt; T
public delegate T Reader&amp;lt;in TEnvironment, out T&amp;gt;(TEnvironment environment);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And its (SelectMany, Wrap, Select) methods are straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReaderExtensions
{
    // SelectMany: (Reader&amp;lt;TEnvironment, TSource&amp;gt;, TSource -&amp;gt; Reader&amp;lt;TEnvironment, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Reader&amp;lt;TEnvironment, TResult&amp;gt;
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; SelectMany&amp;lt;TEnvironment, TSource, TSelector, TResult&amp;gt;(
        this Reader&amp;lt;TEnvironment, TSource&amp;gt; source,
        Func&amp;lt;TSource, Reader&amp;lt;TEnvironment, TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            environment =&amp;gt;
            {
                TSource value = source(environment);
                return resultSelector(value, selector(value)(environment));
            };

    // Wrap: TSource -&amp;gt; Reader&amp;lt;TEnvironment, TSource&amp;gt;
    public static Reader&amp;lt;TEnvironment, TSource&amp;gt; Reader&amp;lt;TEnvironment, TSource&amp;gt;(this TSource value) =&amp;gt; 
        environment =&amp;gt; value;

    // Select: (Reader&amp;lt;TEnvironment, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Reader&amp;lt;TEnvironment, TResult&amp;gt;
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; Select&amp;lt;TEnvironment, TSource, TResult&amp;gt;(
        this Reader&amp;lt;TEnvironment, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).Reader&amp;lt;TEnvironment, TResult&amp;gt;(), (value, result) =&amp;gt; result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are scenarios of accessing input value from shared environment, like reading the configurations, dependency injection, etc. In the following example, the operations are dependents of the configurations, so these operations can be modeled using Reader&amp;lt;ICongiguration,&amp;gt; monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Reader&amp;lt;IConfiguration, FileInfo&amp;gt; DownloadHtml(Uri uri) =&amp;gt;
    configuration =&amp;gt; default;

private static Reader&amp;lt;IConfiguration, FileInfo&amp;gt; ConverToWord(FileInfo htmlDocument, FileInfo template) =&amp;gt;
    configuration =&amp;gt; default;

private static Reader&amp;lt;IConfiguration, Unit&amp;gt; UploadToOneDrive(FileInfo file) =&amp;gt;
    configuration =&amp;gt; default;

internal static void Workflow(IConfiguration configuration, Uri uri, FileInfo template)
{
    Reader&amp;lt;IConfiguration, (FileInfo, FileInfo)&amp;gt; query =
        from htmlDocument in DownloadHtml(uri) // Reader&amp;lt;IConfiguration, FileInfo&amp;gt;.
        from wordDocument in ConverToWord(htmlDocument, template) // Reader&amp;lt;IConfiguration, FileInfo&amp;gt;.
        from unit in UploadToOneDrive(wordDocument) // Reader&amp;lt;IConfiguration, Unit&amp;gt;.
        select (htmlDocument, wordDocument); // Define query.
    (FileInfo, FileInfo) result = query(configuration); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The workflow is also a Reader&amp;lt;ICongiguration, T&amp;gt; function. To execute the workflow, it must read the required configuration input. Then all operation in the workflow execute sequentially by reading the same configuration input.&lt;/p&gt;
&lt;h2&gt;Writer monad&lt;/h2&gt;
&lt;p&gt;Writer is a function that returns a computed value along with a stream of additional content, so this function is of type () –&amp;gt; Tuple&amp;lt;T, TContent&amp;gt;. In the writer monad workflow, each operation’s additional output content is merged with the next operation’s additional output content, so that when the entire workflow is executed, all operations’ additional output content are merged as the workflow’s final additional output content. Each merge operation accepts 2 TContent instances, and result another TContent instance. It is a binary operation and can be implemented by monoid’s multiplication: TContent ⊙ TContent –&amp;gt; TContent. So writer can be represented by a () –&amp;gt; Tuple&amp;lt;T, TContent&amp;gt; function along with a IMonoid&amp;lt;TContent&amp;gt; monoid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class WriterBase&amp;lt;TContent, T, TContentMonoid&amp;gt; : IMonoid&amp;lt;TContent&amp;gt; where TContentMonoid : IMonoid&amp;lt;TContent&amp;gt;
{
    private readonly Lazy&amp;lt;(TContent, T)&amp;gt; lazy;

    protected WriterBase(Func&amp;lt;(TContent, T)&amp;gt; writer)
    {
        this.lazy = new Lazy&amp;lt;(TContent, T)&amp;gt;(writer);
    }

    public TContent Content =&amp;gt; this.lazy.Value.Item1;

    public T Value =&amp;gt; this.lazy.Value.Item2;

    public static TContent Multiply(TContent value1, TContent value2) =&amp;gt; TContentMonoid.Multiply(value1, value2);

    public static TContent Unit =&amp;gt; TContentMonoid.Unit;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The most common scenario of outputting additional content, is tracing and logging, where the TContent is a sequence of log entries. A sequence of log entries can be represented as IEnumerable&amp;lt;T&amp;gt;, so the fore mentioned (IEnumerable&amp;lt;T&amp;gt;, Enumerable.Concat&amp;lt;T&amp;gt;, Enumerable.Empty&amp;lt;T&amp;gt;()) monoid can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Writer&amp;lt;TEntry, T&amp;gt; : WriterBase&amp;lt;IEnumerable&amp;lt;TEntry&amp;gt;, T, EnumerableConcatMonoid&amp;lt;TEntry&amp;gt;&amp;gt;
{
    public Writer(Func&amp;lt;(IEnumerable&amp;lt;TEntry&amp;gt;, T)&amp;gt; writer) : base(writer) { }

    public Writer(T value) : base(() =&amp;gt; (Unit, value)) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to State&amp;lt;TState,&amp;gt; and Reader&amp;lt;TEnvironment,&amp;gt;, here Writer&amp;lt;TEntry,&amp;gt; can be monad with the following (SelectMany, Wrap, Select) methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class WriterExtensions
{
    // SelectMany: (Writer&amp;lt;TEntry, TSource&amp;gt;, TSource -&amp;gt; Writer&amp;lt;TEntry, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Writer&amp;lt;TEntry, TResult&amp;gt;
    public static Writer&amp;lt;TEntry, TResult&amp;gt; SelectMany&amp;lt;TEntry, TSource, TSelector, TResult&amp;gt;(
        this Writer&amp;lt;TEntry, TSource&amp;gt; source,
        Func&amp;lt;TSource, Writer&amp;lt;TEntry, TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            new Writer&amp;lt;TEntry, TResult&amp;gt;(() =&amp;gt;
            {
                Writer&amp;lt;TEntry, TSelector&amp;gt; result = selector(source.Value);
                return (Tutorial.CategoryTheory.Writer&amp;lt;TEntry, TSource&amp;gt;.Multiply(source.Content, result.Content),
                    resultSelector(source.Value, result.Value));
            });

    // Wrap: TSource -&amp;gt; Writer&amp;lt;TEntry, TSource&amp;gt;
    public static Writer&amp;lt;TEntry, TSource&amp;gt; Writer&amp;lt;TEntry, TSource&amp;gt;(this TSource value) =&amp;gt;
        new Writer&amp;lt;TEntry, TSource&amp;gt;(value);

    // Select: (Writer&amp;lt;TEnvironment, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Writer&amp;lt;TEnvironment, TResult&amp;gt;
    public static Writer&amp;lt;TEntry, TResult&amp;gt; Select&amp;lt;TEntry, TSource, TResult&amp;gt;(
        this Writer&amp;lt;TEntry, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).Writer&amp;lt;TEntry, TResult&amp;gt;(), (value, result) =&amp;gt; result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most commonly, each operation in the workflow logs string message. So the following method is defined to construct a writer instance from a value and a string log factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Writer&amp;lt;string, TSource&amp;gt; LogWriter&amp;lt;TSource&amp;gt;(this TSource value, Func&amp;lt;TSource, string&amp;gt; logFactory) =&amp;gt;
    new Writer&amp;lt;string, TSource&amp;gt;(() =&amp;gt; (logFactory(value).Enumerable(), value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The previous Fun&amp;lt;&amp;gt; monad workflow now can output logs for each operation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    Writer&amp;lt;string, string&amp;gt; query = from filePath in Console.ReadLine().LogWriter(value =&amp;gt;
                                        $&quot;File path: {value}&quot;) // Writer&amp;lt;string, string&amp;gt;.
                                   from encodingName in Console.ReadLine().LogWriter(value =&amp;gt;
                                        $&quot;Encoding name: {value}&quot;) // Writer&amp;lt;string, string&amp;gt;.
                                   from encoding in Encoding.GetEncoding(encodingName).LogWriter(value =&amp;gt;
                                        $&quot;Encoding: {value}&quot;) // Writer&amp;lt;string, Encoding&amp;gt;.
                                   from fileContent in File.ReadAllText(filePath, encoding).LogWriter(value =&amp;gt;
                                        $&quot;File content length: {value.Length}&quot;) // Writer&amp;lt;string, string&amp;gt;.
                                   select fileContent; // Define query.
    string result = query.Value; // Execute query.
    query.Content.WriteLines();
    // File path: D:\File.txt
    // Encoding name: utf-8
    // Encoding: System.Text.UTF8Encoding
    // File content length: 76138
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Continuation monad&lt;/h2&gt;
&lt;p&gt;In program, a function can return the result value, so that some other continuation function can use that value; or a function can take a continuation function as parameter, after it computes the result value, it calls back the continuation function with that value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class CpsExtensions
{
    // Sqrt: int -&amp;gt; double
    internal static double Sqrt(int int32) =&amp;gt; Math.Sqrt(int32);

    // SqrtWithCallback: (int, double -&amp;gt; TContinuation) -&amp;gt; TContinuation
    internal static TContinuation SqrtWithCallback&amp;lt;TContinuation&amp;gt;(
        int int32, Func&amp;lt;double, TContinuation&amp;gt; continuation) =&amp;gt;
            continuation(Math.Sqrt(int32));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The former is style is called direct style, and the latter is called continuation-passing style (CPS). Generally, for a TSource –&amp;gt; TResult function, its CPS version can accept a TResult –&amp;gt; TContinuation continuation function, so the CPS function is of type (TSource, TResult –&amp;gt; TContinuation) –&amp;gt; TContinuation. Again, just like the state monad, the CPS function can be curried to TSource –&amp;gt; ((TResult –&amp;gt; TContinuation) –&amp;gt; TContinuation)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SqrtWithCallback: int -&amp;gt; (double -&amp;gt; TContinuation) -&amp;gt; TContinuation
internal static Func&amp;lt;Func&amp;lt;double, TContinuation&amp;gt;, TContinuation&amp;gt; SqrtWithCallback&amp;lt;TContinuation&amp;gt;(int int32) =&amp;gt;
    continuation =&amp;gt; continuation(Math.Sqrt(int32));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the returned (TResult –&amp;gt; TContinuation) –&amp;gt; TContinuation function type can be given an alias Cps:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cps: (T -&amp;gt; TContinuation&amp;gt;) -&amp;gt; TContinuation
public delegate TContinuation Cps&amp;lt;TContinuation, out T&amp;gt;(Func&amp;lt;T, TContinuation&amp;gt; continuation);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the above function can be renamed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SqrtCps: int -&amp;gt; Cps&amp;lt;TContinuation, double&amp;gt;
internal static Cps&amp;lt;TContinuation, double&amp;gt; SqrtCps&amp;lt;TContinuation&amp;gt;(int int32) =&amp;gt;
    continuation =&amp;gt; continuation(Math.Sqrt(int32));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CPS function becomes TSource –&amp;gt; Cps&amp;lt;TContinuation, TResult&amp;gt;, which is a monadic selector function. Just like State&amp;lt;TState,&amp;gt;, here Cps&amp;lt;TContinuation,&amp;gt; is the continuation monad. Its (SelectMany, Wrap, Select) methods can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class CpsExtensions
{
    // SelectMany: (Cps&amp;lt;TContinuation, TSource&amp;gt;, TSource -&amp;gt; Cps&amp;lt;TContinuation, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Cps&amp;lt;TContinuation, TResult&amp;gt;
    public static Cps&amp;lt;TContinuation, TResult&amp;gt; SelectMany&amp;lt;TContinuation, TSource, TSelector, TResult&amp;gt;(
        this Cps&amp;lt;TContinuation, TSource&amp;gt; source,
        Func&amp;lt;TSource, Cps&amp;lt;TContinuation, TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            continuation =&amp;gt; source(value =&amp;gt;
                selector(value)(result =&amp;gt;
                    continuation(resultSelector(value, result))));

    // Wrap: TSource -&amp;gt; Cps&amp;lt;TContinuation, TSource&amp;gt;
    public static Cps&amp;lt;TContinuation, TSource&amp;gt; Cps&amp;lt;TContinuation, TSource&amp;gt;(this TSource value) =&amp;gt;
        continuation =&amp;gt; continuation(value);

    // Select: (Cps&amp;lt;TContinuation, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Cps&amp;lt;TContinuation, TResult&amp;gt;
    public static Cps&amp;lt;TContinuation, TResult&amp;gt; Select&amp;lt;TContinuation, TSource, TResult&amp;gt;(
        this Cps&amp;lt;TContinuation, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).Cps&amp;lt;TContinuation, TResult&amp;gt;(), (value, result) =&amp;gt; result);
            // Equivalent to:
            // continuation =&amp;gt; source(value =&amp;gt; continuation(selector(value)));
            // Or:
            // continuation =&amp;gt; source(continuation.o(selector));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A more complex example is sum of squares. The CPS version of sum and square are straightforward. If direct style of square operation of type int –&amp;gt; int, and the direct style of sum operation is (int, int) –&amp;gt; int, then their CPS versions are just of type int –&amp;gt; Cps&amp;lt;TContinuation, int&amp;gt;, and (int, int) –&amp;gt; Cps&amp;lt;TContinuation, int&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SquareCps: int -&amp;gt; Cps&amp;lt;TContinuation, int&amp;gt;
internal static Cps&amp;lt;TContinuation, int&amp;gt; SquareCps&amp;lt;TContinuation&amp;gt;(int x) =&amp;gt;
    continuation =&amp;gt; continuation(x * x);

// SumCps: (int, int) -&amp;gt; Cps&amp;lt;TContinuation, int&amp;gt;
internal static Cps&amp;lt;TContinuation, int&amp;gt; SumCps&amp;lt;TContinuation&amp;gt;(int x, int y) =&amp;gt;
    continuation =&amp;gt; continuation(x + y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then CPS version of sum of square can be implemented with them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SumOfSquaresCps: (int, int) -&amp;gt; Cps&amp;lt;TContinuation, int&amp;gt;
internal static Cps&amp;lt;TContinuation, int&amp;gt; SumOfSquaresCps&amp;lt;TContinuation&amp;gt;(int a, int b) =&amp;gt;
    continuation =&amp;gt;
        SquareCps&amp;lt;TContinuation&amp;gt;(a)(squareOfA =&amp;gt;
        SquareCps&amp;lt;TContinuation&amp;gt;(b)(squareOfB =&amp;gt;
        SumCps&amp;lt;TContinuation&amp;gt;(squareOfA, squareOfB)(continuation)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not intuitive. But the continuation monad can help. A Cps&amp;lt;TContinuation, T&amp;gt; function can be viewed as a monad wrapper of T value. So T value can be unwrapped from Cps&amp;lt;TContinuation, T&amp;gt; with the LINQ from clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Cps&amp;lt;TContinuation, int&amp;gt; SumOfSquaresCpsLinq&amp;lt;TContinuation&amp;gt;(int a, int b) =&amp;gt;
    from squareOfA in SquareCps&amp;lt;TContinuation&amp;gt;(a) // Cps&amp;lt;TContinuation, int&amp;gt;.
    from squareOfB in SquareCps&amp;lt;TContinuation&amp;gt;(b) // Cps&amp;lt;TContinuation, int&amp;gt;.
    from sum in SumCps&amp;lt;TContinuation&amp;gt;(squareOfA, squareOfB) // Cps&amp;lt;TContinuation, int&amp;gt;.
    select sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following is a similar example of fibonacci:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Cps&amp;lt;TContinuation, uint&amp;gt; FibonacciCps&amp;lt;TContinuation&amp;gt;(uint uInt32) =&amp;gt;
    uInt32 &amp;gt; 1
        ? (from a in FibonacciCps&amp;lt;TContinuation&amp;gt;(uInt32 - 1U)
            from b in FibonacciCps&amp;lt;TContinuation&amp;gt;(uInt32 - 2U)
            select a + b)
        : uInt32.Cps&amp;lt;TContinuation, uint&amp;gt;();
    // Equivalent to:
    // continuation =&amp;gt; uInt32 &amp;gt; 1U
    //    ? continuation(FibonacciCps&amp;lt;int&amp;gt;(uInt32 - 1U)(Id) + FibonacciCps&amp;lt;int&amp;gt;(uInt32 - 2U)(Id))
    //    : continuation(uInt32);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, a direct style function can be easily converted to CPS function – just pass the direct style function’s return value to a continuation function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Cps&amp;lt;TContinuation, T&amp;gt; Cps&amp;lt;TContinuation, T&amp;gt;(Func&amp;lt;T&amp;gt; function) =&amp;gt;
    continuation =&amp;gt; continuation(function());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the previous workflows can be represented in CPS too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow&amp;lt;TContinuation&amp;gt;(Func&amp;lt;string, TContinuation&amp;gt; continuation)
{
    Cps&amp;lt;TContinuation, string&amp;gt; query =
        from filePath in Cps&amp;lt;TContinuation, string&amp;gt;(Console.ReadLine) // Cps&amp;lt;TContinuation, string&amp;gt;.
        from encodingName in Cps&amp;lt;TContinuation, string&amp;gt;(Console.ReadLine) // Cps&amp;lt;TContinuation, string&amp;gt;.
        from encoding in Cps&amp;lt;TContinuation, Encoding&amp;gt;(() =&amp;gt; Encoding.GetEncoding(encodingName)) // Cps&amp;lt;TContinuation, Encoding&amp;gt;.
        from fileContent in Cps&amp;lt;TContinuation, string&amp;gt;(() =&amp;gt; File.ReadAllText(filePath, encoding)) // Cps&amp;lt;TContinuation, string&amp;gt;.
        select fileContent; // Define query.
    TContinuation result = query(continuation); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the workflow, each operation’s continuation function is its next operation. When the workflow executes, each operation computes its return value, then calls back its next operation with its return value. When the last operation executes, it calls back the workflow’s continuation function.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (7) Monad and LINQ to Monads</title><link>https://dixin.github.io/posts/category-theory-via-csharp-7-monad-and-linq-to-monads/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-7-monad-and-linq-to-monads/</guid><description>As fore mentioned endofunctor category can be monoidal (the entire category. Actually, an endofunctor In the endofunctor category can be monoidal too. This kind of endofunctor is called monad. Monad i</description><pubDate>Thu, 26 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Monad&lt;/h2&gt;
&lt;p&gt;As fore mentioned endofunctor category can be monoidal (the entire category. Actually, an endofunctor In the endofunctor category can be monoidal too. This kind of endofunctor is called monad. Monad is another important algebraic structure in category theory and LINQ. Formally, &lt;a href=&quot;http://en.wikipedia.org/wiki/Monad_(category_theory)&quot;&gt;monad&lt;/a&gt; is an endofunctor equipped with 2 natural transformations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monoid multiplication ◎ or μ, which a natural transformation ◎: F(F) ⇒ F, which means, for each object X, ◎ maps F(F(X)) to F(X). For convenience, this mapping operation is also denoted F ◎ F ⇒ F.&lt;/li&gt;
&lt;li&gt;Monoid unit η, which is a natural transformation η: I ⇒ F. Here I is the identity functor, which maps each object X to X itself. For each X, there is η maps I(X) to F(X). Since I(X) is just X, η can also be viewed as mapping: X → F(X).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So monad F is a monoid (F, ◎, η) in the category of endofunctors. Apparently it must preserve the monoid laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity preservation α: (F ◎ F) ◎ F ≡ F ◎ (F ◎ F)&lt;/li&gt;
&lt;li&gt;Left unit preservation λ: η ◎ F ≡ F, and right unit preservation ρ: F ≡ F ◎ η&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So that, the following diagram commutes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-6-Monad-and-LINQ-t_1486B/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-6-Monad-and-LINQ-t_1486B/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In DotNet category, monad can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public partial interface IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; : IFunctor&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;
{
    // From IFunctor&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;:
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TMonad&amp;lt;TSource&amp;gt; -&amp;gt; TMonad&amp;lt;TResult&amp;gt;)
    // Func&amp;lt;TMonad&amp;lt;TSource&amp;gt;, TMonad&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);

    // Multiply: TMonad&amp;lt;TMonad&amp;lt;TSource&amp;gt;&amp;gt; -&amp;gt; TMonad&amp;lt;TSource&amp;gt;
    TMonad&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(TMonad&amp;lt;TMonad&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper);
        
    // Unit: TSource -&amp;gt; TMonad&amp;lt;TSource&amp;gt;
    TMonad&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;LINQ to Monads and monad laws&lt;/h2&gt;
&lt;h3&gt;Built-in IEnumerable&amp;lt;&amp;gt; monad&lt;/h3&gt;
&lt;p&gt;The previously discussed IEnumerable&amp;lt;&amp;gt; functor is a built-in monad, it is straightforward to implement its (Multiply, Unit) method pair:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IMonad&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper)
    {
        foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sourceWrapper)
        {
            foreach (TSource value in source)
            {
                yield return value;
            }
        }
    }

    // Unit: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The monoid unit η is exactly the same as the Wrap method for monoidal functor. It is easy to verify the above implementation preserves the monoid laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MonoidLaws()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 0, 1, 2, 3, 4 };

    // Associativity preservation: source.Wrap().Multiply().Wrap().Multiply() == source.Wrap().Wrap().Multiply().Multiply().
    source.Enumerable().Multiply().Enumerable().Multiply().WriteLines();
    // 0 1 2 3 4
    source.Enumerable().Enumerable().Multiply().Multiply().WriteLines();
    // 0 1 2 3 4
    // Left unit preservation: Unit(source).Multiply() == f.
    Unit(source).Multiply().WriteLines(); // 0 1 2 3 4
    // Right unit preservation: source == source.Select(Unit).Multiply().
    source.Select(Unit).Multiply().WriteLines(); // 0 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in LINQ to Object chapter, for IEnumerable&amp;lt;&amp;gt;, there is already a query method SelectMany providing the same ability to flatten hierarchy an IEnumerable&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; sequence to an IEnumerable&amp;lt;T&amp;gt; sequence. Actually, monad can be alternatively defined with SelectMany and η/Wrap:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial interface IMonad&amp;lt;TMonad&amp;gt; where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;
{
    // SelectMany: (TMonad&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TMonad&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; TMonad&amp;lt;TResult&amp;gt;
    TMonad&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        TMonad&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, TMonad&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector);

    // Wrap: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    TMonad&amp;lt;TSource&amp;gt; Wrap&amp;lt;TSource&amp;gt;(TSource value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the alternative implementation is very similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IMonad&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // SelectMany: (IEnumerable&amp;lt;TSource&amp;gt;, TSource -&amp;gt; IEnumerable&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;
    public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, IEnumerable&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector)
    {
        foreach (TSource value in source)
        {
            foreach (TSelector result in selector(value))
            {
                yield return resultSelector(value, result);
            }
        }
    }

    // Wrap: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Enumerable&amp;lt;TSource&amp;gt;(this TSource value)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above 2 versions of monad definition are equivalent. First, the (SelectMany, Wrap) methods can be implemented with the (Select, Multiply, Unit) methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // (Select, Multiply, Unit) implements (SelectMany, Wrap).
{
    // SelectMany: (IEnumerable&amp;lt;TSource&amp;gt;, TSource -&amp;gt; IEnumerable&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;
    public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, IEnumerable&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            (from value in source
             select (from result in selector(value)
                     select resultSelector(value, result))).Multiply();
            // Compiled to:
            // source.Select(value =&amp;gt; selector(value).Select(result =&amp;gt; resultSelector(value, result))).Multiply();

    // Wrap: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Enumerable&amp;lt;TSource&amp;gt;(this TSource value) =&amp;gt; Unit(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the (Select, Multiply, Unit) methods can be implemented with (SelectMany, Wrap) methods too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // (SelectMany, Wrap) implements (Select, Multiply, Unit).
{
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;).
    public static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            from value in source
            from result in value.Enumerable()
            select result;
            // source.SelectMany(Enumerable, (result, value) =&amp;gt; value);

    // Multiply: IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper) =&amp;gt;
        from source in sourceWrapper
        from value in source
        select value;
        // sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value);

    // Unit: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt; value.Enumerable();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So monad support is built-in in the C# language. As discussed in the LINQ query expression pattern part, SelectMany enables multiple from clauses, which can chain operations together to build a workflow, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow&amp;lt;T1, T2, T3, T4&amp;gt;(
    Func&amp;lt;IEnumerable&amp;lt;T1&amp;gt;&amp;gt; source1,
    Func&amp;lt;IEnumerable&amp;lt;T2&amp;gt;&amp;gt; source2,
    Func&amp;lt;IEnumerable&amp;lt;T3&amp;gt;&amp;gt; source3,
    Func&amp;lt;T1, T2, T3, IEnumerable&amp;lt;T4&amp;gt;&amp;gt; source4)
{
    IEnumerable&amp;lt;T4&amp;gt; query = from value1 in source1()
                            from value2 in source2()
                            from value3 in source3()
                            from value4 in source4(value1, value2, value3)
                            select value4; // Define query.
    query.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here N + 1 from clauses are compiled to N SelectMany fluent calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledWorkflow&amp;lt;T1, T2, T3, T4&amp;gt;(
    Func&amp;lt;IEnumerable&amp;lt;T1&amp;gt;&amp;gt; source1,
    Func&amp;lt;IEnumerable&amp;lt;T2&amp;gt;&amp;gt; source2,
    Func&amp;lt;IEnumerable&amp;lt;T3&amp;gt;&amp;gt; source3,
    Func&amp;lt;T1, T2, T3, IEnumerable&amp;lt;T4&amp;gt;&amp;gt; source4)
{
    IEnumerable&amp;lt;T4&amp;gt; query = source1()
        .SelectMany(value1 =&amp;gt; source2(), (value1, value2) =&amp;gt; new { Value1 = value1, Value2 = value2 })
        .SelectMany(result2 =&amp;gt; source3(), (result2, value3) =&amp;gt; new { Result2 = result2, Value3 = value3 })
        .SelectMany(
            result3 =&amp;gt; source4(result3.Result2.Value1, result3.Result2.Value2, result3.Value3),
            (result3, value4) =&amp;gt; value4); // Define query.
    query.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In LINQ, if monad’s SelectMany implements deferred execution, then monad enables imperative programming paradigm (a sequence of commands) in a purely functional way. In above LINQ query definition, the calls to the commands are not executed. When trying to pull results from the LINQ query, the workflow stars, and the commands executes sequentially.&lt;/p&gt;
&lt;h3&gt;Monad law and Kleisli composition&lt;/h3&gt;
&lt;p&gt;Regarding monad (F, ◎, η) can be redefined as (F, SelectMany, Wrap), the monoid laws now can be expressed by SelectMany and Wrap too, which are called monad laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity law: SelectMany is the associative operator, since it is equivalent to Multiply.&lt;/li&gt;
&lt;li&gt;Left unit law and right unit law: Wrap is the unit η, since it is identical to Unit.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void MonadLaws()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 0, 1, 2, 3, 4 };
    Func&amp;lt;int, IEnumerable&amp;lt;char&amp;gt;&amp;gt; selector = int32 =&amp;gt; new string(&apos;*&apos;, int32);
    Func&amp;lt;int, IEnumerable&amp;lt;double&amp;gt;&amp;gt; selector1 = int32 =&amp;gt; new double[] { int32 / 2D, Math.Sqrt(int32) };
    Func&amp;lt;double, IEnumerable&amp;lt;string&amp;gt;&amp;gt; selector2 =
        @double =&amp;gt; new string[] { @double.ToString(&quot;0.0&quot;), @double.ToString(&quot;0.00&quot;) };
    const int Value = 5;

    // Associativity: source.SelectMany(selector1).SelectMany(selector2) == source.SelectMany(value =&amp;gt; selector1(value).SelectMany(selector2)).
    (from value in source
     from result1 in selector1(value)
     from result2 in selector2(result1)
     select result2).WriteLines();
    // 0.0 0.00 0.0 0.00
    // 0.5 0.50 1.0 1.00
    // 1.0 1.00 1.4 1.41
    // 1.5 1.50 1.7 1.73
    // 2.0 2.00 2.0 2.00
    (from value in source
     from result in (from result1 in selector1(value)
                     from result2 in selector2(result1)
                     select result2)
     select result).WriteLines();
    // 0.0 0.00 0.0 0.00
    // 0.5 0.50 1.0 1.00
    // 1.0 1.00 1.4 1.41
    // 1.5 1.50 1.7 1.73
    // 2.0 2.00 2.0 2.00
    // Left unit: value.Wrap().SelectMany(selector) == selector(value).
    (from value in Value.Enumerable()
     from result in selector(value)
     select result).WriteLines(); // * * * * *
    selector(Value).WriteLines(); // * * * * *
    // Right unit: source == source.SelectMany(Wrap).
    (from value in source
     from result in value.Enumerable()
     select result).WriteLines(); // 0 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, the monad laws are not intuitive. The Kleisli composition ∘ can help. For 2 monadic selector functions that can be passed to SelectMany,are also called Kleisli functions like s1: TSource –&amp;gt; TMonad&amp;lt;TMiddle&amp;gt; and s2: TMiddle –&amp;gt; TMonad&amp;lt;TResult&amp;gt;, their Kleisli composition is still a monadic selector (s2 ∘ s1): TSource –&amp;gt; TMonad&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;( // After.
    this Func&amp;lt;TMiddle, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector2,
    Func&amp;lt;TSource, IEnumerable&amp;lt;TMiddle&amp;gt;&amp;gt; selector1) =&amp;gt;
        value =&amp;gt; selector1(value).SelectMany(selector2, (result1, result2) =&amp;gt; result2);
        // Equivalent to:
        // value =&amp;gt; selector1(value).Select(selector2).Multiply();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static class FuncExtensions
{
    public static Func&amp;lt;TSource, TMonad&amp;lt;TResult&amp;gt;&amp;gt; o&amp;lt;TMonad&amp;lt;&amp;gt;, TSource, TMiddle, TResult&amp;gt;( // After.
        this Func&amp;lt;TMiddle, TMonad&amp;lt;TResult&amp;gt;&amp;gt; selector2,
        Func&amp;lt;TSource, TMonad&amp;lt;TMiddle&amp;gt;&amp;gt; selector1) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            value =&amp;gt; selector1(value).SelectMany(selector2, (result1, result2) =&amp;gt; result2);
            // Equivalent to:
            // value =&amp;gt; selector1(value).Select(selector2).Multiply();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now above monad laws can be expressed by monadic selectors and Kleisli composition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity law: the Kleisli composition of monadic selectors is now the monoid multiplication, it is associative. For monadic selectors s1, s2, s3, there is (s3 ∘ s2) ∘ s1 = s3 ∘ (s2 ∘ s1).&lt;/li&gt;
&lt;li&gt;Left unit law and right unit law: Wrap is still the monoid unit η, it is of type TSource –&amp;gt; TMonad&amp;lt;TSource&amp;gt;, so it can also be viewed as a monadic selector too. For monadic selector s, there is η ∘ s = s and s = s ∘ η.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void KleisliComposition()
{
    Func&amp;lt;bool, IEnumerable&amp;lt;int&amp;gt;&amp;gt; selector1 =
        boolean =&amp;gt; boolean ? new int[] { 0, 1, 2, 3, 4 } : new int[] { 5, 6, 7, 8, 9 };
    Func&amp;lt;int, IEnumerable&amp;lt;double&amp;gt;&amp;gt; selector2 = int32 =&amp;gt; new double[] { int32 / 2D, Math.Sqrt(int32) };
    Func&amp;lt;double, IEnumerable&amp;lt;string&amp;gt;&amp;gt; selector3 =
        @double =&amp;gt; new string[] { @double.ToString(&quot;0.0&quot;), @double.ToString(&quot;0.00&quot;) };

    // Associativity: selector3.o(selector2).o(selector1) == selector3.o(selector2.o(selector1)).
    selector3.o(selector2).o(selector1)(true).WriteLines();
    // 0.0 0.00 0.0 0.00
    // 0.5 0.50 1.0 1.00
    // 1.0 1.00 1.4 1.41
    // 1.5 1.50 1.7 1.73
    // 2.0 2.00 2.0 2.00
    selector3.o(selector2.o(selector1))(true).WriteLines();
    // 0.0 0.00 0.0 0.00
    // 0.5 0.50 1.0 1.00
    // 1.0 1.00 1.4 1.41
    // 1.5 1.50 1.7 1.73
    // 2.0 2.00 2.0 2.00
    // Left unit: Unit.o(selector) == selector.
    Func&amp;lt;int, IEnumerable&amp;lt;int&amp;gt;&amp;gt; leftUnit = Enumerable;
    leftUnit.o(selector1)(true).WriteLines(); // 0 1 2 3 4
    selector1(true).WriteLines(); // 0 1 2 3 4
    // Right unit: selector == selector.o(Unit).
    selector1(false).WriteLines(); // 5 6 7 8 9
    Func&amp;lt;bool, IEnumerable&amp;lt;bool&amp;gt;&amp;gt; rightUnit = Enumerable;
    selector1.o(rightUnit)(false).WriteLines(); // 5 6 7 8 9
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Kleisli category&lt;/h3&gt;
&lt;p&gt;With monad and Kleisli composition, a new kind of category called Kleisli category can be defined. Given a monad (F, ◎, η) in category C, there is a Kleisli category of F, denoted CF:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Its objects ob(CF) are ob(C), all objects in C.&lt;/li&gt;
&lt;li&gt;Its morphisms hom(CF) are Kleisli morphisms. A Kleisli morphisms m from object X to object Y is m: X → F(Y). In DotNet, the Kleisli morphisms are above monadic selector functions.&lt;/li&gt;
&lt;li&gt;The composition of Kleisli morphisms is the above Kleisli composition.&lt;/li&gt;
&lt;li&gt;The identity Kleisli morphism is η of the monad, so that ηX: X → F(X).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-6-Monad-and-LINQ-t_1486B/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-6-Monad-and-LINQ-t_1486B/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As already demonstrated, Kleisli composition and η satisfy the category associativity law and identity law.&lt;/p&gt;
&lt;h3&gt;Monad pattern of LINQ&lt;/h3&gt;
&lt;p&gt;So LINQ SelectMany query’s quintessential mathematics is monad. Generally, in DotNet category, a type is a monad if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This type is an open generic type definition, which can be viewed as type constructor of kind * –&amp;gt; *, so that it maps a concrete type to another concrete monad-wrapped type.&lt;/li&gt;
&lt;li&gt;It is equipped with the standard LINQ query method SelectMany, which can be either instance method or extension method.&lt;/li&gt;
&lt;li&gt;The implementation of SelectMany satisfies the monad laws, so that the monad’s monoid structure is preserved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As &lt;a href=&quot;https://www.linkedin.com/in/brianbeckman&quot;&gt;Brian Beckman&lt;/a&gt; said in &lt;a href=&quot;http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads&quot;&gt;this Channel 9 video&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LINQ is monad. It is very carefully designed by &lt;a href=&quot;http://en.wikipedia.org/wiki/Erik_Meijer_(computer_scientist)&quot;&gt;Erik Meijer&lt;/a&gt; so that it is monad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://ericlippert.com/&quot;&gt;Eric Lippert&lt;/a&gt; also &lt;a href=&quot;http://stackoverflow.com/questions/4683506/are-there-any-connections-between-haskell-and-linq&quot;&gt;mentioned&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The LINQ syntax is designed specifically to make operations on the sequence monad feel natural, but in fact the implementation is more general; what C# calls &quot;SelectMany&quot; is a slightly modified form of the &quot;Bind&quot; operation on an arbitrary monad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On the other hand, to enable the monad LINQ query expression (multiple from clauses with select clause) for a type does not require that type to be strictly a monad. This LINQ workflow syntax can be enabled for any generic or non generic type as long as it has such a SelectMany method, which can be virtually demonstrated as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
internal static void Workflow&amp;lt;TMonad&amp;lt;&amp;gt;, T1, T2, T3, T4, TResult&amp;gt;( // Non generic TMonad can work too.
    Func&amp;lt;TMonad&amp;lt;T1&amp;gt;&amp;gt; operation1,
    Func&amp;lt;TMonad&amp;lt;T2&amp;gt;&amp;gt; operation2,
    Func&amp;lt;TMonad&amp;lt;T3&amp;gt;&amp;gt; operation3,
    Func&amp;lt;TMonad&amp;lt;T4&amp;gt;&amp;gt; operation4,
    Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; resultSelector) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;
{
    TMonad&amp;lt;TResult&amp;gt; query = from /* T1 */ value1 in /* TMonad&amp;lt;T1&amp;gt; */ operation1()
                            from /* T2 */ value2 in /* TMonad&amp;lt;T1&amp;gt; */ operation2()
                            from /* T3 */ value3 in /* TMonad&amp;lt;T1&amp;gt; */ operation3()
                            from /* T4 */ value4 in /* TMonad&amp;lt;T1&amp;gt; */ operation4()
                            select /* TResult */ resultSelector(value1, value2, value3, value4); // Define query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monad vs. monoidal/applicative functor&lt;/h2&gt;
&lt;p&gt;Monad is monoidal functor and applicative functor. Monads’ (SelectMany, Wrap) methods implement monoidal functor’s Multiply and Unit methods, and applicative functor’s (Apply, Wrap) methods. This can be virtually demonstrated as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static partial class MonadExtensions // (SelectMany, Wrap) implements (Multiply, Unit).
{
    // Multiply: (TMonad&amp;lt;T1&amp;gt;, TMonad&amp;lt;T2&amp;gt;) =&amp;gt; TMonad&amp;lt;(T1, T2)&amp;gt;
    public static TMonad&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;TMonad&amp;lt;&amp;gt;, T1, T2&amp;gt;(
        this TMonad&amp;lt;T1&amp;gt; source1, TMonad&amp;lt;T2&amp;gt; source2) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            from value1 in source1
            from value2 in source2
            select (value1, value2);
            // source1.SelectMany(value1 =&amp;gt; source2 (value1, value2) =&amp;gt; value1.ValueTuple(value2));

    // Unit: Unit -&amp;gt; TMonad&amp;lt;Unit&amp;gt;
    public static TMonad&amp;lt;Unit&amp;gt; Unit&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;(
        Unit unit = default) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt; unit.Wrap();
}

// Cannot be compiled.
public static partial class MonadExtensions // (SelectMany, Wrap) implements (Apply, Wrap).
{
    // Apply: (TMonad&amp;lt;TSource -&amp;gt; TResult&amp;gt;, TMonad&amp;lt;TSource&amp;gt;) -&amp;gt; TMonad&amp;lt;TResult&amp;gt;
    public static TMonad&amp;lt;TResult&amp;gt; Apply&amp;lt;TMonad&amp;lt;&amp;gt;, TSource, TResult&amp;gt;(
        this TMonad&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, 
        TMonad&amp;lt;TSource&amp;gt; source) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            from selector in selectorWrapper
            from value in source
            select selector(value);
            // selectorWrapper.SelectMany(selector =&amp;gt; source, (selector, value) =&amp;gt; selector(value));

    // Monad&apos;s Wrap is identical to applicative functor&apos;s Wrap.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If monad is defined with the (Multiply, Unit) methods, they implement monoidal functor’s Multiply and Unit methods, and applicative functor’s (Apply, Wrap) methods too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static class MonadExtensions // Monad (Multiply, Unit) implements monoidal functor (Multiply, Unit).
{
    // Multiply: (TMonad&amp;lt;T1&amp;gt;, TMonad&amp;lt;T2&amp;gt;) =&amp;gt; TMonad&amp;lt;(T1, T2)&amp;gt;
    public static TMonad&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;TMonad&amp;lt;&amp;gt;, T1, T2&amp;gt;(
        this TMonad&amp;lt;T1&amp;gt; source1, TMonad&amp;lt;T2&amp;gt; source2) where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            (from value1 in source1
             select (from value2 in source2
                     select (value1, value2))).Multiply();
            // source1.Select(value1 =&amp;gt; source2.Select(value2 =&amp;gt; (value1, value2))).Multiply();

    // Unit: Unit -&amp;gt; TMonad&amp;lt;Unit&amp;gt;
    public static TMonad&amp;lt;Unit&amp;gt; Unit&amp;lt;TMonad&amp;gt;(Unit unit = default) where TMonad&amp;lt;&amp;gt;: IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt; 
        TMonad&amp;lt;Unit&amp;gt;.Unit&amp;lt;Unit&amp;gt;(unit);
}

// Cannot be compiled.
public static partial class MonadExtensions // Monad (Multiply, Unit) implements applicative functor (Apply, Wrap).
{
    // Apply: (TMonad&amp;lt;TSource -&amp;gt; TResult&amp;gt;, TMonad&amp;lt;TSource&amp;gt;) -&amp;gt; TMonad&amp;lt;TResult&amp;gt;
    public static TMonad&amp;lt;TResult&amp;gt; Apply&amp;lt;TMonad&amp;lt;&amp;gt;, TSource, TResult&amp;gt;(
        this TMonad&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, 
        TMonad&amp;lt;TSource&amp;gt; source)  where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            (from selector in selectorWrapper
             select (from value in source
                     select selector(value))).Multiply();
            // selectorWrapper.Select(selector =&amp;gt; source.Select(value =&amp;gt; selector(value))).Multiply();

    // Wrap: TSource -&amp;gt; TMonad&amp;lt;TSource&amp;gt;
    public static TMonad&amp;lt;TSource&amp;gt; Wrap&amp;lt;TMonad&amp;lt;&amp;gt;, TSource&amp;gt;(
        this TSource value) where TMonad&amp;lt;&amp;gt;: IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; =&amp;gt; TMonad&amp;lt;TSource&amp;gt;.Unit&amp;lt;TSource&amp;gt;(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the monad definition can be updated to implement monoidal functor and applicative functor too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public partial interface IMonad&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt; : IMonoidalFunctor&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;, IApplicativeFunctor&amp;lt;TMonad&amp;lt;&amp;gt;&amp;gt;
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More LINQ to Monads&lt;/h2&gt;
&lt;p&gt;Many other open generic type definitions provided by .NET can be monad. Take Lazy&amp;lt;&amp;gt; functor as example, first, apparently it is a type constructor of kind * –&amp;gt; *. Then, its SelectMany query method can be defined as extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LazyExtensions // Lazy&amp;lt;T&amp;gt; : IMonad&amp;lt;Lazy&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Lazy&amp;lt;Lazy&amp;lt;TSource&amp;gt; -&amp;gt; Lazy&amp;lt;TSource&amp;gt;
    public static Lazy&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(this Lazy&amp;lt;Lazy&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper) =&amp;gt;
        sourceWrapper.SelectMany(Id, False);

    // Unit: TSource -&amp;gt; Lazy&amp;lt;TSource&amp;gt;
    public static Lazy&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt; Lazy(value);

    // SelectMany: (Lazy&amp;lt;TSource&amp;gt;, TSource -&amp;gt; Lazy&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Lazy&amp;lt;TResult&amp;gt;
    public static Lazy&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this Lazy&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, Lazy&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; resultSelector(source.Value, selector(source.Value).Value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its Wrap method has been implemented previously, as a requirement of applicative functor. The following is an example of chaining operations into a workflow with Lazy&amp;lt;&amp;gt; monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    Lazy&amp;lt;string&amp;gt; query = from filePath in new Lazy&amp;lt;string&amp;gt;(Console.ReadLine)
                         from encodingName in new Lazy&amp;lt;string&amp;gt;(Console.ReadLine)
                         from encoding in new Lazy&amp;lt;Encoding&amp;gt;(() =&amp;gt; Encoding.GetEncoding(encodingName))
                         from fileContent in new Lazy&amp;lt;string&amp;gt;(() =&amp;gt; File.ReadAllText(filePath, encoding))
                         select fileContent; // Define query.
    string result = query.Value; // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since SelectMany implements deferred execution, the above LINQ query is pure and the workflow is deferred. When the query is executed by calling Lazy&amp;lt;&amp;gt;.Value, the workflow is started.&lt;/p&gt;
&lt;p&gt;Func&amp;lt;&amp;gt; functor is also monad, with the following SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions // Func&amp;lt;T&amp;gt; : IMonad&amp;lt;Func&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Func&amp;lt;Func&amp;lt;T&amp;gt; -&amp;gt; Func&amp;lt;T&amp;gt;
    public static Func&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(this Func&amp;lt;Func&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper) =&amp;gt; 
        sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value);

    // Unit: Unit -&amp;gt; Func&amp;lt;Unit&amp;gt;
    public static Func&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt; Func(value);

    // SelectMany: (Func&amp;lt;TSource&amp;gt;, TSource -&amp;gt; Func&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Func&amp;lt;TResult&amp;gt;
    public static Func&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this Func&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, Func&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; () =&amp;gt;
        {
            TSource value = source();
            return resultSelector(value, selector(value)());
        };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the workflow is similar to Lazy&amp;lt;&amp;gt; monad’s workflow, because Lazy&amp;lt;T&amp;gt; is just a wrapper of Func&amp;lt;T&amp;gt; factory function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    Func&amp;lt;string&amp;gt; query = from filePath in new Func&amp;lt;string&amp;gt;(Console.ReadLine)
                         from encodingName in new Func&amp;lt;string&amp;gt;(Console.ReadLine)
                         from encoding in new Func&amp;lt;Encoding&amp;gt;(() =&amp;gt; Encoding.GetEncoding(encodingName))
                         from fileContent in new Func&amp;lt;string&amp;gt;(() =&amp;gt; File.ReadAllText(filePath, encoding))
                         select fileContent; // Define query.
    string result = query(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Optional&amp;lt;&amp;gt; monad is monad too, with the following SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class OptionalExtensions // Optional&amp;lt;T&amp;gt; : IMonad&amp;lt;Optional&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Optional&amp;lt;Optional&amp;lt;TSource&amp;gt; -&amp;gt; Optional&amp;lt;TSource&amp;gt;
    public static Optional&amp;lt;TSource&amp;gt; Multiply&amp;lt;TSource&amp;gt;(this Optional&amp;lt;Optional&amp;lt;TSource&amp;gt;&amp;gt; sourceWrapper) =&amp;gt;
        sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value);

    // Unit: TSource -&amp;gt; Optional&amp;lt;TSource&amp;gt;
    public static Optional&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt; Optional(value);

    // SelectMany: (Optional&amp;lt;TSource&amp;gt;, TSource -&amp;gt; Optional&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Optional&amp;lt;TResult&amp;gt;
    public static Optional&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this Optional&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, Optional&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; new Optional&amp;lt;TResult&amp;gt;(() =&amp;gt;
            {
                if (source.HasValue)
                {
                    Optional&amp;lt;TSelector&amp;gt; result = selector(source.Value);
                    if (result.HasValue)
                    {
                        return (true, resultSelector(source.Value, result.Value));
                    }
                }
                return (false, default);
            });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The LINQ workflow of Optional&amp;lt;&amp;gt; monad is also pure and deferred, where each operation in the chaining is an Optional&amp;lt;T&amp;gt; instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Workflow()
{
    string input;
    Optional&amp;lt;string&amp;gt; query =
        from filePath in new Optional&amp;lt;string&amp;gt;(() =&amp;gt; string.IsNullOrWhiteSpace(input = Console.ReadLine())
            ? (false, default) : (true, input))
        from encodingName in new Optional&amp;lt;string&amp;gt;(() =&amp;gt; string.IsNullOrWhiteSpace(input = Console.ReadLine())
            ? (false, default) : (true, input))
        from encoding in new Optional&amp;lt;Encoding&amp;gt;(() =&amp;gt;
            {
                try
                {
                    return (true, Encoding.GetEncoding(encodingName));
                }
                catch (ArgumentException)
                {
                    return (false, default);
                }
            })
        from fileContent in new Optional&amp;lt;string&amp;gt;(() =&amp;gt; File.Exists(filePath)
            ? (true, File.ReadAllText(filePath, encoding)) : (false, default))
        select fileContent; // Define query.
    if (query.HasValue) // Execute query.
    {
        string result = query.Value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Optional&amp;lt;&amp;gt; covers the scenario that each operation of the workflow may not have invalid result. When an operation has valid result (Optional&amp;lt;T&amp;gt;.HasValue returns true), its next operation executes. And when all all the operations have valid result, the entire workflow has a valid query result.&lt;/p&gt;
&lt;p&gt;The ValueTuple&amp;lt;&amp;gt; functor is also monad. Again, its SelectMany cannot defer the call of selector, just like its Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T, TResult&amp;gt; : IMonad&amp;lt;ValueTuple&amp;lt;T,&amp;gt;&amp;gt;
{
    // Multiply: ValueTuple&amp;lt;T, ValueTuple&amp;lt;T, TSource&amp;gt; -&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;
    public static (T, TSource) Multiply&amp;lt;T, TSource&amp;gt;(this (T, (T, TSource)) sourceWrapper) =&amp;gt;
        sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value); // Immediate execution.

    // Unit: TSource -&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;
    public static (T, TSource) Unit&amp;lt;T, TSource&amp;gt;(TSource value) =&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;(value);

    // SelectMany: (ValueTuple&amp;lt;T, TSource&amp;gt;, TSource -&amp;gt; ValueTuple&amp;lt;T, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; ValueTuple&amp;lt;T, TResult&amp;gt;
    public static (T, TResult) SelectMany&amp;lt;T, TSource, TSelector, TResult&amp;gt;(
        this (T, TSource) source,
        Func&amp;lt;TSource, (T, TSelector)&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            (source.Item1, resultSelector(source.Item2, selector(source.Item2).Item2)); // Immediate execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So its workflow is the immediate execution version of Lazy&amp;lt;&amp;gt; monad’s workflow:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions
{
    internal static void Workflow()
    {
        ValueTuple&amp;lt;string&amp;gt; query = from filePath in new ValueTuple&amp;lt;string&amp;gt;(Console.ReadLine())
                                   from encodingName in new ValueTuple&amp;lt;string&amp;gt;(Console.ReadLine())
                                   from encoding in new ValueTuple&amp;lt;Encoding&amp;gt;(Encoding.GetEncoding(encodingName))
                                   from fileContent in new ValueTuple&amp;lt;string&amp;gt;(File.ReadAllText(filePath, encoding))
                                   select fileContent; // Define and execute query.
        string result = query.Item1; // Query result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Task&amp;lt;&amp;gt; functor is monad too. Once again, its SelectMany is immediate and impure, just like its Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TaskExtensions // Task&amp;lt;T&amp;gt; : IMonad&amp;lt;Task&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Task&amp;lt;Task&amp;lt;T&amp;gt; -&amp;gt; Task&amp;lt;T&amp;gt;
    public static Task&amp;lt;TResult&amp;gt; Multiply&amp;lt;TResult&amp;gt;(this Task&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; sourceWrapper) =&amp;gt;
        sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value); // Immediate execution, impure.

    // Unit: TSource -&amp;gt; Task&amp;lt;TSource&amp;gt;
    public static Task&amp;lt;TSource&amp;gt; Unit&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt; Task(value);

    // SelectMany: (Task&amp;lt;TSource&amp;gt;, TSource -&amp;gt; Task&amp;lt;TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; Task&amp;lt;TResult&amp;gt;
    public static async Task&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this Task&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, Task&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            resultSelector(await source, await selector(await source)); // Immediate execution, impure.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the following LINQ workflow with Task&amp;lt;&amp;gt; monad is also immediate and impure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task WorkflowAsync(string uri)
{
    Task&amp;lt;string&amp;gt; query = from response in new HttpClient().GetAsync(uri) // Return Task&amp;lt;HttpResponseMessage&amp;gt;.
                         from stream in response.Content.ReadAsStreamAsync() // Return Task&amp;lt;Stream&amp;gt;.
                         from text in new StreamReader(stream).ReadToEndAsync() // Return Task&amp;lt;string&amp;gt;.
                         select text; // Define and execute query.
    string result = await query; // Query result.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is easy to verify all the above SelectMany methods satisfy the monad laws, and all the above (Multiply, Unit) methods preserve the monoid laws. However, not any SelectMany or (Multiply, Unit) methods can automatically satisfy those laws. Take the ValueTuple&amp;lt;T,&amp;gt; functor as example, here are its SelectMany and (Multiply, Unit):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T, TResult&amp;gt; : IMonad&amp;lt;ValueTuple&amp;lt;T,&amp;gt;&amp;gt;
{
    // Multiply: ValueTuple&amp;lt;T, ValueTuple&amp;lt;T, TSource&amp;gt; -&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;
    public static (T, TSource) Multiply&amp;lt;T, TSource&amp;gt;(this (T, (T, TSource)) sourceWrapper) =&amp;gt;
        sourceWrapper.SelectMany(source =&amp;gt; source, (source, value) =&amp;gt; value); // Immediate execution.

    // Unit: TSource -&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;
    public static (T, TSource) Unit&amp;lt;T, TSource&amp;gt;(TSource value) =&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;(value);

    // SelectMany: (ValueTuple&amp;lt;T, TSource&amp;gt;, TSource -&amp;gt; ValueTuple&amp;lt;T, TSelector&amp;gt;, (TSource, TSelector) -&amp;gt; TResult) -&amp;gt; ValueTuple&amp;lt;T, TResult&amp;gt;
    public static (T, TResult) SelectMany&amp;lt;T, TSource, TSelector, TResult&amp;gt;(
        this (T, TSource) source,
        Func&amp;lt;TSource, (T, TSelector)&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            (source.Item1, resultSelector(source.Item2, selector(source.Item2).Item2)); // Immediate execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above (Multiply, Unit) implementations cannot preserve the monoid left unit law:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MonoidLaws()
{
    (string, int) source = (&quot;a&quot;, 1);

    // Associativity preservation: source.Wrap().Multiply().Wrap().Multiply() == source.Wrap().Wrap().Multiply().Multiply().
    source
        .ValueTuple&amp;lt;string, (string, int)&amp;gt;()
        .Multiply()
        .ValueTuple&amp;lt;string, (string, int)&amp;gt;()
        .Multiply()
        .WriteLine(); // (, 1)
    source
        .ValueTuple&amp;lt;string, (string, int)&amp;gt;()
        .ValueTuple&amp;lt;string, (string, (string, int))&amp;gt;()
        .Multiply()
        .Multiply()
        .WriteLine(); // (, 1)
    // Left unit preservation: Unit(f).Multiply() == source.
    Unit&amp;lt;string, (string, int)&amp;gt;(source).Multiply().WriteLine(); // (, 1)
    // Right unit preservation: source == source.Select(Unit).Multiply().
    source.Select(Unit&amp;lt;string, int&amp;gt;).Multiply().WriteLine(); // (a, 1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the above SelectMany implementation breaks the left unit monad law too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MonadLaws()
{
    ValueTuple&amp;lt;string, int&amp;gt; source = (&quot;a&quot;, 1);
    Func&amp;lt;int, ValueTuple&amp;lt;string, char&amp;gt;&amp;gt; selector = int32 =&amp;gt; (&quot;b&quot;, &apos;@&apos;);
    Func&amp;lt;int, ValueTuple&amp;lt;string, double&amp;gt;&amp;gt; selector1 = int32 =&amp;gt; (&quot;c&quot;, Math.Sqrt(int32));
    Func&amp;lt;double, ValueTuple&amp;lt;string, string&amp;gt;&amp;gt; selector2 = @double =&amp;gt; (&quot;d&quot;, @double.ToString(&quot;0.00&quot;));
    const int Value = 5;

    // Associativity: source.SelectMany(selector1).SelectMany(selector2) == source.SelectMany(value =&amp;gt; selector1(value).SelectMany(selector2)).
    (from value in source
        from result1 in selector1(value)
        from result2 in selector2(result1)
        select result2).WriteLine(); // (a, 1.00)
    (from value in source
        from result in (from result1 in selector1(value) from result2 in selector2(result1) select result2)
        select result).WriteLine(); // (a, 1.00)
    // Left unit: value.Wrap().SelectMany(selector) == selector(value).
    (from value in Value.ValueTuple&amp;lt;string, int&amp;gt;()
        from result in selector(value)
        select result).WriteLine(); // (, @)
    selector(Value).WriteLine(); // (b, @)
    // Right unit: source == source.SelectMany(Wrap).
    (from value in source
        from result in value.ValueTuple&amp;lt;string, int&amp;gt;()
        select result).WriteLine(); // (a, 1)
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (6) Monoidal Functor and Applicative Functor</title><link>https://dixin.github.io/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor/</guid><description>Given monoidal categories (C, ⊗, IC) and (D, ⊛, ID), a strong lax monoidal functor is a functor F: C → D equipped with:</description><pubDate>Wed, 25 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Monoidal functor&lt;/h2&gt;
&lt;p&gt;Given monoidal categories (C, ⊗, IC) and (D, ⊛, ID), a strong lax monoidal functor is a functor F: C → D equipped with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monoid binary multiplication operation, which is a natural transformation φ: F(X) ⊛ F(Y) ⇒ F(X ⊗ Y)&lt;/li&gt;
&lt;li&gt;Monoid unit, which is a morphism ι: ID → F(IC)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;F preserves the monoid laws in D:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity law is preserved with D’s associator αD: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/Untitled-4.fw_thumb1_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/Untitled-4.fw_thumb1_thumb_1.png&quot; alt=&quot;Untitled-4.fw_thumb1&quot; title=&quot;Untitled-4.fw_thumb1&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Left unit law is preserved with D’s left unitor λD: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt; and right unit law is preserved with D’s right unitor ρD: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/Untitled-3..fw_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/8aeb52ea4130_CA43/Untitled-3..fw_thumb_thumb.png&quot; alt=&quot;Untitled-3..fw_thumb&quot; title=&quot;Untitled-3..fw_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this tutorial, strong lax monoidal functor is called monoidal functor for short. In DotNet category, monoidal functors are monoidal endofunctors. In the definition, (C, ⊗, IC) and (D, ⊛, ID) are both (DotNet, ValueTuple&amp;lt;,&amp;gt;, Unit), so monoidal functor can be IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt; : IFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
    where TMonoidalFunctor : IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
{
    // From IFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;:
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TMonoidalFunctor&amp;lt;TSource&amp;gt; -&amp;gt; TMonoidalFunctor&amp;lt;TResult&amp;gt;)
    // Func&amp;lt;TMonoidalFunctor&amp;lt;TSource&amp;gt;, TMonoidalFunctor&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);

    // Multiply: TMonoidalFunctor&amp;lt;T1&amp;gt; x TMonoidalFunctor&amp;lt;T2&amp;gt; -&amp;gt; TMonoidalFunctor&amp;lt;T1 x T2&amp;gt;
    // Multiply: ValueTuple&amp;lt;TMonoidalFunctor&amp;lt;T1&amp;gt;, TMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; -&amp;gt; TMonoidalFunctor&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;
    TMonoidalFunctor&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(
        ValueTuple&amp;lt;TMonoidalFunctor&amp;lt;T1&amp;gt;, TMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; bifunctor);

    // Unit: Unit -&amp;gt; TMonoidalFunctor&amp;lt;Unit&amp;gt;
    TMonoidalFunctor&amp;lt;Unit&amp;gt; Unit(Unit unit);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiply accepts a ValueTuple&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; bifunctor, which is literally a 2-tuple (IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;). For convenience, the explicit ValueTuple&amp;lt;,&amp;gt; parameter can be represented by an implicit tuple, a pair of parameters. So the monoidal functor definition is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt; : IFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
    where TMonoidalFunctor : IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: TMonoidalFunctor&amp;lt;T1&amp;gt; x TMonoidalFunctor&amp;lt;T2&amp;gt; -&amp;gt; TMonoidalFunctor&amp;lt;T1 x T2&amp;gt;
    // Multiply: (TMonoidalFunctor&amp;lt;T1&amp;gt;, TMonoidalFunctor&amp;lt;T2&amp;gt;) -&amp;gt; TMonoidalFunctor&amp;lt;(T1, T2)&amp;gt;
    TMonoidalFunctor&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(
        TMonoidalFunctor&amp;lt;T1&amp;gt; source1, TMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; source2); // Unit: Unit

    // Unit: Unit -&amp;gt; TMonoidalFunctor&amp;lt;Unit&amp;gt;
    TMonoidalFunctor&amp;lt;Unit&amp;gt; Unit(Unit unit);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;IEnumerable&amp;lt;&amp;gt; monoidal functor&lt;/h3&gt;
&lt;p&gt;IEnumerable&amp;lt;&amp;gt; functor is a monoidal functor. Its Multiply method can be implemented as its extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: IEnumerable&amp;lt;T1&amp;gt; x IEnumerable&amp;lt;T2&amp;gt; -&amp;gt; IEnumerable&amp;lt;T1 x T2&amp;gt;
    // Multiply: ValueTuple&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; -&amp;gt; IEnumerable&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;
    // Multiply: (IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;) -&amp;gt; IEnumerable&amp;lt;(T1, T2)&amp;gt;
    public static IEnumerable&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(
        this IEnumerable&amp;lt;T1&amp;gt; source1, IEnumerable&amp;lt;T2&amp;gt; source2) // Implicit tuple.
    {
        foreach (T1 value1 in source1)
        {
            foreach (T2 value2 in source2)
            {
                yield return (value1, value2);
            }
        }
    }

    // Unit: Unit -&amp;gt; IEnumerable&amp;lt;Unit&amp;gt;
    public static IEnumerable&amp;lt;Unit&amp;gt; Unit(Unit unit = default)
    {
        yield return unit;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now extension method Multiply can be used as a infix operator. It can be verified that the above Multiply and Unit implementations preserve the monoid laws by working with associator, left unitor and right unitor of DotNet monoidal category:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// using static Dixin.Linq.CategoryTheory.DotNetCategory;
internal static void MonoidalFunctorLaws()
{
    IEnumerable&amp;lt;Unit&amp;gt; unit = Unit();
    IEnumerable&amp;lt;int&amp;gt; source1 = new int[] { 0, 1 };
    IEnumerable&amp;lt;char&amp;gt; source2 = new char[] { &apos;@&apos;, &apos;#&apos; };
    IEnumerable&amp;lt;bool&amp;gt; source3 = new bool[] { true, false };
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 0, 1, 2, 3, 4 };

    // Associativity preservation: source1.Multiply(source2).Multiply(source3).Select(Associator) == source1.Multiply(source2.Multiply(source3)).
    source1.Multiply(source2).Multiply(source3).Select(Associator).WriteLines();
        // (0, (@, True)) (0, (@, False)) (0, (#, True)) (0, (#, False))
        // (1, (@, True)) (1, (@, False)) (1, (#, True)) (1, (#, False))
    source1.Multiply(source2.Multiply(source3)).WriteLines();
        // (0, (@, True)) (0, (@, False)) (0, (#, True)) (0, (#, False))
        // (1, (@, True)) (1, (@, False)) (1, (#, True)) (1, (#, False))
    // Left unit preservation: unit.Multiply(source).Select(LeftUnitor) == source.
    unit.Multiply(source).Select(LeftUnitor).WriteLines(); // 0 1 2 3 4
    // Right unit preservation: source == source.Multiply(unit).Select(RightUnitor).
    source.Multiply(unit).Select(RightUnitor).WriteLines(); // 0 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How could these methods be useful? Remember functor’s Select method enables selector working with value(s) wrapped by functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Selector1Arity(IEnumerable&amp;lt;int&amp;gt; xs)
{
    Func&amp;lt;int, bool&amp;gt; selector = x =&amp;gt; x &amp;gt; 0;
    // Apply selector with xs.
    IEnumerable&amp;lt;bool&amp;gt; applyWithXs = xs.Select(selector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Select can be viewed as applying 1 arity selector (a TSource –&amp;gt; TResult function) with TFunctor&amp;lt;TSource&amp;gt;. For a N arity selector, to have it work with value(s) wrapped by functor, first curry it, so that it can be viewed as 1 arity function. In the following example, the (T1, T2, T3) –&amp;gt; TResult selector is curried to T1 –&amp;gt; (T2 –&amp;gt; T3 –&amp;gt; TResult) function, so that it can be viewed as only have 1 parameter, and can work with TFunctor&amp;lt;T1&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectorNArity(IEnumerable&amp;lt;int&amp;gt; xs, IEnumerable&amp;lt;long&amp;gt; ys, IEnumerable&amp;lt;double&amp;gt; zs)
{
    Func&amp;lt;int, long, double, bool&amp;gt; selector = (x, y, z) =&amp;gt; x + y + z &amp;gt; 0;

    // Curry selector.
    Func&amp;lt;int, Func&amp;lt;long, Func&amp;lt;double, bool&amp;gt;&amp;gt;&amp;gt; curriedSelector = 
        selector.Curry(); // 1 arity: x =&amp;gt; (y =&amp;gt; z =&amp;gt; x + y + z &amp;gt; 0)
    // Partially apply selector with xs.
    IEnumerable&amp;lt;Func&amp;lt;long, Func&amp;lt;double, bool&amp;gt;&amp;gt;&amp;gt; applyWithXs = xs.Select(curriedSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So partially applying the T1 –&amp;gt; (T2 –&amp;gt; T3 –&amp;gt; TResult) selector with TFunctor&amp;lt;T1&amp;gt; returns TFunctor&amp;lt;T2 –&amp;gt; T3 –&amp;gt; TResult&amp;gt;, where the T2 –&amp;gt; T3 –&amp;gt; TResult function is wrapped by the TFunctor&amp;lt;&amp;gt; functor. To further apply TFunctor&amp;lt;T2 –&amp;gt; T3 –&amp;gt; TResult&amp;gt; with TFunctor&amp;lt;T2&amp;gt;, Multiply can be called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Partially apply selector with ys.
    IEnumerable&amp;lt;(Func&amp;lt;long, Func&amp;lt;double, bool&amp;gt;&amp;gt;, long)&amp;gt; multiplyWithYs = applyWithXs.Multiply(ys);
    IEnumerable&amp;lt;Func&amp;lt;double, bool&amp;gt;&amp;gt; applyWithYs = multiplyWithYs.Select(product =&amp;gt;
    {
        Func&amp;lt;long, Func&amp;lt;double, bool&amp;gt;&amp;gt; partialAppliedSelector = product.Item1;
        long y = product.Item2;
        return partialAppliedSelector(y);
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result of Multiply is TFunctor&amp;lt;(T2 –&amp;gt; T3 –&amp;gt; TResult, T2)&amp;gt;, where each T2 –&amp;gt; T3 –&amp;gt; TResult function is paired with each T2 value, so that each function can be applied with each value, And TFunctor&amp;lt;(T2 –&amp;gt; T3 –&amp;gt; TResult, T2)&amp;gt; is mapped to TFunctor&amp;lt;(T3 –&amp;gt; TResult)&amp;gt;, which can be applied with TFunctor&amp;lt;T3&amp;gt; in the same way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Partially apply selector with zs.
    IEnumerable&amp;lt;(Func&amp;lt;double, bool&amp;gt;, double)&amp;gt; multiplyWithZs = applyWithYs.Multiply(zs);
    IEnumerable&amp;lt;bool&amp;gt; applyWithZs = multiplyWithZs.Select(product =&amp;gt;
    {
        Func&amp;lt;double, bool&amp;gt; partialAppliedSelector = product.Item1;
        double z = product.Item2;
        return partialAppliedSelector(z);
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Multiply enables applying functor-wrapped functions (TFunctor&amp;lt;T –&amp;gt; TResult&amp;gt;) with functor-wrapped values (TFunctor&amp;lt;TSource&amp;gt;), which returns functor-wrapped results (TFunctor&amp;lt;TResult&amp;gt;). Generally, the Multiply and Select calls can be encapsulated as the following Apply method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Apply: (IEnumerable&amp;lt;TSource -&amp;gt; TResult&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;
public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
        selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the above N arity selector application becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Apply(IEnumerable&amp;lt;int&amp;gt; xs, IEnumerable&amp;lt;long&amp;gt; ys, IEnumerable&amp;lt;double&amp;gt; zs)
{
    Func&amp;lt;int, long, double, bool&amp;gt; selector = (x, y, z) =&amp;gt; x + y + z &amp;gt; 0;
    // Partially apply selector with xs.
    IEnumerable&amp;lt;Func&amp;lt;long, Func&amp;lt;double, bool&amp;gt;&amp;gt;&amp;gt; applyWithXs = xs.Select(selector.Curry());
    // Partially apply selector with ys.
    IEnumerable&amp;lt;Func&amp;lt;double, bool&amp;gt;&amp;gt; applyWithYs = applyWithXs.Apply(ys);
    // Partially apply selector with zs.
    IEnumerable&amp;lt;bool&amp;gt; applyWithZs = applyWithYs.Apply(zs);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Applicative functor&lt;/h2&gt;
&lt;p&gt;A functor, with the above ability to apply functor-wrapped functions with functor-wrapped values, is also called applicative functor. The following is the definition of applicative functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt; : IFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;
    where TApplicativeFunctor&amp;lt;&amp;gt; : IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;
{
    // From: IFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;:
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TApplicativeFunctor&amp;lt;TSource&amp;gt; -&amp;gt; TApplicativeFunctor&amp;lt;TResult&amp;gt;)
    // Func&amp;lt;TApplicativeFunctor&amp;lt;TSource&amp;gt;, TApplicativeFunctor&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);

    // Apply: (TApplicativeFunctor&amp;lt;TSource -&amp;gt; TResult&amp;gt;, TApplicativeFunctor&amp;lt;TSource&amp;gt; -&amp;gt; TApplicativeFunctor&amp;lt;TResult&amp;gt;
    TApplicativeFunctor&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        TApplicativeFunctor&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, TApplicativeFunctor&amp;lt;TSource&amp;gt; source);

    // Wrap: TSource -&amp;gt; TApplicativeFunctor&amp;lt;TSource&amp;gt;
    TApplicativeFunctor&amp;lt;TSource&amp;gt; Wrap&amp;lt;TSource&amp;gt;(TSource value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And applicative functor must satisfy the applicative laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functor preservation: applying function is equivalent to applying functor-wrapped function&lt;/li&gt;
&lt;li&gt;Identity preservation: applying functor-wrapped identity function, is equivalent to doing nothing.&lt;/li&gt;
&lt;li&gt;Composition preservation: functor-wrapped functions can be composed by applying.&lt;/li&gt;
&lt;li&gt;Homomorphism: applying functor-wrapped function with functor-wrapped value, is equivalent to functor-wrapping the result of applying that function with that value.&lt;/li&gt;
&lt;li&gt;Interchange: when applying functor-wrapped functions with a functor-wrapped value, the functor-wrapped functions and the functor-wrapped value can interchange position.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;IEnumerable&amp;lt;&amp;gt; applicative functor&lt;/h3&gt;
&lt;p&gt;IEnumerable&amp;lt;&amp;gt; functor is a applicative functor. Again, these methods are implemented as extension methods. And for IEnumerable&amp;lt;&amp;gt;, the Wrap method is called Enumerable to be intuitive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (IEnumerable&amp;lt;TSource -&amp;gt; TResult&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;
    public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, IEnumerable&amp;lt;TSource&amp;gt; source)
    {
        foreach (Func&amp;lt;TSource, TResult&amp;gt; selector in selectorWrapper)
        {
            foreach (TSource value in source)
            {
                yield return selector(value);
            }
        }
    }

    // Wrap: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Enumerable&amp;lt;TSource&amp;gt;(this TSource value)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be verified that the above Apply and Wrap (Enumerable) implementations satisfy the applicative laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ApplicativeLaws()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 0, 1, 2, 3, 4 };
    Func&amp;lt;int, double&amp;gt; selector = int32 =&amp;gt; Math.Sqrt(int32);
    IEnumerable&amp;lt;Func&amp;lt;int, double&amp;gt;&amp;gt; selectorWrapper1 =
        new Func&amp;lt;int, double&amp;gt;[] { int32 =&amp;gt; int32 / 2D, int32 =&amp;gt; Math.Sqrt(int32) };
    IEnumerable&amp;lt;Func&amp;lt;double, string&amp;gt;&amp;gt; selectorWrapper2 =
        new Func&amp;lt;double, string&amp;gt;[] { @double =&amp;gt; @double.ToString(&quot;0.0&quot;), @double =&amp;gt; @double.ToString(&quot;0.00&quot;) };
    Func&amp;lt;Func&amp;lt;double, string&amp;gt;, Func&amp;lt;Func&amp;lt;int, double&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; o =
        new Func&amp;lt;Func&amp;lt;double, string&amp;gt;, Func&amp;lt;int, double&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;(Linq.FuncExtensions.o).Curry();
    int value = 5;

    // Functor preservation: source.Select(selector) == selector.Wrap().Apply(source).
    source.Select(selector).WriteLines(); // 0 1 1.4142135623731 1.73205080756888 2
    selector.Enumerable().Apply(source).WriteLines(); // 0 1 1.4142135623731 1.73205080756888 2
    // Identity preservation: Id.Wrap().Apply(source) == source.
    new Func&amp;lt;int, int&amp;gt;(Functions.Id).Enumerable().Apply(source).WriteLines(); // 0 1 2 3 4
    // Composition preservation: o.Wrap().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source) == selectorWrapper2.Apply(selectorWrapper1.Apply(source)).
    o.Enumerable().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source).WriteLines();
        // 0.0  0.5  1.0  1.5  2.0
        // 0.0  1.0  1.4  1.7  2.0 
        // 0.00 0.50 1.00 1.50 2.00
        // 0.00 1.00 1.41 1.73 2.00
    selectorWrapper2.Apply(selectorWrapper1.Apply(source)).WriteLines();
        // 0.0  0.5  1.0  1.5  2.0
        // 0.0  1.0  1.4  1.7  2.0 
        // 0.00 0.50 1.00 1.50 2.00
        // 0.00 1.00 1.41 1.73 2.00
    // Homomorphism: selector.Wrap().Apply(value.Wrap()) == selector(value).Wrap().
    selector.Enumerable().Apply(value.Enumerable()).WriteLines(); // 2.23606797749979
    selector(value).Enumerable().WriteLines(); // 2.23606797749979
    // Interchange: selectorWrapper.Apply(value.Wrap()) == (selector =&amp;gt; selector(value)).Wrap().Apply(selectorWrapper).
    selectorWrapper1.Apply(value.Enumerable()).WriteLines(); // 2.5 2.23606797749979
    new Func&amp;lt;Func&amp;lt;int, double&amp;gt;, double&amp;gt;(function =&amp;gt; function(value)).Enumerable().Apply(selectorWrapper1)
        .WriteLines(); // 2.5 2.23606797749979
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monoidal functor vs. applicative functor&lt;/h2&gt;
&lt;p&gt;The applicative functor definition is actually equivalent to above monoidal functor definition. First, applicative functor’s Apply and Wrap methods can be implemented by monoidal functor’s Multiply and Unit methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (IEnumerable&amp;lt;TSource -&amp;gt; TResult&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;
    public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Enumerable&amp;lt;TSource&amp;gt;(this TSource value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other hand, monoidal functor’s Multiply and Unit methods can be implemented by applicative functor’s Apply and Wrap methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: IEnumerable&amp;lt;T1&amp;gt; x IEnumerable&amp;lt;T2&amp;gt; -&amp;gt; IEnumerable&amp;lt;T1 x T2&amp;gt;
    // Multiply: (IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;) -&amp;gt; IEnumerable&amp;lt;(T1, T2)&amp;gt;
    public static IEnumerable&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(
        this IEnumerable&amp;lt;T1&amp;gt; source1, IEnumerable&amp;lt;T2&amp;gt; source2) =&amp;gt;
            new Func&amp;lt;T1, T2, (T1, T2)&amp;gt;(ValueTuple.Create).Curry().Enumerable().Apply(source1).Apply(source2);

    // Unit: Unit -&amp;gt; IEnumerable&amp;lt;Unit&amp;gt;
    public static IEnumerable&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt; unit.Enumerable();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, for any applicative functor, its (Apply, Wrap) method pair can implement the (Multiply, Unit) method pair required as monoidal functor, and vice versa. This can be virtually demonstrated as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static class MonoidalFunctorExtensions // (Multiply, Unit) implements (Apply, Wrap).
{
    // Apply: (TMonoidalFunctor&amp;lt;TSource -&amp;gt; TResult&amp;gt;, TMonoidalFunctor&amp;lt;TSource&amp;gt;) -&amp;gt; TMonoidalFunctor&amp;lt;TResult&amp;gt;
    public static TMonoidalFunctor&amp;lt;TResult&amp;gt; Apply&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;, TSource, TResult&amp;gt;(
        this TMonoidalFunctor&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, TMonoidalFunctor&amp;lt;TSource&amp;gt; source) 
        where TMonoidalFunctor&amp;lt;&amp;gt; : IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; TMonoidalFunctor&amp;lt;TSource&amp;gt;
    public static TMonoidalFunctor&amp;lt;TSource&amp;gt; Wrap&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;, TSource&amp;gt;(this TSource value) 
        where TMonoidalFunctor&amp;lt;&amp;gt; : IMonoidalFunctor&amp;lt;TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt; =&amp;gt;TMonoidalFunctor&amp;lt;TSource&amp;gt;
            TMonoidalFunctor&amp;lt;TSource&amp;gt;.Unit().Select(unit =&amp;gt; value);
}

// Cannot be compiled.
public static class ApplicativeFunctorExtensions // (Apply, Wrap) implements (Multiply, Unit).
{
    // Multiply: TApplicativeFunctor&amp;lt;T1&amp;gt; x TApplicativeFunctor&amp;lt;T2&amp;gt; -&amp;gt; TApplicativeFunctor&amp;lt;T1 x T2&amp;gt;
    // Multiply: (TApplicativeFunctor&amp;lt;T1&amp;gt;, TApplicativeFunctor&amp;lt;T2&amp;gt;) -&amp;gt; TApplicativeFunctor&amp;lt;(T1, T2)&amp;gt;
    public static TApplicativeFunctor&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;, T1, T2&amp;gt;(
        this TApplicativeFunctor&amp;lt;T1&amp;gt; source1, TApplicativeFunctor&amp;lt;T2&amp;gt; source2) 
        where TApplicativeFunctor&amp;lt;&amp;gt; : IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt; =&amp;gt;
            new Func&amp;lt;T1, T2, (T1, T2)&amp;gt;(ValueTuple.Create).Curry().Wrap().Apply(source1).Apply(source2);

    // Unit: Unit -&amp;gt; TApplicativeFunctor&amp;lt;Unit&amp;gt;
    public static TApplicativeFunctor&amp;lt;Unit&amp;gt; Unit&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;(Unit unit = default)
        where TApplicativeFunctor&amp;lt;&amp;gt; : IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt; =&amp;gt; unit.Wrap();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More Monoidal functors and applicative functors&lt;/h2&gt;
&lt;p&gt;The Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Func&amp;lt;T,&amp;gt; functors are also monoidal/applicative functors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LazyExtensions // Lazy&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;Lazy&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Lazy&amp;lt;T1&amp;gt; x Lazy&amp;lt;T2&amp;gt; -&amp;gt; Lazy&amp;lt;T1 x T2&amp;gt;
    // Multiply: (Lazy&amp;lt;T1&amp;gt;, Lazy&amp;lt;T2&amp;gt;) -&amp;gt; Lazy&amp;lt;(T1, T2)&amp;gt;
    public static Lazy&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(this Lazy&amp;lt;T1&amp;gt; source1, Lazy&amp;lt;T2&amp;gt; source2) =&amp;gt;
        new Lazy&amp;lt;(T1, T2)&amp;gt;(() =&amp;gt; (source1.Value, source2.Value));

    // Unit: Unit -&amp;gt; Lazy&amp;lt;Unit&amp;gt;
    public static Lazy&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt; new Lazy&amp;lt;Unit&amp;gt;(() =&amp;gt; unit);
}

public static partial class LazyExtensions // Lazy&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;Lazy&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (Lazy&amp;lt;TSource -&amp;gt; TResult&amp;gt;, Lazy&amp;lt;TSource&amp;gt;) -&amp;gt; Lazy&amp;lt;TResult&amp;gt;
    public static Lazy&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this Lazy&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, Lazy&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; Lazy&amp;lt;TSource&amp;gt;
    public static Lazy&amp;lt;T&amp;gt; Lazy&amp;lt;T&amp;gt;(this T value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}

public static partial class FuncExtensions // Func&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;Func&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Func&amp;lt;T1&amp;gt; x Func&amp;lt;T2&amp;gt; -&amp;gt; Func&amp;lt;T1 x T2&amp;gt;
    // Multiply: (Func&amp;lt;T1&amp;gt;, Func&amp;lt;T2&amp;gt;) -&amp;gt; Func&amp;lt;(T1, T2)&amp;gt;
    public static Func&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(this Func&amp;lt;T1&amp;gt; source1, Func&amp;lt;T2&amp;gt; source2) =&amp;gt;
        () =&amp;gt; (source1(), source2());

    // Unit: Unit -&amp;gt; Func&amp;lt;Unit&amp;gt;
    public static Func&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt; () =&amp;gt; unit;
}

public static partial class FuncExtensions // Func&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;Func&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (Func&amp;lt;TSource -&amp;gt; TResult&amp;gt;, Func&amp;lt;TSource&amp;gt;) -&amp;gt; Func&amp;lt;TResult&amp;gt;
    public static Func&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this Func&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, Func&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; Func&amp;lt;TSource&amp;gt;
    public static Func&amp;lt;T&amp;gt; Func&amp;lt;T&amp;gt;(this T value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}

public static partial class FuncExtensions // Func&amp;lt;T, TResult&amp;gt; : IMonoidalFunctor&amp;lt;Func&amp;lt;T,&amp;gt;&amp;gt;
{
    // Multiply: Func&amp;lt;T, T1&amp;gt; x Func&amp;lt;T, T2&amp;gt; -&amp;gt; Func&amp;lt;T, T1 x T2&amp;gt;
    // Multiply: (Func&amp;lt;T, T1&amp;gt;, Func&amp;lt;T, T2&amp;gt;) -&amp;gt; Func&amp;lt;T, (T1, T2)&amp;gt;
    public static Func&amp;lt;T, (T1, T2)&amp;gt; Multiply&amp;lt;T, T1, T2&amp;gt;(this Func&amp;lt;T, T1&amp;gt; source1, Func&amp;lt;T, T2&amp;gt; source2) =&amp;gt;
        value =&amp;gt; (source1(value), source2(value));

    // Unit: Unit -&amp;gt; Func&amp;lt;T, Unit&amp;gt;
    public static Func&amp;lt;T, Unit&amp;gt; Unit&amp;lt;T&amp;gt;(Unit unit = default) =&amp;gt; _ =&amp;gt; unit;
}

public static partial class FuncExtensions // Func&amp;lt;T, TResult&amp;gt; : IApplicativeFunctor&amp;lt;Func&amp;lt;T,&amp;gt;&amp;gt;
{
    // Apply: (Func&amp;lt;T, TSource -&amp;gt; TResult&amp;gt;, Func&amp;lt;T, TSource&amp;gt;) -&amp;gt; Func&amp;lt;T, TResult&amp;gt;
    public static Func&amp;lt;T, TResult&amp;gt; Apply&amp;lt;T, TSource, TResult&amp;gt;(
        this Func&amp;lt;T, Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, Func&amp;lt;T, TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; Func&amp;lt;T, TSource&amp;gt;
    public static Func&amp;lt;T, TSource&amp;gt; Func&amp;lt;T, TSource&amp;gt;(this TSource value) =&amp;gt; Unit&amp;lt;T&amp;gt;().Select(unit =&amp;gt; value);
}

public static partial class OptionalExtensions // Optional&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;Optional&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Optional&amp;lt;T1&amp;gt; x Optional&amp;lt;T2&amp;gt; -&amp;gt; Optional&amp;lt;T1 x T2&amp;gt;
    // Multiply: (Optional&amp;lt;T1&amp;gt;, Optional&amp;lt;T2&amp;gt;) -&amp;gt; Optional&amp;lt;(T1, T2)&amp;gt;
    public static Optional&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(this Optional&amp;lt;T1&amp;gt; source1, Optional&amp;lt;T2&amp;gt; source2) =&amp;gt;
        new Optional&amp;lt;(T1, T2)&amp;gt;(() =&amp;gt; source1.HasValue &amp;amp;&amp;amp; source2.HasValue
            ? (true, (source1.Value, source2.Value))
            : (false, (default, default)));

    // Unit: Unit -&amp;gt; Optional&amp;lt;Unit&amp;gt;
    public static Optional&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt;
        new Optional&amp;lt;Unit&amp;gt;(() =&amp;gt; (true, unit));
}

public static partial class OptionalExtensions // Optional&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;Optional&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (Optional&amp;lt;TSource -&amp;gt; TResult&amp;gt;, Optional&amp;lt;TSource&amp;gt;) -&amp;gt; Optional&amp;lt;TResult&amp;gt;
    public static Optional&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this Optional&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, Optional&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2));

    // Wrap: TSource -&amp;gt; Optional&amp;lt;TSource&amp;gt;
    public static Optional&amp;lt;T&amp;gt; Optional&amp;lt;T&amp;gt;(this T value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ValueTuple&amp;lt;&amp;gt; and Task&amp;lt;&amp;gt; functors are monoidal/applicative functors too. Notice their Multiply/Apply methods cannot defer the execution, and Task&amp;lt;&amp;gt;’s Multiply/Apply methods are impure.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;ValueTuple&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: ValueTuple&amp;lt;T1&amp;gt; x ValueTuple&amp;lt;T2&amp;gt; -&amp;gt; ValueTuple&amp;lt;T1 x T2&amp;gt;
    // Multiply: (ValueTuple&amp;lt;T1&amp;gt;, ValueTuple&amp;lt;T2&amp;gt;) -&amp;gt; ValueTuple&amp;lt;(T1, T2)&amp;gt;
    public static ValueTuple&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(this ValueTuple&amp;lt;T1&amp;gt; source1, ValueTuple&amp;lt;T2&amp;gt; source2) =&amp;gt;
        new ValueTuple&amp;lt;(T1, T2)&amp;gt;((source1.Item1, source2.Item1)); // Immediate execution.

    // Unit: Unit -&amp;gt; ValueTuple&amp;lt;Unit&amp;gt;
    public static ValueTuple&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt; new ValueTuple&amp;lt;Unit&amp;gt;(unit);
}

public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;ValueTuple&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (ValueTuple&amp;lt;TSource -&amp;gt; TResult&amp;gt;, ValueTuple&amp;lt;TSource&amp;gt;) -&amp;gt; ValueTuple&amp;lt;TResult&amp;gt;
    public static ValueTuple&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this ValueTuple&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, ValueTuple&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2)); // Immediate execution.

    // Wrap: TSource -&amp;gt; ValueTuple&amp;lt;TSource&amp;gt;
    public static ValueTuple&amp;lt;T&amp;gt; ValueTuple&amp;lt;T&amp;gt;(this T value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}

public static partial class TaskExtensions // Task&amp;lt;T&amp;gt; : IMonoidalFunctor&amp;lt;Task&amp;lt;&amp;gt;&amp;gt;
{
    // Multiply: Task&amp;lt;T1&amp;gt; x Task&amp;lt;T2&amp;gt; -&amp;gt; Task&amp;lt;T1 x T2&amp;gt;
    // Multiply: (Task&amp;lt;T1&amp;gt;, Task&amp;lt;T2&amp;gt;) -&amp;gt; Task&amp;lt;(T1, T2)&amp;gt;
    public static async Task&amp;lt;(T1, T2)&amp;gt; Multiply&amp;lt;T1, T2&amp;gt;(this Task&amp;lt;T1&amp;gt; source1, Task&amp;lt;T2&amp;gt; source2) =&amp;gt;
        ((await source1), (await source2)); // Immediate execution, impure.

    // Unit: Unit -&amp;gt; Task&amp;lt;Unit&amp;gt;
    public static Task&amp;lt;Unit&amp;gt; Unit(Unit unit = default) =&amp;gt; System.Threading.Tasks.Task.FromResult(unit);
}

public static partial class TaskExtensions // Task&amp;lt;T&amp;gt; : IApplicativeFunctor&amp;lt;Task&amp;lt;&amp;gt;&amp;gt;
{
    // Apply: (Task&amp;lt;TSource -&amp;gt; TResult&amp;gt;, Task&amp;lt;TSource&amp;gt;) -&amp;gt; Task&amp;lt;TResult&amp;gt;
    public static Task&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this Task&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorWrapper, Task&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2)); // Immediate execution, impure.

    // Wrap: TSource -&amp;gt; Task&amp;lt;TSource&amp;gt;
    public static Task&amp;lt;T&amp;gt; Task&amp;lt;T&amp;gt;(this T value) =&amp;gt; Unit().Select(unit =&amp;gt; value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is easy to verify all the above (Multiply, Unit) method pairs preserve the monoid laws, and all the above (Apply, Wrap) method pairs satisfy the applicative laws. However, not any (Multiply, Unit) or any (Apply, Wrap) can automatically satisfy the laws. Take the ValueTuple&amp;lt;T,&amp;gt; functor as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T1, T2 : IMonoidalFunctor&amp;lt;ValueTuple&amp;lt;T,&amp;gt;&amp;gt;
{
    // Multiply: ValueTuple&amp;lt;T, T1&amp;gt; x ValueTuple&amp;lt;T, T2&amp;gt; -&amp;gt; ValueTuple&amp;lt;T, T1 x T2&amp;gt;
    // Multiply: (ValueTuple&amp;lt;T, T1&amp;gt;, ValueTuple&amp;lt;T, T2&amp;gt;) -&amp;gt; ValueTuple&amp;lt;T, (T1, T2)&amp;gt;
    public static (T, (T1, T2)) Multiply&amp;lt;T, T1, T2&amp;gt;(this (T, T1) source1, (T, T2) source2) =&amp;gt;
        (source1.Item1, (source1.Item2, source2.Item2)); // Immediate execution.

    // Unit: Unit -&amp;gt; ValueTuple&amp;lt;Unit&amp;gt;
    public static (T, Unit) Unit&amp;lt;T&amp;gt;(Unit unit = default) =&amp;gt; (default, unit);
}

public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T, TResult&amp;gt; : IApplicativeFunctor&amp;lt;ValueTuple&amp;lt;T,&amp;gt;&amp;gt;
{
    // Apply: (ValueTuple&amp;lt;T, TSource -&amp;gt; TResult&amp;gt;, ValueTuple&amp;lt;T, TSource&amp;gt;) -&amp;gt; ValueTuple&amp;lt;T, TResult&amp;gt;
    public static (T, TResult) Apply&amp;lt;T, TSource, TResult&amp;gt;(
        this (T, Func&amp;lt;TSource, TResult&amp;gt;) selectorWrapper, (T, TSource) source) =&amp;gt;
            selectorWrapper.Multiply(source).Select(product =&amp;gt; product.Item1(product.Item2)); // Immediate execution.

    // Wrap: TSource -&amp;gt; ValueTuple&amp;lt;T, TSource&amp;gt;
    public static (T, TSource) ValueTuple&amp;lt;T, TSource&amp;gt;(this TSource value) =&amp;gt; Unit&amp;lt;T&amp;gt;().Select(unit =&amp;gt; value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above (Multiply, Unit) implementations cannot preserve the left unit law:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MonoidalFunctorLaws()
{
    (string, int) source = (&quot;a&quot;, 1);
    (string, Unit) unit = Unit&amp;lt;string&amp;gt;();
    (string, int) source1 = (&quot;b&quot;, 2);
    (string, char) source2 = (&quot;c&quot;, &apos;@&apos;);
    (string, bool) source3 = (&quot;d&quot;, true);

    // Associativity preservation: source1.Multiply(source2).Multiply(source3).Select(Associator) == source1.Multiply(source2.Multiply(source3)).
    source1.Multiply(source2).Multiply(source3).Select(Associator).WriteLine(); // (b, (2, (@, True)))
    source1.Multiply(source2.Multiply(source3)).WriteLine(); // (b, (2, (@, True)))
    // Left unit preservation: unit.Multiply(source).Select(LeftUnitor) == source.
    unit.Multiply(source).Select(LeftUnitor).WriteLine(); // (, 1)
    // Right unit preservation: source == source.Multiply(unit).Select(RightUnitor).
    source.Multiply(unit).Select(RightUnitor).WriteLine(); // (a, 1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the above (Apply, Wrap) implementation breaks all applicative laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ApplicativeLaws()
{
    (string, int) source = (&quot;a&quot;, 1);
    Func&amp;lt;int, double&amp;gt; selector = int32 =&amp;gt; Math.Sqrt(int32);
    (string, Func&amp;lt;int, double&amp;gt;) selectorWrapper1 = 
        (&quot;b&quot;, new Func&amp;lt;int, double&amp;gt;(int32 =&amp;gt; Math.Sqrt(int32)));
    (string, Func&amp;lt;double, string&amp;gt;) selectorWrapper2 =
        (&quot;c&quot;, new Func&amp;lt;double, string&amp;gt;(@double =&amp;gt; @double.ToString(&quot;0.00&quot;)));
    Func&amp;lt;Func&amp;lt;double, string&amp;gt;, Func&amp;lt;Func&amp;lt;int, double&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; o = 
        new Func&amp;lt;Func&amp;lt;double, string&amp;gt;, Func&amp;lt;int, double&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;(Linq.FuncExtensions.o).Curry();
    int value = 5;

    // Functor preservation: source.Select(selector) == selector.Wrap().Apply(source).
    source.Select(selector).WriteLine(); // (a, 1)
    selector.ValueTuple&amp;lt;string, Func&amp;lt;int, double&amp;gt;&amp;gt;().Apply(source).WriteLine(); // (, 1)
    // Identity preservation: Id.Wrap().Apply(source) == source.
    new Func&amp;lt;int, int&amp;gt;(Functions.Id).ValueTuple&amp;lt;string, Func&amp;lt;int, int&amp;gt;&amp;gt;().Apply(source).WriteLine(); // (, 1)
    // Composition preservation: o.Curry().Wrap().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source) == selectorWrapper2.Apply(selectorWrapper1.Apply(source)).
    o.ValueTuple&amp;lt;string, Func&amp;lt;Func&amp;lt;double, string&amp;gt;, Func&amp;lt;Func&amp;lt;int, double&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;&amp;gt;()
        .Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source).WriteLine(); // (, 1.00)
    selectorWrapper2.Apply(selectorWrapper1.Apply(source)).WriteLine(); // (c, 1.00)
    // Homomorphism: selector.Wrap().Apply(value.Wrap()) == selector(value).Wrap().
    selector.ValueTuple&amp;lt;string, Func&amp;lt;int, double&amp;gt;&amp;gt;().Apply(value.ValueTuple&amp;lt;string, int&amp;gt;()).WriteLine(); // (, 2.23606797749979)
    selector(value).ValueTuple&amp;lt;string, double&amp;gt;().WriteLine(); // (, 2.23606797749979)
    // Interchange: selectorWrapper.Apply(value.Wrap()) == (selector =&amp;gt; selector(value)).Wrap().Apply(selectorWrapper).
    selectorWrapper1.Apply(value.ValueTuple&amp;lt;string, int&amp;gt;()).WriteLine(); // (b, 2.23606797749979)
    new Func&amp;lt;Func&amp;lt;int, double&amp;gt;, double&amp;gt;(function =&amp;gt; function(value))
        .ValueTuple&amp;lt;string, Func&amp;lt;Func&amp;lt;int, double&amp;gt;, double&amp;gt;&amp;gt;().Apply(selectorWrapper1).WriteLine(); // (, 2.23606797749979)
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (5) Bifunctor</title><link>https://dixin.github.io/posts/category-theory-via-csharp-5-bifunctor/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-5-bifunctor/</guid><description>A functor is the mapping from 1 object to another object, with a “Select” ability to map 1 morphism to another morphism. A [bifunctor](http://en.wikipedia.org/wiki/Functor#Bifunctors_and_multifunctors</description><pubDate>Sun, 15 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Bifunctor&lt;/h2&gt;
&lt;p&gt;A functor is the mapping from 1 object to another object, with a “Select” ability to map 1 morphism to another morphism. A &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor#Bifunctors_and_multifunctors&quot;&gt;bifunctor&lt;/a&gt; (binary functor), as the name implies, is the mapping from 2 objects and from 2 morphisms. Giving category C, D and E, bifunctor F from category C, D to E is a structure-preserving morphism from C, D to E, denoted F: C × D → E:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image1.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image1_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F maps objects X ∈ ob(C), Y ∈ ob(D) to object F(X, Y) ∈ ob(E)&lt;/li&gt;
&lt;li&gt;F also maps morphisms mC: X → X’ ∈ hom(C), mD: Y → Y’ ∈ hom(D) to morphism mE: F(X, Y) → F(X’, Y’) ∈ hom(E)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In DotNet category, bifunctors are binary endofunctors, and can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IBifunctor&amp;lt;TBifunctor&amp;lt;,&amp;gt;&amp;gt; where TBifunctor&amp;lt;,&amp;gt; : IBifunctor&amp;lt;TBifunctor&amp;lt;,&amp;gt;&amp;gt;
{
    Func&amp;lt;TBifunctor&amp;lt;TSource1, TSource2&amp;gt;, TBifunctor&amp;lt;TResult1, TResult2&amp;gt;&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        Func&amp;lt;TSource1, TResult1&amp;gt; selector1, Func&amp;lt;TSource2, TResult2&amp;gt; selector2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The most intuitive built-in bifunctor is ValueTuple&amp;lt;,&amp;gt;. Apparently ValueTuple&amp;lt;,&amp;gt; can be viewed as a type constructor of kind * –&amp;gt; * –&amp;gt; *, which accepts 2 concrete types to and return another concrete type. Its Select implementation is also straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T1, T2&amp;gt; : IBifunctor&amp;lt;ValueTuple&amp;lt;,&amp;gt;&amp;gt;
{
    // Bifunctor Select: (TSource1 -&amp;gt; TResult1, TSource2 -&amp;gt; TResult2) -&amp;gt; (ValueTuple&amp;lt;TSource1, TSource2&amp;gt; -&amp;gt; ValueTuple&amp;lt;TResult1, TResult2&amp;gt;).
    public static Func&amp;lt;ValueTuple&amp;lt;TSource1, TSource2&amp;gt;, ValueTuple&amp;lt;TResult1, TResult2&amp;gt;&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        Func&amp;lt;TSource1, TResult1&amp;gt; selector1, Func&amp;lt;TSource2, TResult2&amp;gt; selector2) =&amp;gt; source =&amp;gt;
            Select(source, selector1, selector2);

    // LINQ-like Select: (ValueTuple&amp;lt;TSource1, TSource2&amp;gt;, TSource1 -&amp;gt; TResult1, TSource2 -&amp;gt; TResult2) -&amp;gt; ValueTuple&amp;lt;TResult1, TResult2&amp;gt;).
    public static ValueTuple&amp;lt;TResult1, TResult2&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        this ValueTuple&amp;lt;TSource1, TSource2&amp;gt; source,
        Func&amp;lt;TSource1, TResult1&amp;gt; selector1,
        Func&amp;lt;TSource2, TResult2&amp;gt; selector2) =&amp;gt;
            (selector1(source.Item1), selector2(source.Item2));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, similar to ValueTuple&amp;lt;&amp;gt; functor’s Select method, ValueTuple&amp;lt;,&amp;gt; bifunctor’s Select method has to call selector1 and selector2 immediately. To implement deferred execution, the following Lazy&amp;lt;,&amp;gt; bifunctor can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Lazy&amp;lt;T1, T2&amp;gt;
{
    private readonly Lazy&amp;lt;(T1, T2)&amp;gt; lazy;

    public Lazy(Func&amp;lt;(T1, T2)&amp;gt; factory) =&amp;gt; this.lazy = new Lazy&amp;lt;(T1, T2)&amp;gt;(factory);

    public T1 Value1 =&amp;gt; this.lazy.Value.Item1;

    public T2 Value2 =&amp;gt; this.lazy.Value.Item2;

    public override string ToString() =&amp;gt; this.lazy.Value.ToString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lazy&amp;lt;,&amp;gt; is simply the lazy version of ValueTuple&amp;lt;,&amp;gt;. Jut like Lazy&amp;lt;&amp;gt;, Lazy&amp;lt;,&amp;gt; can be constructed with a factory function, so that the call to selector1 and selector2 are deferred:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LazyExtensions // Lazy&amp;lt;T1, T2&amp;gt; : IBifunctor&amp;lt;Lazy&amp;lt;,&amp;gt;&amp;gt;
{
    // Bifunctor Select: (TSource1 -&amp;gt; TResult1, TSource2 -&amp;gt; TResult2) -&amp;gt; (Lazy&amp;lt;TSource1, TSource2&amp;gt; -&amp;gt; Lazy&amp;lt;TResult1, TResult2&amp;gt;).
    public static Func&amp;lt;Lazy&amp;lt;TSource1, TSource2&amp;gt;, Lazy&amp;lt;TResult1, TResult2&amp;gt;&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        Func&amp;lt;TSource1, TResult1&amp;gt; selector1, Func&amp;lt;TSource2, TResult2&amp;gt; selector2) =&amp;gt; source =&amp;gt;
            Select(source, selector1, selector2);

    // LINQ-like Select: (Lazy&amp;lt;TSource1, TSource2&amp;gt;, TSource1 -&amp;gt; TResult1, TSource2 -&amp;gt; TResult2) -&amp;gt; Lazy&amp;lt;TResult1, TResult2&amp;gt;).
    public static Lazy&amp;lt;TResult1, TResult2&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        this Lazy&amp;lt;TSource1, TSource2&amp;gt; source,
        Func&amp;lt;TSource1, TResult1&amp;gt; selector1,
        Func&amp;lt;TSource2, TResult2&amp;gt; selector2) =&amp;gt;
            new Lazy&amp;lt;TResult1, TResult2&amp;gt;(() =&amp;gt; (selector1(source.Value1), selector2(source.Value2)));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monoidal category&lt;/h2&gt;
&lt;p&gt;With the help of bifunctor, &lt;a href=&quot;http://en.wikipedia.org/wiki/Monoidal_category&quot;&gt;monoidal category&lt;/a&gt; can be defined. A &lt;a href=&quot;http://en.wikipedia.org/wiki/Monoidal_category&quot;&gt;monoidal category&lt;/a&gt; is a category C equipped with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A bifunctor ⊗ as the monoid binary multiplication operation: bifunctor ⊗ maps 2 objects in C to another object in C, denoted C ⊗ C → C, which is also called the &lt;a href=&quot;http://en.wikipedia.org/wiki/Tensor_product&quot;&gt;monoidal product&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Tensor_product&quot;&gt;tensor product&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An unit object I ∈ ob(C) as the monoid unit, also called tensor unit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For (C, ⊗, I) to be a monoid, it also needs to be equipped with the following natural transformations, so that the monoid laws are satisfied:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associator αX, Y, Z: (X ⊗ Y) ⊗ Z ⇒ X ⊗ (Y ⊗ Z) for the associativity law, where X, Y, Z ∈ ob(C)&lt;/li&gt;
&lt;li&gt;Left unitor λX: I ⊗ X ⇒ X for the left unit law, and right unitor ρX: X ⊗ I ⇒ X for the right unit law, where X ∈ ob(C)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following monoid triangle identity and pentagon identity diagrams still commute for monoidal category:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Bifunctor_548F/image_thumb12_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Bifunctor_548F/image_thumb12_thumb_thumb.png&quot; alt=&quot;image_thumb12_thumb&quot; title=&quot;image_thumb12_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Bifunctor_548F/Untitled-2.fw_thumb_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Bifunctor_548F/Untitled-2.fw_thumb_thumb_thumb.png&quot; alt=&quot;Untitled-2.fw_thumb_thumb&quot; title=&quot;Untitled-2.fw_thumb_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here for monoidal category, the above ⊙ (general multiplication operator) becomes ⊗ (bifunctor).&lt;/p&gt;
&lt;p&gt;Monoidal category can be simply defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IMonoidalCategory&amp;lt;TObject, TMorphism&amp;gt; : ICategory&amp;lt;TObject, TMorphism&amp;gt;, IMonoid&amp;lt;TObject&amp;gt; { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DotNet category is monoidal category, with the most intuitive bifunctor ValueTuple&amp;lt;,&amp;gt; as the monoid multiplication, and Unit type as the monoid unit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class DotNetCategory : IMonoidalCategory&amp;lt;Type, Delegate&amp;gt;
{
    public static Type Multiply(Type value1, Type value2) =&amp;gt; typeof(ValueTuple&amp;lt;,&amp;gt;).MakeGenericType(value1, value2);

    public static Type Unit =&amp;gt; typeof(Unit);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To have (DotNet, ValueTuple&amp;lt;,&amp;gt;, Unit) satisfy the monoid laws, the associator, left unitor and right unitor are easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class DotNetCategory
{
    // Associator: (T1 x T2) x T3 -&amp;gt; T1 x (T2 x T3)
    // Associator: ValueTuple&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;, T3&amp;gt; -&amp;gt; ValueTuple&amp;lt;T1, ValueTuple&amp;lt;T2, T3&amp;gt;&amp;gt;
    public static (T1, (T2, T3)) Associator&amp;lt;T1, T2, T3&amp;gt;(((T1, T2), T3) product) =&amp;gt;
        (product.Item1.Item1, (product.Item1.Item2, product.Item2));

    // LeftUnitor: Unit x T -&amp;gt; T
    // LeftUnitor: ValueTuple&amp;lt;Unit, T&amp;gt; -&amp;gt; T
    public static T LeftUnitor&amp;lt;T&amp;gt;((Unit, T) product) =&amp;gt; product.Item2;

    // RightUnitor: T x Unit -&amp;gt; T
    // RightUnitor: ValueTuple&amp;lt;T, Unit&amp;gt; -&amp;gt; T
    public static T RightUnitor&amp;lt;T&amp;gt;((T, Unit) product) =&amp;gt; product.Item1;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (4) Natural Transformation</title><link>https://dixin.github.io/posts/category-theory-via-csharp-4-natural-transformation/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-4-natural-transformation/</guid><description>If F: C → D and G: C → D are both functors from categories C to category D, the mapping from F to G is called  and denoted</description><pubDate>Sat, 14 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Natural transformation and naturality&lt;/h2&gt;
&lt;p&gt;If F: C → D and G: C → D are both functors from categories C to category D, the mapping from F to G is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Natural_transformation&quot;&gt;natural transformation&lt;/a&gt; and denoted α: F ⇒ G. α: F ⇒ G is actually family of morphisms from F to G, For each object X in category C, there is a specific morphism αX: F(X) → G(X) in category D, called the component of α at X. For each morphism m: X → Y in category C and 2 functors F: C → D, G: C → D, there is a naturality square in D:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In another word, for m: X → Y in category C, there must be αY ∘ F(m) ≡ G(m) ∘ αX , or equivalently αY ∘ SelectF(m) ≡ SelectG(m) ∘ αX in category D.&lt;/p&gt;
&lt;p&gt;In DotNet category, the following ToLazy&amp;lt;&amp;gt; generic method transforms Func&amp;lt;&amp;gt; functor to Lazy&amp;lt;&amp;gt; functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NaturalTransformations
{
    // ToLazy: Func&amp;lt;&amp;gt; -&amp;gt; Lazy&amp;lt;&amp;gt;
    public static Lazy&amp;lt;T&amp;gt; ToLazy&amp;lt;T&amp;gt;(this Func&amp;lt;T&amp;gt; function) =&amp;gt; new Lazy&amp;lt;T&amp;gt;(function);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, for above natural transformation: ToLazy&amp;lt;&amp;gt;: Func&amp;lt;&amp;gt; ⇒ Lazy&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;for each specific object T, there is an object Func&amp;lt;T&amp;gt;, an object Lazy&amp;lt;T&amp;gt;, and a morphism ToFunc&amp;lt;T&amp;gt;: Func&amp;lt;T&amp;gt; → Lazy&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For each specific morphism selector: TSource → TResult, there is a naturality square, which consists of 4 morphisms:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ToLazy&amp;lt;TResult&amp;gt;: Func&amp;lt;TResult&amp;gt; → Lazy&amp;lt;TResult&amp;gt;, which is the component of ToLazy&amp;lt;&amp;gt; at TResult&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FuncExtensions.Select(selector): Func&amp;lt;TSource&amp;gt; → Func&amp;lt;TResult&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LazyExtensions.Select(selector): Lazy&amp;lt;TSource&amp;gt; → Lazy&amp;lt;TResult&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ToLazy&amp;lt;TSource&amp;gt;: Func&amp;lt;TSource&amp;gt; → Lazy&amp;lt;TSource&amp;gt;, which is the component of ToLazy&amp;lt;&amp;gt; at TSource&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following example is a simple naturality square that commutes for ToLazy&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Naturality()
{
    Func&amp;lt;int, string&amp;gt; selector = int32 =&amp;gt; Math.Sqrt(int32).ToString(&quot;0.00&quot;);

    // Naturality square:
    // ToFunc&amp;lt;string&amp;gt;.o(LazyExtensions.Select(selector)) == FuncExtensions.Select(selector).o(ToFunc&amp;lt;int&amp;gt;)
    Func&amp;lt;Func&amp;lt;string&amp;gt;, Lazy&amp;lt;string&amp;gt;&amp;gt; funcStringToLazyString = ToLazy&amp;lt;string&amp;gt;;
    Func&amp;lt;Func&amp;lt;int&amp;gt;, Func&amp;lt;string&amp;gt;&amp;gt; funcInt32ToFuncString = FuncExtensions.Select(selector);
    Func&amp;lt;Func&amp;lt;int&amp;gt;, Lazy&amp;lt;string&amp;gt;&amp;gt; leftComposition = funcStringToLazyString.o(funcInt32ToFuncString);
    Func&amp;lt;Lazy&amp;lt;int&amp;gt;, Lazy&amp;lt;string&amp;gt;&amp;gt; lazyInt32ToLazyString = LazyExtensions.Select(selector);
    Func&amp;lt;Func&amp;lt;int&amp;gt;, Lazy&amp;lt;int&amp;gt;&amp;gt; funcInt32ToLazyInt32 = ToLazy&amp;lt;int&amp;gt;;
    Func&amp;lt;Func&amp;lt;int&amp;gt;, Lazy&amp;lt;string&amp;gt;&amp;gt; rightComposition = lazyInt32ToLazyString.o(funcInt32ToLazyInt32);

    Func&amp;lt;int&amp;gt; funcInt32 = () =&amp;gt; 2;
    Lazy&amp;lt;string&amp;gt; lazyString = leftComposition(funcInt32);
    lazyString.Value.WriteLine(); // 1.41
    lazyString = rightComposition(funcInt32);
    lazyString.Value.WriteLine(); // 1.41
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following are a few more examples of natural transformations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ToFunc: Lazy&amp;lt;T&amp;gt; -&amp;gt; Func&amp;lt;T&amp;gt;
public static Func&amp;lt;T&amp;gt; ToFunc&amp;lt;T&amp;gt;(this Lazy&amp;lt;T&amp;gt; lazy) =&amp;gt; () =&amp;gt; lazy.Value;

// ToEnumerable: Func&amp;lt;T&amp;gt; -&amp;gt; IEnumerable&amp;lt;T&amp;gt;
public static IEnumerable&amp;lt;T&amp;gt; ToEnumerable&amp;lt;T&amp;gt;(this Func&amp;lt;T&amp;gt; function)
{
    yield return function();
}

// ToEnumerable: Lazy&amp;lt;T&amp;gt; -&amp;gt; IEnumerable&amp;lt;T&amp;gt;
public static IEnumerable&amp;lt;T&amp;gt; ToEnumerable&amp;lt;T&amp;gt;(this Lazy&amp;lt;T&amp;gt; lazy)
{
    yield return lazy.Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Functor Category&lt;/h2&gt;
&lt;p&gt;Now there are functors, and mappings between functors, which are natural transformations. Naturally, they lead to category of functors. Given 2 categories C and D, there is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor_category&quot;&gt;functor category&lt;/a&gt;, denoted DC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Its objects ob(DC) are the functors from category C to D .&lt;/li&gt;
&lt;li&gt;Its morphisms hom(DC) are the natural transformations between those functors.&lt;/li&gt;
&lt;li&gt;The composition of natural transformations α: F ⇒ G and β: G ⇒ H, is natural transformations (β ∘ α): F ⇒ H.&lt;/li&gt;
&lt;li&gt;The identity natural transformation idF: F ⇒ F maps each functor to itself&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Regarding the category laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity law: As fore mentioned, natural transformation’s components are morphisms in D, so natural transformation composition in DC can be viewed as morphism composition in D: (β ∘ α)X: F(X) → H(X) = (βX: G(X) → H(X)) ∘ (αX: F(X) → G(X)). Natural transformations’ composition in DC is associative, since all component morphisms’ composition in D is associative&lt;/li&gt;
&lt;li&gt;Identity law: similarly, identity natural transform’s components are the id morphisms idF(X): F(X) → F(X) in D. Identity natural transform satisfy identity law, since all its components satisfy identity law.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example of natural transformations composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ToFunc: Lazy&amp;lt;T&amp;gt; -&amp;gt; Func&amp;lt;T&amp;gt;
public static Func&amp;lt;T&amp;gt; ToFunc&amp;lt;T&amp;gt;(this Lazy&amp;lt;T&amp;gt; lazy) =&amp;gt; () =&amp;gt; lazy.Value;
#endif

// ToOptional: Func&amp;lt;T&amp;gt; -&amp;gt; Optional&amp;lt;T&amp;gt;
public static Optional&amp;lt;T&amp;gt; ToOptional&amp;lt;T&amp;gt;(this Func&amp;lt;T&amp;gt; function) =&amp;gt;
    new Optional&amp;lt;T&amp;gt;(() =&amp;gt; (true, function()));

// ToOptional: Lazy&amp;lt;T&amp;gt; -&amp;gt; Optional&amp;lt;T&amp;gt;
public static Optional&amp;lt;T&amp;gt; ToOptional&amp;lt;T&amp;gt;(this Lazy&amp;lt;T&amp;gt; lazy) =&amp;gt;
    // new Func&amp;lt;Func&amp;lt;T&amp;gt;, Optional&amp;lt;T&amp;gt;&amp;gt;(ToOptional).o(new Func&amp;lt;Lazy&amp;lt;T&amp;gt;, Func&amp;lt;T&amp;gt;&amp;gt;(ToFunc))(lazy);
    lazy.ToFunc().ToOptional();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Endofunctor category&lt;/h3&gt;
&lt;p&gt;Given category C, there is a endofunctors category, denoted CC, or End(C), where the objects are the endofunctors from category C to C itself, and the morphisms are the natural transformations between those endofunctors.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/public-static-partial-class-Optio.------_E2EC/image3_thumb_thumb.png&quot; alt=&quot;image3_thumb&quot; title=&quot;image3_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;All the functors in C# are endofunctors from DotNet category to DotNet. They are the objects of endofunctor category DotNetDotNet or End(DotNet).&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (3) Functor and LINQ to Functors</title><link>https://dixin.github.io/posts/category-theory-via-csharp-3-functor-and-linq-to-functors/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-3-functor-and-linq-to-functors/</guid><description>In category theory,  is a ) from category to category. Giving category C and D, functor F from</description><pubDate>Fri, 13 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Functor and functor laws&lt;/h2&gt;
&lt;p&gt;In category theory, &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor&quot;&gt;functor&lt;/a&gt; is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Map_(mathematics)&quot;&gt;mapping&lt;/a&gt; from category to category. Giving category C and D, functor F from category C to D is a structure-preserving morphism from C to D, denoted F: C → D:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-3-Functor_DC22/image6_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-3-Functor_DC22/image6_thumb_thumb.png&quot; alt=&quot;image6_thumb&quot; title=&quot;image6_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F maps objects in C to objects in D, for example, X, Y, Z, … ∈ ob(C) are mapped to F(X), F(Y), F(Z), … ∈ in ob(D)&lt;/li&gt;
&lt;li&gt;F also maps morphisms in C to morphisms in D, for example, m: X → Y ∈ hom(C) is mapped to morphism F(m): F(X) → F(Y) ∈ hom(D). In this tutorial, to align to C#/.NET terms, this morphism mapping capability of functor is also called “select”. so F(m) is also denoted SelectF(m).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And F must satisfy the following functor laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Composition preservation: F(m2 ∘ m1) ≡ F(m2) ∘ F(m1), or SelectF(m2 ∘ m1) ≡ SelectF(m2) ∘ SelectF(m1), F maps composition in C to composition in D&lt;/li&gt;
&lt;li&gt;Identity preservation: F(idX) ≡ idF(X), or SelectF(idX) ≡ idF(X), F maps each identity morphism in C to identity morphism in D &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-3-Functor_DC22/image3_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-3-Functor_DC22/image3_thumb_thumb.png&quot; alt=&quot;image3_thumb&quot; title=&quot;image3_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Endofunctor&lt;/h3&gt;
&lt;p&gt;When a functor F’s source category and target category are the same category C, it is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor#Examples&quot;&gt;endofunctor&lt;/a&gt;, denoted F: C → C. In the DotNet category, there are endofunctors mapping objects (types) and morphisms (functions) in DotNet category to other objects and morphisms in itself. In C#, endofunctor in DotNet can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt; where TFunctor&amp;lt;&amp;gt; : IFunctor&amp;lt;TFunctor&amp;gt;
{
    Func&amp;lt;TFunctor&amp;lt;TSource&amp;gt;, TFunctor&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In DotNet category, objects are types, so the functor’s type mapping capability is represented by generic type TFunctor&amp;lt;&amp;gt;, which maps type T to another type TFunctor&amp;lt;T&amp;gt;. And in DotNet category, morphisms are functions, so the functor’s function mapping capability is represented by the Select method, which maps function of type TSource –&amp;gt; TResult to another function of type TFunctor&amp;lt;TSource&amp;gt; –&amp;gt; TFunctor&amp;lt;TResult&amp;gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, the above interface cannot be compiled, because C#/.NET do not support &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_class#Higher-kinded_polymorphism&quot;&gt;higher-kinded polymorphism&lt;/a&gt; for types.&lt;/p&gt;
&lt;h3&gt;Type constructor and higher-kinded type&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Kind_(type_theory)&quot;&gt;Kind&lt;/a&gt; is the meta type of a type:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A concrete type has the simplest kind, denoted *. All non generic types (types without type parameters) are of kind *. Closed generic types (types with concrete type arguments) are also concrete types of kind *.&lt;/li&gt;
&lt;li&gt;An open generic type definition with type parameter can be viewed as a type constructor, which works like a function. For example, IEnumerable&amp;lt;&amp;gt; can accept a type of kind * (like int), and return another closed type of kind * (like IEnumerable&amp;lt;int&amp;gt;), so IEnumerable&amp;lt;&amp;gt; is a type constructor, its kind is denoted * –&amp;gt; *; ValueTuple&amp;lt;,&amp;gt; can accept 2 types of kind * (like string and bool), and return another closed type of kind * (like ValueTuple&amp;lt;string, bool&amp;gt;) so ValueTuple&amp;lt;,&amp;gt; is a type constructor, its kind is denoted (*, *) –&amp;gt; *, or * –&amp;gt; * –&amp;gt; * in curried style.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In above IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt; generic type definition, its type parameter TFunctor&amp;lt;&amp;gt; is an open generic type of kind * –&amp;gt; *. As a result, IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt; can be viewed as a type constructor, which works like a higher-order function, accepting a TFunctor&amp;lt;&amp;gt; type constructor of kind * –&amp;gt; *, and returning a concrete type of kind *. So IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt; is of kind (* –&amp;gt; *) –&amp;gt; *. This is called a higher-kinded type, and not supported by .NET and C# compiler. In another word, C# generic type definition does not support its type parameter to have type parameters. In C#, functor support is implemented by LINQ query comprehensions instead of type system.&lt;/p&gt;
&lt;h2&gt;LINQ to Functors&lt;/h2&gt;
&lt;h3&gt;Built-in IEnumerable&amp;lt;&amp;gt; functor&lt;/h3&gt;
&lt;p&gt;IEnumerable&amp;lt;&amp;gt; is a built-in functor of DotNet category, which can be viewed as virtually implementing above IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;T&amp;gt; : IFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;, IEnumerable
{
    // Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Endofunctor IEnumerable&amp;lt;&amp;gt; in DotNet category maps each T object (type) to IEnumerable&amp;lt;T&amp;gt; object (type), and its Select method maps TSource→ TResult morphism (function) to IEnumerable&amp;lt;TSource&amp;gt; → IEnumerable&amp;lt;TResult&amp;gt; morphism (function). So its Select method is of type (TSource –&amp;gt; TResult) –&amp;gt; (IEnumerable&amp;lt;TSource&amp;gt; –&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;), which can be uncurried to (TSource –&amp;gt; TResult, IEnumerable&amp;lt;TSource&amp;gt;) –&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;T&amp;gt; : IFunctor&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;, IEnumerable
{
    // Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);
    // can be equivalently converted to:
    // IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector, IEnumerable&amp;lt;TSource&amp;gt; source);

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now swap the 2 parameters of the uncurried Select, then its type becomes (IEnumerable&amp;lt;TSource&amp;gt;, TSource –&amp;gt; TResult) –&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;T&amp;gt; : IFunctor&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;, IEnumerable
{
    // Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(Func&amp;lt;TSource, TResult&amp;gt; selector);
    // can be equivalently converted to:
    // IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET, this equivalent version of Select is exactly the LINQ query method Select. The following is the comparison of functor Select method and LINQ Select method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableExtensions // IEnumerable&amp;lt;T&amp;gt; : IFunctor&amp;lt;IEnumerable&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;).
    public static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt; 
            Select(source, selector);

    // 1. Uncurry to Select: (TSource -&amp;gt; TResult, IEnumerable&amp;lt;TSource&amp;gt;) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;.
    // 2. Swap 2 parameters to Select: (IEnumerable&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; IEnumerable&amp;lt;TResult&amp;gt;.
    // 3. Define as LINQ extension method.
    public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
    {
        foreach (TSource value in source)
        {
            yield return selector(value);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the IEnumerable&amp;lt;&amp;gt; functor’s morphism mapping capability is implemented as the LINQ mapping query. As a part of the LINQ query expression pattern, functor support is built in in the C# language:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Map()
{
    IEnumerable&amp;lt;int&amp;gt; source = System.Linq.Enumerable.Range(0, 5);
    // Map int to string.
    Func&amp;lt;int, string&amp;gt; selector = Convert.ToString;
    // Map IEnumerable&amp;lt;int&amp;gt; to IEnumerable&amp;lt;string&amp;gt;.
    IEnumerable&amp;lt;string&amp;gt; query = from value in source
                                select selector(value); // Define query.
    query.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the above Select implementation satisfies the functor laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// using static Dixin.Linq.CategoryTheory.Functions;
internal static void FunctorLaws()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 0, 1, 2, 3, 4 };
    Func&amp;lt;int, double&amp;gt; selector1 = int32 =&amp;gt; Math.Sqrt(int32);
    Func&amp;lt;double, string&amp;gt; selector2 = @double =&amp;gt; @double.ToString(&quot;0.00&quot;);

    // Associativity preservation: source.Select(selector2.o(selector1)) == source.Select(selector1).Select(selector2).
    (from value in source
        select selector2.o(selector1)(value)).WriteLines();  // 0.00 1.00 1.41 1.73 2.00
    (from value in source
        select selector1(value) into value
        select selector2(value)).WriteLines();  // 0.00 1.00 1.41 1.73 2.00
    // Identity preservation: source.Select(Id) == Id(source).
    (from value in source
        select Id(value)).WriteLines(); // 0 1 2 3 4
    Id(source).WriteLines(); // 0 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Functor pattern of LINQ&lt;/h3&gt;
&lt;p&gt;So LINQ Select mapping query’s quintessential mathematics is functor. Generally, in DotNet category, a type is a functor if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This type is an open generic type definition, which can be viewed as type constructor of kind * –&amp;gt; *, so that it maps a concrete type T to another concrete functor-wrapped type.&lt;/li&gt;
&lt;li&gt;It is equipped with the standard LINQ query method Select, which can be either instance method or extension method.&lt;/li&gt;
&lt;li&gt;The implementation of Select satisfies the functor laws, so that DotNet category’s associativity law and identity law are preserved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other hand, to enable the LINQ functor query expression (single from clauses with select clause) for a type does not require that type to be strictly a functor. This LINQ syntax can be enabled for any generic or non generic type with as long as it has such a Select method, , which can be virtually demonstrated as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
internal static void Map&amp;lt;TFunctor&amp;lt;&amp;gt;, TSource, TResult&amp;gt;( // Non generic TFunctor can work too.
    TFunctor&amp;lt;TSource&amp;gt; functor, Func&amp;lt;TSource, TResult&amp;gt; selector) where TFunctor&amp;lt;&amp;gt; : IFunctor&amp;lt;TFunctor&amp;lt;&amp;gt;&amp;gt;
{
    TFunctor&amp;lt;TResult&amp;gt; query = from /* TSource */ value in /* TFunctor&amp;lt;TSource&amp;gt; */ functor
                              select /* TResult */ selector(value); // Define query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More LINQ to Functors&lt;/h2&gt;
&lt;p&gt;Many other open generic type definitions provided by .NET can be functor. Take Lazy&amp;lt;&amp;gt; as example, first, apparently it is a type constructor of kind * –&amp;gt; *. Then, its Select query method can be defined as extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LazyExtensions // Lazy&amp;lt;T&amp;gt; : IFunctor&amp;lt;Lazy&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Lazy&amp;lt;TSource&amp;gt; -&amp;gt; Lazy&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;Lazy&amp;lt;TSource&amp;gt;, Lazy&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector);

    // LINQ Select: (Lazy&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Lazy&amp;lt;TResult&amp;gt;
    public static Lazy&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this Lazy&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; selector(source.Value));

    internal static void Map()
    {
        Lazy&amp;lt;int&amp;gt; source = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; 1);
        // Map int to string.
        Func&amp;lt;int, string&amp;gt; selector = Convert.ToString;
        // Map Lazy&amp;lt;int&amp;gt; to Lazy&amp;lt;string&amp;gt;.
        Lazy&amp;lt;string&amp;gt; query = from value in source
                             select selector(value); // Define query.
        string result = query.Value; // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;&amp;gt; with 1 type parameter is also a functor with the following Select implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions // Func&amp;lt;T&amp;gt; : IFunctor&amp;lt;Func&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Func&amp;lt;TSource&amp;gt; -&amp;gt; Func&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;Func&amp;lt;TSource&amp;gt;, Func&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector);

    // LINQ Select: (Func&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Func&amp;lt;TResult&amp;gt;
    public static Func&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this Func&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            () =&amp;gt; selector(source());

    internal static void Map()
    {
        Func&amp;lt;int&amp;gt; source = () =&amp;gt; 1;
        // Map int to string.
        Func&amp;lt;int, string&amp;gt; selector = Convert.ToString;
        // Map Func&amp;lt;int&amp;gt; to Func&amp;lt;string&amp;gt;.
        Func&amp;lt;string&amp;gt; query = from value in source
                             select selector(value); // Define query.
        string result = query(); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Select maps TSource –&amp;gt; TResult function to Func&amp;lt;TSource&amp;gt; –&amp;gt; Func&amp;lt;TResult&amp;gt; function, which is straightforward. The other Func generic delegate types, like Func&amp;lt;,&amp;gt; with 2 type parameters, could be more interesting. Just like fore mentioned ValueTuple&amp;lt;,&amp;gt;, Func&amp;lt;,&amp;gt; is of kind * –&amp;gt; * –&amp;gt; *, and can be viewed as a type constructor accepting 2 concrete types and returning another concrete type, which is different from functor. However, if Func&amp;lt;,&amp;gt; already has a concrete type T as its first type parameter, then Func&amp;lt;T,&amp;gt; can be viewed as a partially applied type constructor of kind * –&amp;gt; *, which can map one concrete type (its second type parameter) to another concrete type. So that Func&amp;lt;T,&amp;gt; is also a functor, with the following Select method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions // Func&amp;lt;T, TResult&amp;gt; : IFunctor&amp;lt;Func&amp;lt;T,&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Func&amp;lt;T, TSource&amp;gt; -&amp;gt; Func&amp;lt;T, TResult&amp;gt;)
    public static Func&amp;lt;Func&amp;lt;T, TSource&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt; Select&amp;lt;T, TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector);

    // LINQ Select: (Func&amp;lt;T, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Func&amp;lt;T, TResult&amp;gt;
    public static Func&amp;lt;T, TResult&amp;gt; Select&amp;lt;T, TSource, TResult&amp;gt;(
        this Func&amp;lt;T, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            value =&amp;gt; selector(source(value)); // selector.o(source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time Select maps TSource –&amp;gt; TResult function to Func&amp;lt;T, TSource&amp;gt; –&amp;gt; Func&amp;lt;T, TResult&amp;gt; function. Actually, Func&amp;lt;T,&amp;gt; functor’s Select is exactly the function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Map&amp;lt;T&amp;gt;(T input)
{
    Func&amp;lt;T, string&amp;gt; source = value =&amp;gt; value.ToString();
    // Map string to bool.
    Func&amp;lt;string, bool&amp;gt; selector = string.IsNullOrWhiteSpace;
    // Map Func&amp;lt;T, string&amp;gt; to Func&amp;lt;T, bool&amp;gt;.
    Func&amp;lt;T, bool&amp;gt; query = from value in source
                          select selector(value); // Define query.
    bool result = query(input); // Execute query.

    // Equivalent to:
    Func&amp;lt;T, string&amp;gt; function1 = source;
    Func&amp;lt;string, bool&amp;gt; function2 = selector;
    Func&amp;lt;T, bool&amp;gt; composition = function2.o(function1);
    result = composition(input);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ValueTuple&amp;lt;&amp;gt; with 1 type parameter simply wraps a value. It is the eager version of Lazy&amp;lt;&amp;gt;, and it is also functor, with the following Select method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T&amp;gt; : IFunctor&amp;lt;ValueTuple&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (ValueTuple&amp;lt;TSource&amp;gt; -&amp;gt; ValueTuple&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;ValueTuple&amp;lt;TSource&amp;gt;, ValueTuple&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector); // Immediate execution.

    // LINQ Select: (ValueTuple&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; ValueTuple&amp;lt;TResult&amp;gt;
    public static ValueTuple&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this ValueTuple&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            new ValueTuple&amp;lt;TResult&amp;gt;(selector(source.Item1)); // Immediate execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unlike all the previous Select, here ValueTuple&amp;lt;&amp;gt;’s Select query method cannot implement deferred execution. To construct a ValueTuple&amp;lt;TResult&amp;gt; instance and return, selector must be called immediately to evaluate the result value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Map()
{
    ValueTuple&amp;lt;int&amp;gt; source = new ValueTuple&amp;lt;int&amp;gt;(1);
    // Map int to string.
    Func&amp;lt;int, string&amp;gt; selector = int32 =&amp;gt;
        {
            $&quot;{nameof(selector)} is called with {int32}.&quot;.WriteLine();
            return Convert.ToString(int32);
        };
    // Map ValueTuple&amp;lt;int&amp;gt; to ValueTuple&amp;lt;string&amp;gt;.
    ValueTuple&amp;lt;string&amp;gt; query = from value in source // Define and execute query.
                                select selector(value); // selector is called with 1.
    string result = query.Item1; // Query result.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to Func&amp;lt;T,&amp;gt;, ValueTuple&amp;lt;T,&amp;gt; is also functor, with the following Select method of immediate execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ValueTupleExtensions // ValueTuple&amp;lt;T, T2&amp;gt; : IFunctor&amp;lt;ValueTuple&amp;lt;T,&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (ValueTuple&amp;lt;T, TSource&amp;gt; -&amp;gt; ValueTuple&amp;lt;T, TResult&amp;gt;)
    public static Func&amp;lt;(T, TSource), (T, TResult)&amp;gt; Select&amp;lt;T, TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector); // Immediate execution.

    // LINQ Select: (ValueTuple&amp;lt;T, TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; ValueTuple&amp;lt;T, TResult&amp;gt;
    public static (T, TResult) Select&amp;lt;T, TSource, TResult&amp;gt;(
        this(T, TSource) source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            (source.Item1, selector(source.Item2)); // Immediate execution.

    internal static void Map&amp;lt;T&amp;gt;(T item1)
    {
        (T, int) source = (item1, 1);
        // Map int to string.
        Func&amp;lt;int, string&amp;gt; selector = int32 =&amp;gt;
        {
            $&quot;{nameof(selector)} is called with {int32}.&quot;.WriteLine();
            return Convert.ToString(int32);
        };
        // Map ValueTuple&amp;lt;T, int&amp;gt; to ValueTuple&amp;lt;T, string&amp;gt;.
        (T, string) query = from value in source // Define and execute query.
                            select selector(value); // selector is called with 1.
        string result = query.Item2; // Query result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Task is also an example of functor, with the following Select method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TaskExtensions // Task&amp;lt;T&amp;gt; : IFunctor&amp;lt;Task&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Task&amp;lt;TSource&amp;gt; -&amp;gt; Task&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;Task&amp;lt;TSource&amp;gt;, Task&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector); // Immediate execution, impure.

    // LINQ Select: (Task&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Task&amp;lt;TResult&amp;gt;
    public static async Task&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this Task&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            selector(await source); // Immediate execution, impure.

    internal static async Task MapAsync()
    {
        Task&amp;lt;int&amp;gt; source = System.Threading.Tasks.Task.FromResult(1);
        // Map int to string.
        Func&amp;lt;int, string&amp;gt; selector = Convert.ToString;
        // Map Task&amp;lt;int&amp;gt; to Task&amp;lt;string&amp;gt;.
        Task&amp;lt;string&amp;gt; query = from value in source
                             select selector(value); // Define and execute query.
        string result = await query; // Query result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to ValueTuple&amp;lt;&amp;gt;, above Select implementation is not deferred either. When Select is called, if the source task is already completed, the selector function is called immediately. And unlike all the previous Select methods are pure (referential transparent and side effect free), this Select use the await syntactic sugar to construct a state machine and start it immediately. So it changes state and is impure.&lt;/p&gt;
&lt;p&gt;Nullable&amp;lt;&amp;gt; is also an interesting type. It is of kind * –&amp;gt; * and the following Select method can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NullableExtensions // Nullable&amp;lt;T&amp;gt; : IFunctor&amp;lt;Nullable&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Nullable&amp;lt;TSource&amp;gt; -&amp;gt; Nullable&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;TSource?, TResult?&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) where TSource : struct where TResult : struct =&amp;gt; source =&amp;gt;
            Select(source, selector); // Immediate execution.

    // LINQ Select: (Nullable&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Nullable&amp;lt;TResult&amp;gt;
    public static TResult? Select&amp;lt;TSource, TResult&amp;gt;(
        this TSource? source, Func&amp;lt;TSource, TResult&amp;gt; selector) where TSource : struct where TResult : struct =&amp;gt;
            source.HasValue ? selector(source.Value) : default; // Immediate execution.

    internal static void Map()
    {
        long? source1 = 1L;
        // Map int to string.
        Func&amp;lt;long, TimeSpan&amp;gt; selector = TimeSpan.FromTicks;
        // Map Nullable&amp;lt;int&amp;gt; to Nullable&amp;lt;TimeSpan&amp;gt;.
        TimeSpan? query1 = from value in source1
                           select selector(value); // Define and execute query.
        TimeSpan result1 = query1.Value; // Query result.

        long? source2 = null;
        // Map Nullable&amp;lt;int&amp;gt; to Nullable&amp;lt;TimeSpan&amp;gt;.
        TimeSpan? query2 = from value in source2
                           select selector(value); // Define and execute query.
        bool result2 = query2.HasValue; // Query result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above Select method, if the source Nullable&amp;lt;TSource&amp;gt; instance represents an actual value of TSource, that value is extracted to call selector, and the result is wrapped into another Nullable&amp;lt;TResult&amp;gt; instance to return; if the source represents null, selector is not called, and a Nullable&amp;lt;TResult&amp;gt; instance representing null is directly returned. There are 2 issues here. First, Nullable&amp;lt;&amp;gt;’s type parameter is constrained to be structures, so it can only map some objects of DotNet category (the value types). Second, the Select implementation cannot be deferred. As LINQ query method, deferred execution is always preferred whenever possible. So the following Optional&amp;lt;T&amp;gt; type can be defined to be used with any type parameter, and also be lazy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public readonly struct Optional&amp;lt;T&amp;gt;
{
    private readonly Lazy&amp;lt;(bool, T)&amp;gt; factory;

    public Optional(Func&amp;lt;(bool, T)&amp;gt; factory = null) =&amp;gt;
        this.factory = factory == null ? null : new Lazy&amp;lt;(bool, T)&amp;gt;(factory);

    public bool HasValue =&amp;gt; this.factory?.Value.Item1 ?? false;

    public T Value
    {
        get
        {
            if (!this.HasValue)
            {
                throw new InvalidOperationException($&quot;{nameof(Optional&amp;lt;T&amp;gt;)} object must have a value.&quot;);
            }
            return this.factory.Value.Item2;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optional&amp;lt;T&amp;gt; is still a structure just like Nullable&amp;lt;T&amp;gt;, so its instance cannot be null. Its parameter is not constrained, so it can wrap any valid or invalid value of any type, Its constructor accepts a factory function just like Lazy&amp;lt;&amp;gt;, s the evaluation of its wrapped value can be deferred. And the factory function returns a tuple of bool value and T value, where the bool value indicates if the other T value is a valid value, and that bool value can be returned by the the HasValue property.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Optional()
{
    int int32 = 1;
    Func&amp;lt;int, string&amp;gt; function = Convert.ToString;

    Nullable&amp;lt;int&amp;gt; nullableInt32 = new Nullable&amp;lt;int&amp;gt;(int32);
    Nullable&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt; nullableFunction = new Nullable&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt;(function); // Cannot be compiled.
    Nullable&amp;lt;string&amp;gt; nullableString = new Nullable&amp;lt;string&amp;gt;(); // Cannot be compiled.

    Optional&amp;lt;int&amp;gt; optionalInt32 = new Optional&amp;lt;int&amp;gt;(() =&amp;gt; (true, int32));
    Optional&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt; optionalFunction = new Optional&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt;(() =&amp;gt; true, function));
    Optional&amp;lt;string&amp;gt; optionalString = new Optional&amp;lt;string&amp;gt;(); // Equivalent to: new Optional&amp;lt;string&amp;gt;(() =&amp;gt; false, default);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, Optional&amp;lt;&amp;gt; is a factor, and its Select can be defined with deferred execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class OptionalExtensions // Optional&amp;lt;T&amp;gt; : IFunctor&amp;lt;Optional&amp;lt;&amp;gt;&amp;gt;
{
    // Functor Select: (TSource -&amp;gt; TResult) -&amp;gt; (Optional&amp;lt;TSource&amp;gt; -&amp;gt; Optional&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;Optional&amp;lt;TSource&amp;gt;, Optional&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; source =&amp;gt;
            Select(source, selector);

    // LINQ Select: (Optional&amp;lt;TSource&amp;gt;, TSource -&amp;gt; TResult) -&amp;gt; Optional&amp;lt;TResult&amp;gt;
    public static Optional&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        this Optional&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            new Optional&amp;lt;TResult&amp;gt;(() =&amp;gt; source.HasValue
                ? (true, selector(source.Value)) : (false, default));

    internal static void Map()
    {
        Optional&amp;lt;int&amp;gt; source1 = new Optional&amp;lt;int&amp;gt;(() =&amp;gt; (true, 1));
        // Map int to string.
        Func&amp;lt;int, string&amp;gt; selector = Convert.ToString;
        // Map Optional&amp;lt;int&amp;gt; to Optional&amp;lt;string&amp;gt;.
        Optional&amp;lt;string&amp;gt; query1 = from value in source1
                                    select selector(value); // Define query.
        if (query1.HasValue) // Execute query.
        {
            string result1 = query1.Value;
        }

        Optional&amp;lt;int&amp;gt; source2 = new Optional&amp;lt;int&amp;gt;();
        // Map Optional&amp;lt;int&amp;gt; to Optional&amp;lt;string&amp;gt;.
        Optional&amp;lt;string&amp;gt; query2 = from value in source2
                                    select selector(value); // Define query.
        if (query2.HasValue) // Execute query.
        {
            string result2 = query2.Value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is easy to verify all the above Select methods satisfy the functor laws. However, not any Select can automatically satisfy the functor laws. The following is a different Select implementation for Lazy&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Lazy&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this Lazy&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
        new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; default);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it breaks the functor because it does not preserve the identity law:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctorLaws()
{
    Lazy&amp;lt;int&amp;gt; lazy = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; 1);
    Func&amp;lt;int, string&amp;gt; selector1 = Convert.ToString;
    Func&amp;lt;string, double&amp;gt; selector2 = Convert.ToDouble;

    // Associativity preservation: TFunctor&amp;lt;T&amp;gt;.Select(f2.o(f1)) == TFunctor&amp;lt;T&amp;gt;.Select(f1).Select(f2)
    lazy.Select(selector2.o(selector1)).Value.WriteLine(); // 0
    lazy.Select(selector1).Select(selector2).Value.WriteLine(); // 0
    // Identity preservation: TFunctor&amp;lt;T&amp;gt;.Select(Id) == Id(TFunctor&amp;lt;T&amp;gt;)
    lazy.Select(Id).Value.WriteLine(); // 0
    Id(lazy).Value.WriteLine(); // 1
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (2) Monoid</title><link>https://dixin.github.io/posts/category-theory-via-csharp-2-monoid/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-2-monoid/</guid><description>) is an important algebraic structure in category theory. A monoid M is a set M equipped with a binary operation ⊙ and a special element</description><pubDate>Thu, 12 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Monoid and monoid laws&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Monoid_(category_theory)&quot;&gt;Monoid&lt;/a&gt; is an important algebraic structure in category theory. A monoid M is a set M equipped with a binary operation ⊙ and a special element I, denoted 3-tuple (M, ⊙, I), where&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;M is a set of elements&lt;/li&gt;
&lt;li&gt;⊙ is a binary operator called multiplication, so that M ⊙ M → M, which means the multiplication of 2 elements in set M always results an element in set M. This operation is also denoted μ, so that μ(M, M) ≡ M ⊙ M.&lt;/li&gt;
&lt;li&gt;I is a special unit element (aka neutral element, or identity element) in set M&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the binary operator and the unit element must satisfy the following monoid laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;associative law αX, Y, Z: (X ⊙ Y) ⊙ Z ≡ X ⊙ (Y ⊙ Z), where X ∈ M, Y ∈ M, Z ∈ M&lt;/li&gt;
&lt;li&gt;left unit law λX: I ⊙ X ≡ X, where X ∈ M; and right unit law ρX: X ≡ X ⊙ I, where X ∈ M&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the triangle identity commutes: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and the pentagon identity commutes:: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/Untitled-2.fw_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/Untitled-2.fw_thumb.png&quot; alt=&quot;Untitled-2.fw&quot; title=&quot;Untitled-2.fw&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C#, the monoid definition can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IMonoid&amp;lt;T&amp;gt;
{
    static abstract T Multiply(T value1, T value2);

    static abstract T Unit { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An intuitive example is the set ℤ of all integers, with binary operator + and unit element 0. The addition of 2 integers always results another integer; Also for integers x, y ,z, there is (x + y) + z ≡ x + (y + z) and 0 + x ≡ x ≡ x + 0 (ℤ, +, 0), so that (ℤ, +, 0) is monoid. Apparently (ℤ, *, 1) is monoid too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Int32SumMonoid : IMonoid&amp;lt;int&amp;gt;
{
    public static int Multiply(int value1, int value2) =&amp;gt; value1 + value2;

    public static int Unit =&amp;gt; GenericIndirection.AdditiveUnit&amp;lt;int&amp;gt;(); // 0.
}

public class Int32ProductMonoid : IMonoid&amp;lt;int&amp;gt;
{
    public static int Multiply(int value1, int value2) =&amp;gt; value1 * value2;

    public static int Unit =&amp;gt; GenericIndirection.MultiplicativeUnit&amp;lt;int&amp;gt;(); // 1.
}

public static class GenericIndirection
{
    public static T AdditiveUnit&amp;lt;T&amp;gt;() where T : IAdditiveIdentity&amp;lt;T, T&amp;gt; =&amp;gt; T.AdditiveIdentity;

    public static T MultiplicativeUnit&amp;lt;T&amp;gt;() where T : IMultiplicativeIdentity&amp;lt;T, T&amp;gt; =&amp;gt; T.MultiplicativeIdentity;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another monoid example is (string, string.Concat, string.Empty):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class StringConcatMonoid : IMonoid&amp;lt;string&amp;gt;
{
    public static string Multiply(string value1, string value2) =&amp;gt; string.Concat(value1, value2);

    public static string Unit =&amp;gt; string.Empty;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here string can be viewed as a sequence of char, and the unit string is an empty sequence. Generally, (IEnumerable&amp;lt;T&amp;gt;, Enumerable.Concat&amp;lt;T&amp;gt;, Enumerable.Empty&amp;lt;T&amp;gt;()) is a monoid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class EnumerableConcatMonoid&amp;lt;T&amp;gt; : IMonoid&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;
{
    public static IEnumerable&amp;lt;T&amp;gt; Multiply(IEnumerable&amp;lt;T&amp;gt; value1, IEnumerable&amp;lt;T&amp;gt; value2) =&amp;gt; value1.Concat(value2);

    public static IEnumerable&amp;lt;T&amp;gt; Unit =&amp;gt; Enumerable.Empty&amp;lt;T&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The set of Boolean values { true, false }, with binary operator &amp;amp;&amp;amp; and unit element true, is a monoid with only 2 element: ({true, false}, &amp;amp;&amp;amp;, true); And so is ({ true, false }, ||, false):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class BooleanAndMonoid : IMonoid&amp;lt;bool&amp;gt;
{
    public static bool Multiply(bool value1, bool value2) =&amp;gt; value1 &amp;amp;&amp;amp; value2;

    public static bool Unit =&amp;gt; true;
}

public class BooleanOrMonoid : IMonoid&amp;lt;bool&amp;gt;
{
    public static bool Multiply(bool value1, bool value2) =&amp;gt; value1 || value2;

    public static bool Unit =&amp;gt; false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A monoid with 1 single element can be defined with the special type void (System.Void):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [ComVisible(true)]
    [Serializable]
    [StructLayout(LayoutKind.Sequential, Size = 1)]
    public struct Void
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The set { default(void) } with the following operator and unit is a monoid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class VoidMonoid : IMonoid&amp;lt;void&amp;gt;
{
    public void Multiply(void value1, void value2) =&amp;gt; default;

    public void Unit() =&amp;gt; default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, C# compiler does not allow void keyword or System.Void type to be used in this way, so here System.Void can be replaced with its equivalency in F#, the Microsoft.FSharp.Core.Unit type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.FSharp.Core
{
    [CompilationMapping(SourceConstructFlags.ObjectType)]
    [Serializable]
    public sealed class Unit : IComparable
    {
        internal Unit() { }

        public override int GetHashCode() =&amp;gt; 0;

        public override bool Equals(object obj) =&amp;gt; 
            obj == null || LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric&amp;lt;Unit&amp;gt;(obj);

        int IComparable.CompareTo(object obj) =&amp;gt; 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With an internal constructor, Unit cannot be instantiated, a Unit variable can only be default(Unit), which is null. So similarly, set { default(Unit) } with the following operator and unit element is monoid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class UnitMonoid : IMonoid&amp;lt;Unit&amp;gt;
{
    public static Unit Multiply(Unit value1, Unit value2) =&amp;gt; default;

    public static Unit Unit =&amp;gt; default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monoid as category&lt;/h2&gt;
&lt;p&gt;An individual monoid (M, ⊙, I) can be a category C with 1 single object M, where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The collection of objects ob(C) is { M }, which means, category C has 1 single object, that is M.&lt;/li&gt;
&lt;li&gt;The collection of orphisms hom(C) is set M itself, which mean, each elements in set M is a morphism in category C.&lt;/li&gt;
&lt;li&gt;The composition operation ∘ of C is ⊙: since each morphism in C is each element in M, the composition of morphisms is just the multiplication of elements.&lt;/li&gt;
&lt;li&gt;The identity morphism id of C is unit element I: the identity morphism in C is the unit element in M&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this way, since M, ⊙, I satisfies the monoid laws, apparently the category laws are satisfied. In C#, this singleton category can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MonoidCategory&amp;lt;T, TMonoid&amp;gt; : ICategory&amp;lt;Type, T&amp;gt; where TMonoid : IMonoid&amp;lt;T&amp;gt;
{
    public static IEnumerable&amp;lt;Type&amp;gt; Objects { get { yield return typeof(TMonoid); } }

    public static T Compose(T morphism2, T morphism1) =&amp;gt; TMonoid.Multiply(morphism1, morphism2);

    public static T Id(Type @object) =&amp;gt; TMonoid.Unit;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (1) Fundamentals</title><link>https://dixin.github.io/posts/category-theory-via-csharp-1-fundamentals/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-csharp-1-fundamentals/</guid><description>Category theory is a theoretical framework to describe abstract structures and relations in mathematics, first introduced by  and [Saun</description><pubDate>Sun, 01 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Category theory is a theoretical framework to describe abstract structures and relations in mathematics, first introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Samuel_Eilenberg&quot;&gt;Samuel Eilenberg&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Saunders_Mac_Lane&quot;&gt;Saunders Mac Lane&lt;/a&gt; in 1940s. It examines mathematical concepts and properties in an abstract way, by formalizing them as collections of items and their relations. Category theory is abstract, and called &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Abstract_nonsense&quot;&gt;general abstract nonsense&lt;/a&gt;&quot; by &lt;a href=&quot;https://en.wikipedia.org/wiki/Norman_Steenrod&quot;&gt;Norman Steenrod&lt;/a&gt;; It is also general, therefore widely applied in many areas in mathematics, physics, and computer science, etc. For programming, category theory is the algebraic theory of types and functions, and also the rationale and foundation of LINQ and any functional programming. This chapter discusses category theory and its important concepts, including category, morphism, natural transform, monoid, functor, and monad, etc. These general abstract concepts will be demonstrated with intuitive diagrams and specific C# and LINQ examples. These knowledge also helps building a deep understanding of functional programming in C# or other languages, since any language with types and functions is a category-theoretic structure.&lt;/p&gt;
&lt;h2&gt;Category and category laws&lt;/h2&gt;
&lt;p&gt;In category theory, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Category_(mathematics)&quot;&gt;category&lt;/a&gt; C is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Algebraic_structure&quot;&gt;algebraic structure&lt;/a&gt; consists of the following 3 kinds of mathematical entities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A collection of objects, denoted ob(C). This is not the &lt;a href=&quot;http://en.wikipedia.org/wiki/Object_(computer_science)&quot;&gt;objects&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;object-oriented programming paradigm&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A collection of morphisms (relations, aka arrows or maps) between objects, denoted hom(C). A morphism m from source object X to target object Y is denoted m: X → Y.&lt;/li&gt;
&lt;li&gt;A composition operation of morphisms, denoted ∘. For m1: X → Y and m2: Y → Z, their composition is also a morphism (m2∘ m1): Y → Z. Here the name of m1 of m2 also implies the order. m2 ∘ m1 can be read as m2 after m1. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And these entities must satisfy the following 2 category laws:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associative law: the composition of morphisms &lt;a href=&quot;http://en.wikipedia.org/wiki/Associativity&quot;&gt;associative&lt;/a&gt;: For m1: W → X, m2: X → Y and m3: Y → Z, there is (m3 ∘ m2) ∘ m1≡ ≡ m3 ∘ (m2 ∘ m1).&lt;/li&gt;
&lt;li&gt;Identity law: for each object X, there is an &lt;a href=&quot;http://en.wikipedia.org/wiki/Identity_function&quot;&gt;identity&lt;/a&gt; morphism: idx : X → X, and identity morphism is neutral for morphism composition. For m: X → Y, there is idY ∘ m ≡ m ≡ m ∘ idX. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_9.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make above abstract definitions intuitive, a category can be represented by the following interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ICategory&amp;lt;TObject, TMorphism&amp;gt;
{
    static abstract IEnumerable&amp;lt;TObject&amp;gt; Objects { get; }

    static abstract TMorphism Compose(TMorphism morphism2, TMorphism morphism1);

    static abstract TMorphism Id(TObject @object);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A simple example of category is the category of integers, where the collection of objects are all integers, and the collection of morphisms are ≤ (less than or equal to) relations, from an integer either to itself, or to another integer greater than or equal to it, for example: m1: 0 → 1 (0 ≤ 1), m2: 1 → 10 (1 ≤ 10), etc. Regarding the transitivity of inequality, the ≤ morphisms can be composed, for example, m1: 0 → 1 (0 ≤ 1) and m2: 1 → 10 (1 ≤ 10) can be composed to another morphism (m2 ∘ m1): 0 → 10 (0 ≤ 10).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/248e0c9c0941_E1F4/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/248e0c9c0941_E1F4/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/248e0c9c0941_E1F4/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/248e0c9c0941_E1F4/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Apparently, the above composition is associative, foe example: ((1 ≤ 10) ∘ (0 ≤ 1)) ∘ (-1 ≤ 0) ≡ -1 ≤ 10 ≡ (1 ≤ 10) ∘ ((0 ≤ 1) ∘ (-1 ≤ 0)). And for each integer X, there is an identity morphism idX: X → X (X ≤ X), and (Y ≤ Y) ∘ (X ≤ Y) ≡ X ≤ Y ≡ (X ≤ Y) ∘ (X ≤ X). So the category laws are satisfied. In C#, integer can be represented by int, and the morphism of ≤ relation can be represented by a BinaryExpression of node type LessThanOrEqual, so the category can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Int32Category : ICategory&amp;lt;int, BinaryExpression&amp;gt;
{
    public static IEnumerable&amp;lt;int&amp;gt; Objects
    {
        get
        {
            for (int int32 = int.MinValue; int32 &amp;lt;= int.MaxValue; int32++)
            {
                yield return int32;
            }
        }
    }

    public static BinaryExpression Compose(BinaryExpression morphism2, BinaryExpression morphism1) =&amp;gt;
        Expression.LessThanOrEqual(morphism2.Left, morphism1.Right); // (Y &amp;lt;= Z) ∘ (X &amp;lt;= Y) =&amp;gt; X &amp;lt;= Z.

    public static BinaryExpression Id(int @object) =&amp;gt;
        Expression.GreaterThanOrEqual(Expression.Constant(@object), Expression.Constant(@object)); // X &amp;lt;= X.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DotNet category&lt;/h2&gt;
&lt;p&gt;.NET can also be viewed as a category of types and functions, called DotNet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ob(DotNet): the collection of objects in DotNet category are .NET types, like string (System.String), int (System.Int32), bool (System.Boolean), etc.&lt;/li&gt;
&lt;li&gt;hom(DotNet): the collection of morphisms in DotNet category are .NET pure functions between the input type (source object) to the output type (target object), like int.Parse: string → int, DateTime.IsLeapYear: int → bool, etc.&lt;/li&gt;
&lt;li&gt;∘: in DotNet category, the composition operation of morphisms is the composition of functions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As already discussed in lambda calculus chapter, function composition is associative, and the unit function Id is the identity morphism:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Functions
{
    public static Func&amp;lt;TSource, TResult&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;(
        this Func&amp;lt;TMiddle, TResult&amp;gt; function2, Func&amp;lt;TSource, TMiddle&amp;gt; function1) =&amp;gt;
            value =&amp;gt; function2(function1(value));

    public static TSource Id&amp;lt;TSource&amp;gt;(T value) =&amp;gt; value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the category laws are satisfied.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_11.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The DotNet category can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class DotNetCategory : ICategory&amp;lt;Type, Delegate&amp;gt;
{
    public static IEnumerable&amp;lt;Type&amp;gt; Objects =&amp;gt; AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(assembly =&amp;gt; assembly.ExportedTypes);

    public static Delegate Compose(Delegate morphism2, Delegate morphism1) =&amp;gt;
        // return (Func&amp;lt;TSource, TResult&amp;gt;)Functions.Compose&amp;lt;TSource, TMiddle, TResult&amp;gt;(
        //    (Func&amp;lt;TMiddle, TResult&amp;gt;)morphism2, (Func&amp;lt;TSource, TMiddle&amp;gt;)morphism1);
        (Delegate)typeof(Tutorial.FuncExtensions).GetMethod(nameof(Tutorial.FuncExtensions.o))
            .MakeGenericMethod( // TSource, TMiddle, TResult.
                morphism1.Method.GetParameters().Single().ParameterType,
                morphism1.Method.ReturnType,
                morphism2.Method.ReturnType)
            .Invoke(null, new object[] { morphism2, morphism1 });

    public static Delegate Id(Type @object) =&amp;gt; // Functions.Id&amp;lt;TSource&amp;gt;
        typeof(Functions).GetMethod(nameof(Functions.Id)).MakeGenericMethod(@object)
            .CreateDelegate(typeof(Func&amp;lt;,&amp;gt;).MakeGenericType(@object, @object));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In DotNet category, each object is a type represented by System.Type, so Objects method queries all available types in current assembly, and also recursively query all available assemblies in all reference assemblies. And each morphism is a function from one type to another, which can be represented by System.Delegate, so the composition is just to call the o operator with 2 Delegate instances.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (8) Undecidability of Equivalence</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-24-undecidability-of-equivalence/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-24-undecidability-of-equivalence/</guid><description>All the previous parts demonstrated what  can do – defining functions to model the computing, applying functions to execute the computing</description><pubDate>Thu, 28 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;All the previous parts demonstrated what &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; can do – defining functions to model the computing, applying functions to execute the computing, implementing recursion, encoding data types and data structures, etc. Lambda calculus is a powerful tool, and it is Turing complete. This part discuss some interesting problem that cannot be done with lambda calculus – asserting whether 2 lambda expressions are equivalent.&lt;/p&gt;
&lt;p&gt;Assuming f1 and f2 are 2 functions, they are equivalent if for ∀x, there is f1 x ≡ f2 x. For example, the following 2 functions can &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-2-fundamentals-lambda-expression-variables-reductions&quot;&gt;alpha-convert&lt;/a&gt; to each other:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f1 := λx.Add x 1
f2 := λy.Add y 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently they are equivalent. And they are both equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f3 := λx.Add 1 x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;because Add is commutative. &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Undecidability_of_equivalence&quot;&gt;Undecidability of equivalence&lt;/a&gt; means, in lambda calculus, there is no function can takes 2 lambda expressions as input, and returns True/False to indicate whether those 2 lambda expressions are equivalent or not. &lt;a href=&quot;http://www.joachim-breitner.de/various/ChurchTalk2011.pdf&quot;&gt;Alonzo Church has a proof&lt;/a&gt; using &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Normal_forms_and_confluence&quot;&gt;normal form&lt;/a&gt;. An intuitive proof can be done by viewing equivalence problem as another version of &lt;a href=&quot;http://en.wikipedia.org/wiki/Halting_problem&quot;&gt;halting problem&lt;/a&gt;. Actually, Alonzo Church’s publish on equivalence is earlier (April 1936) than Alan Turing’s publish on halting problem (May 1936). To make it simple, this part discusses the undecidability of halting problem first, then discuss the undecidability of equivalence.&lt;/p&gt;
&lt;h2&gt;Halting problem&lt;/h2&gt;
&lt;p&gt;The halting problem is the problem of determining, when running an arbitrary program with an input, whether the program halts (finish running) or does not halt (run forever). For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Function Increase halts (finish running) with argument x, and returns x + 1.&lt;/li&gt;
&lt;li&gt;Function &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-20-combinators&quot;&gt;ω does not halt with argument ω&lt;/a&gt;, &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-20-combinators&quot;&gt;Ω := ω ω reduces (runs) forever&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No general algorithm can solve the halting problem for all possible program-input pairs. To prove this, first define a simple function Sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sequence := λa.λb.b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When applying Sequence, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Reduction_strategies&quot;&gt;reduction strategy&lt;/a&gt; matters. In normal order, both its first argument is never reduced. In this part, applicative order is always assumed - the same reduction strategy as C#. So Sequence can be viewed as - reduce (run) a then reduce (run) b sequentially, and return the reduction result of b. When applying Sequence with Ω and another lambda expression. It reduces forever in applicative order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sequence Ω x
≡ Sequence (ω ω) x
≡ Sequence ((λx.x x) (λx.x x)) x
≡ Sequence ((λx.x x) (λx.x x)) x
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because Ω does not halt, Sequence Ω does not halt either. In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Functions&amp;lt;T1, T2&amp;gt;
{
    public static readonly Func&amp;lt;T1, Func&amp;lt;T2, T2&amp;gt;&amp;gt; 
        Sequence = value1 =&amp;gt; value2 =&amp;gt; value2;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assume an IsHalting function exists, which takes 2 parameters f and x, and returns True/False if function f halts/does not halt with parameter x:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsHalting := λf.λx.If (/* f halts with x */) (λx.True) (λx.False)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then an IsNotHalting function can be defined to test whether function f does not halt with argument f (itself):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNotHalting := λf.If (IsHalting f f) (λx.Sequence Ω False) (λx.True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a certain function f does not halt with itself, by definition IsNotHalting f returns True:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNotHalting f
≡ If (IsHalting f f) (λx.Sequence Ω False) (λx.True))
≡ If (False) (λx.Sequence Ω False) (λx.True))
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember the If function is lazy, here λx.Sequence Ω False is never reduced. When f halts with itself, the application reduces to Sequence Ω False:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNotHalting f
≡ If (IsHalting f f) (λx.Sequence Ω False) (λx.True))
≡ If (True) (λx.Sequence Ω False) (λx.True))
≡ Sequence Ω False
≡ Sequence (ω ω) False
≡ Sequence ((λx.x x) (λx.x x)) False
≡ Sequence ((λx.x x) (λx.x x)) False
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, Sequence Ω does not halt. So in this case, IsNotHalting f never returns False.&lt;/p&gt;
&lt;p&gt;In C# IsHalting and IsNotHalting functions can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class Halting&amp;lt;T, TResult&amp;gt;
{
    // IsHalting = f =&amp;gt; x =&amp;gt; True if f halts with x; otherwise, False
    internal static readonly Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;T, Boolean&amp;gt;&amp;gt;
        IsHalting = f =&amp;gt; x =&amp;gt; throw new NotImplementedException();

    // IsNotHalting = f =&amp;gt; If(IsHalting(f)(f))(_ =&amp;gt; Sequence(Ω)(False))(_ =&amp;gt; True)
    internal static readonly Func&amp;lt;SelfApplicableFunc&amp;lt;TResult&amp;gt;, Boolean&amp;gt;
        IsNotHalting = f =&amp;gt;
            If(Halting&amp;lt;SelfApplicableFunc&amp;lt;TResult&amp;gt;, TResult&amp;gt;.IsHalting(new Func&amp;lt;SelfApplicableFunc&amp;lt;TResult&amp;gt;, TResult&amp;gt;(f))(f))
                (_ =&amp;gt; Functions&amp;lt;TResult, Boolean&amp;gt;.Sequence(OmegaCombinators&amp;lt;TResult&amp;gt;.Ω)(False))
                (_ =&amp;gt; True);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here since f can be applied with itself, it is represented with the SelfApplicableFunc&amp;lt;TResult&amp;gt; function type.&lt;/p&gt;
&lt;p&gt;It is interesting when IsNotHalting is applied with argument IsNotHalting (itself). Assume IsNotHalting halts with IsNotHalting, in another word:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsHalting IsNotHalting IsNotHalting
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then there is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNotHalting IsNotHalting
≡ If (IsHalting IsNotHalting IsNotHalting) (λx.Sequence Ω False) (λx.True)
≡ If (True) (λx.Sequence Ω False) (λx.True)
≡ Sequence Ω False
≡ Sequence (ω ω) False
≡ Sequence ((λx.x x) (λx.x x)) False
≡ Sequence ((λx.x x) (λx.x x)) False
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So IsNotHalting IsNotHalting is reduced to Sequence Ω False, and is then reduced forever, which means actually IsNotHalting does not halt with IsNotHalting.&lt;/p&gt;
&lt;p&gt;On the other hand, Assume IsNotHalting does not halt with IsNotHalting, in another word:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsHalting IsNotHalting IsNotHalting
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then there is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNotHalting IsNotHalting
≡ If (IsHalting IsNotHalting IsNotHalting) (λx.Sequence Ω False) (λx.True)
≡ If (False) (λx.Sequence Ω False) (λx.True)
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So IsNotHalting IsNotHalting is reduced to True, which means IsNotHalting halts with IsNotHalting.&lt;/p&gt;
&lt;p&gt;Therefore, if IsHalting exists, it leads to IsNotHalting with the following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If IsNotHalting halts with IsNotHalting, then IsNotHalting does not halt with IsNotHalting&lt;/li&gt;
&lt;li&gt;If IsNotHalting does not halt with IsNotHalting, then IsNotHalting halts with IsNotHalting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This proves IsNotHalting and IsHalting cannot exist.&lt;/p&gt;
&lt;h2&gt;Equivalence problem&lt;/h2&gt;
&lt;p&gt;After understanding the halting problem, the equivalence problem becomes very easy to prove. Assume an AreEquivalent function exists:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AreEquivalent := λa.λb.If (/* a and b are equivalent */) (λx.True) (λx.False)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which takes 2 lambda expression as parameter, and returns True/False if they are/are not equivalent. Now define the following 2 functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GetTrue1 := λf.λx.λy.Sequence (f x) True
GetTrue2 := λf.λx.λy.True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given arbitrary function f and its argument x:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GetTrue1 f x
≡ λy.Sequence (f x) True

  GetTrue2 f x
≡ λy.True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For specified f and x:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if f halts with x, then, ∀y, (GetTrue1 f x y) and (GetTrue2 f x y) both always returns True. That is, partially applied functions GetTrue1 f x and GetTrue2 f x are equivalent.&lt;/li&gt;
&lt;li&gt;if f does not halt with x, then, ∀y, (GetTrue1 f x y) never returns True, and (GetTrue2 f x y) always returns True. That is, partially applied functions (GetTrue1 f x) and (GetTrue2 f x) are not equivalent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now halting problem and equivalence problem are connected. IsHalting function can be directly defined by AreEquivalent function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsHalting := λf.λx.AreEquivalent (GetTrue1 f x) (GetTrue2 f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The partial application (GetTrue1 f x) and (GetTrue2 f x) can be substituted as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsHalting := λf.λx.AreEquivalent (λy.Sequence (f x) True) (λy.True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class Equivalence&amp;lt;T, TResult&amp;gt;
{
    // IsEquivalent = f1 =&amp;gt; f2 =&amp;gt; True if f1 and f2 are equivalent; otherwise, False
    internal static readonly Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Boolean&amp;gt;&amp;gt;
        IsEquivalent = f1 =&amp;gt; f2 =&amp;gt; throw new NotImplementedException();

    // IsHalting = f =&amp;gt; x =&amp;gt; IsEquivalent(_ =&amp;gt; Sequence(f(x))(True))(_ =&amp;gt; True)
    internal static readonly Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;T, Boolean&amp;gt;&amp;gt;
        IsHalting = f =&amp;gt; x =&amp;gt; Equivalence&amp;lt;T, Boolean&amp;gt;.IsEquivalent(_ =&amp;gt; Functions&amp;lt;TResult, Boolean&amp;gt;.Sequence(f(x))(True))(_ =&amp;gt; True);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the above AreEquivalent function can be defined, then IsHalting can be defined. It is already approved that IsHalting cannot exist, so AreEquivalent cannot exist either. This demonstrates equivalence problem is just another version of halting problem. So, lambda expressions’ equivalence is undecidable. The undecidability is actually a very general topic in computability theory and mathematical logic. The undecidability of halting problem and lambda calculus’ undecidability of equivalence are examples of &lt;a href=&quot;http://en.wikipedia.org/wiki/Rice%27s_theorem&quot;&gt;Rice&apos;s theorem&lt;/a&gt;, and also examples of &lt;a href=&quot;http://en.wikipedia.org/wiki/Kurt_G%C3%B6del&quot;&gt;Kurt Gödel&lt;/a&gt;&apos;s &lt;a href=&quot;http://en.wikipedia.org/wiki/G%C3%B6del&apos;s_incompleteness_theorems&quot;&gt;incompleteness theorems&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (7) Fixed Point Combinator and Recursion</title><link>https://dixin.github.io/posts/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion/</guid><description>p is the ) (aka invariant point) of function f :</description><pubDate>Sat, 23 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;p is the &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_(mathematics)&quot;&gt;fixed point&lt;/a&gt; (aka invariant point) of function f &lt;a href=&quot;http://en.wikipedia.org/wiki/If_and_only_if&quot;&gt;if and only if&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p
≡ f p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take function Math.Sqrt as example, it has 2 fix point, 0 and 1, so that 0 ≡ Math.Sqrt(0) and 1 ≡ Math.Sqrt(1).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-7-Fixed-Point-Comb_DA7/FixedPoint.fw_thumb2_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-7-Fixed-Point-Comb_DA7/FixedPoint.fw_thumb2_thumb_thumb.png&quot; alt=&quot;FixedPoint.fw_thumb2_thumb&quot; title=&quot;FixedPoint.fw_thumb2_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The above fixed point definition also leads to infinite substitution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p
≡ f p
≡ f (f p)
≡ f (f (f p))
≡ ...
≡ f (f (f ... (f p) ...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_combinator&quot;&gt;fixed point combinator&lt;/a&gt; Y is defined as if Y f is the fixed point of f:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(Y f)
≡ f (Y f)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Normal order fixed point combinator (Y combinator) and recursion&lt;/h2&gt;
&lt;p&gt;The following &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus&quot;&gt;Y combinator&lt;/a&gt; is an implementation of fixed point combinator, discovered by Haskell Curry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y := λf.(λg.f (g g)) (λg.f (g g))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is called the normal order fixed point combinator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y f
≡ (λf.(λg.f (g g)) (λg.f (g g))) f
≡ (λg.f (g g)) (λg.f (g g))
≡ f ((λg.f (g g)) (λg.f (g g)))
≡ f (Y f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://matt.might.net/articles/compiling-up-to-lambda-calculus/&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3c3b4cb86227_12489/y_combinator_1.jpg&quot; alt=&quot;y_combinator&quot; title=&quot;y_combinator&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following is Y implemented in SKI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y := S (K (S I I)) (S (S (K S) K) (K (S I I)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And just in SK:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y := S S K (S (K (S S (S (S S K)))) K)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Y f can also be substituted infinitely:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(Y f)
≡ f (Y f)
≡ f (f (Y f))
≡ f (f (f (Y f)))
≡ ...
≡ f (f (f ... (f (Y f)) ...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Knights_of_the_Lambda_Calculus&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3c3b4cb86227_12489/390px-Knights_of_the_Lambda_Calculus.svg_3.png&quot; alt=&quot;390px-Knights_of_the_Lambda_Calculus.svg&quot; title=&quot;390px-Knights_of_the_Lambda_Calculus.svg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So Y can be used to implement &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursion_(computer_science)&quot;&gt;recursion&lt;/a&gt;. As fore mentioned, in lambda calculus, a function cannot directly apply it self in its body. Take the factorial function as example, the factorial of n is defined recursively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If n is greater than 0, then factorial of n is the multiplication of n and factorial of n – 1&lt;/li&gt;
&lt;li&gt;if n is 0, then factorial of n is 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So naturally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Factorial := λn.If (n == 0) (λx.1) (λx.n * (Factorial (n - 1)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, in lambda calculus the above definition is illegal, because the self reference does not work anonymously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λn.If (n == 0) (λx.1) (λx.n * (? (n - 1)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now with the power of Y combinator, the recursion can be implemented, but still in the anonymous way. First, in above definition, just pass the reference of itself as an variable/argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the above function is called FactorialHelper, then the Factorial function can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FactorialHelper := λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))
Factorial := Y FactorialHelper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the recursive Factorial is implemented anonymously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Factorial
≡ Y FactorialHelper
≡ (λf.(λg.f (g g)) (λg.f (g g))) FactorialHelper
≡ (λf.(λg.f (g g)) (λg.f (g g))) (λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Factorial is applied, according to the definition of Factorial and Y:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Factorial 3
≡ Y FactorialHelper 3
≡ FactorialHelper (Y FactorialHelper) 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here (Y FactorialHelper) can be substituted by Factorial, according to the definition. So FactorialHelper is called with Factorial and n, exactly as expected.&lt;/p&gt;
&lt;p&gt;The normal order Y combinator does not work with applicative order reduction. In applicative order, here FactorialHelper is applied with (Y FactorialHelper), so the right most argument Y FactorialHelper should be reduced first, which leads to infinite reduction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FactorialHelper (Y FactorialHelper) 3
≡ FactorialHelper (FactorialHelper (Y FactorialHelper)) 3
≡ FactorialHelper (FactorialHelper (FactorialHelper (Y FactorialHelper))) 3
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The normal order Y combinator only works with normal order. In normal order, here FactorialHelper is applied with (Y FactorialHelper), so the left most function FactorialHelper should be reduced first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FactorialHelper (Y FactorialHelper) 3
≡ (λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (Y FactorialHelper) 3
≡ (λn.If (n == 0) (λx.1) (λx.n * (Y FactorialHelper (n - 1)))) 3
≡ If (3 == 0) (λx.1) (λx.3 * (Y FactorialHelper (3 - 1)))
≡ If (False) (λx.1) (λx.3 * (Y FactorialHelper (3 - 1))
≡ 3 * (Y FactorialHelper (3 - 1))
≡ 3 * (FactorialHelper (Y FactorialHelper) (3 - 1))
≡ 3 * ((λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (Y FactorialHelper) (3 - 1))
≡ 3 * ((λn.If (n == 0) (λx.1) (λx.n * (Y FactorialHelper (n - 1)))) (3 - 1))
≡ 3 * (If ((3 - 1) == 0) (λx.1) (λx.(3 - 1) * (Y FactorialHelper ((3 - 1) - 1))))
≡ 3 * ((3 - 1) * (Y FactorialHelper ((3 - 1) - 1)))
≡ 3 * (2 * (Y FactorialHelper ((3 - 1) - 1)))
≡ 3 * (2 * (FactorialHelper (Y FactorialHelper) ((3 - 1) - 1)))
≡ 3 * (2 * ((λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (Y FactorialHelper) ((3 - 1) - 1)))
≡ 3 * (2 * ((λn.If (n == 0) (λx.1) (λx.n * (Y FactorialHelper (n - 1)))) ((3 - 1) - 1)))
≡ 3 * (2 * (If (((3 - 1) - 1) == 0) (λx.1) (λx.((3 - 1) - 1) * (Y FactorialHelper (((3 - 1) - 1) - 1)))))
≡ 3 * (2 * (((3 - 1) - 1) * (Y FactorialHelper (((3 - 1) - 1) - 1))))
≡ 3 * (2 * (1 * (Y FactorialHelper (((3 - 1) - 1) - 1))))
≡ 3 * (2 * (1 * (FactorialHelper (Y FactorialHelper) (((3 - 1) - 1) - 1))))
≡ 3 * (2 * (1 * ((f.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (Y FactorialHelper) (((3 - 1) - 1) - 1))))
≡ 3 * (2 * (1 * ((n.If (n == 0) (λx.1) (λx.n * (Y FactorialHelper (n - 1)))) (((3 - 1) - 1) - 1))))
≡ 3 * (2 * (1 * (If ((((3 - 1) - 1) - 1) == 0) (λx.1) (λx.(((3 - 1) - 1) - 1) * (Y FactorialHelper ((((3 - 1) - 1) - 1) - 1))))))
≡ 3 * (2 * (1 * 1))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the Y f infinite reduction is blocked in in normal order reduction. First, Y f is reduced to f (Y f), then the next reduction is to reduce leftmost expression f, not the the rightmost (Y f). In the above example Y FactorialHelper n:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If n is greater than 0, Y Factorial n is reduced to n * (Y Factorial (n - 1)), where Y Factorial can be further reduced, so the recursion continues.&lt;/li&gt;
&lt;li&gt;If n is 0, Y Factorial n is reduced to 1. The reduction ends, so the recursion terminates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y combinator is easy to implement in C#. Generally, for a recursive function f of type T -&amp;gt; TResult, its helper function accepts the T -&amp;gt; TResult function and a T value, then return TResult, so its helper function is of type (T -&amp;gt; TResult) –&amp;gt; T -&amp;gt; TResult. Y can be viewed as accepting helper function and returns f. so Y is of type ((T -&amp;gt; TResult) –&amp;gt; T -&amp;gt; TResult) -&amp;gt; (T -&amp;gt; TResult). So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FixedPointCombinators&amp;lt;T, TResult&amp;gt;
{
    // Y = (g =&amp;gt; f(g(g)))(g =&amp;gt; f(g(g)))
    public static readonly Func&amp;lt;Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt;
        Y = f =&amp;gt; new SelfApplicableFunc&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt;(g =&amp;gt; f(g(g)))(g =&amp;gt; f(g(g)));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the types of the elements in above lambda expression:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;g: SelfApplicableFunc&amp;lt;T -&amp;gt; TResult&amp;gt;&lt;/li&gt;
&lt;li&gt;g(g): T -&amp;gt; TResult&lt;/li&gt;
&lt;li&gt;f: (T -&amp;gt; TResult) –&amp;gt; T -&amp;gt; TResult&lt;/li&gt;
&lt;li&gt;f(g(g)): T =&amp;gt; TResult&lt;/li&gt;
&lt;li&gt;g =&amp;gt; f(g(g)): SelfApplicableFunc&amp;lt;T -&amp;gt; TResult&amp;gt; –&amp;gt; T -&amp;gt; TResult, which is SelfApplicableFunc&amp;lt;T -&amp;gt; TResult&amp;gt; by definition&lt;/li&gt;
&lt;li&gt;(g =&amp;gt; f(g(g)))(g =&amp;gt; f(g(g))): T -&amp;gt; TResult&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Factorial, apparently it is of function type Numeral -&amp;gt; Numeral, so FactorialHelper is of function type (Numeral -&amp;gt; Numeral) –&amp;gt; Numeral -&amp;gt; Numeral:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static FixedPointCombinators&amp;lt;Numeral, Numeral&amp;gt;;

public static partial class ChurchNumeral
{
    // FactorialHelper = factorial =&amp;gt; n =&amp;gt; If(n == 0)(_ =&amp;gt; 1)(_ =&amp;gt; n * factorial(n - 1))
    public static readonly Func&amp;lt;Func&amp;lt;Numeral, Numeral&amp;gt;, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
        FactorialHelper = factorial =&amp;gt; n =&amp;gt;
            If(n.IsZero())
                (_ =&amp;gt; One)
                (_ =&amp;gt; n.Multiply(factorial(n.Subtract(One))));

    public static readonly Func&amp;lt;Numeral, Numeral&amp;gt;
        Factorial = Y(FactorialHelper);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Calling above Factorial always throws StackOverflowException, because in C# executes in applicative order. When Factorial is called, it calls normal order Y in applicative order, which causes infinite execution.&lt;/p&gt;
&lt;h2&gt;Applicative order fixed point combinator (Z combinator) and recursion&lt;/h2&gt;
&lt;p&gt;The above Y combinator does not work in C#. When reducing Y f in applicative order, the self application in expression f (g g) leads to infinite reduction, which need to be blocked. The solution is to eta convert f (g g) to λx.f (g g) x. So the applicative order fixed point combinator is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Z := λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is called Z combinator. Now reduce Z f in applicative order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Z f
≡ (λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)) f
≡ (λg.λx.f (g g) x) (λg.λx.f (g g) x)
≡ λx.f ((λg.λx.f (g g) x) (λg.λx.f (g g) x)) x
≡ λx.f (Z f) x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time Z f is not reduced to f (Z f), but reduced to the eta expanded version λx.f (Z f) x, so any further reduction is blocked. Still take factorial as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Factorial 3
≡ Z FactorialHelper 3
≡ (λx.FactorialHelper (Z FactorialHelper) x) 3
≡ FactorialHelper (Z FactorialHelper) 3
≡ FactorialHelper (λx.FactorialHelper (Z FactorialHelper) x) 3
≡ (λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (λx.FactorialHelper (Z FactorialHelper) x) 3
≡ (λn.If (n == 0) (λx.1) (λx.n * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1)))) 3
≡ If (3 == 0) (λx.1) (λx.3 * ((λx.FactorialHelper (Z FactorialHelper) x) (3 - 1)))
≡ If (False) (λx.1) (λx.3 * ((λx.FactorialHelper (Z FactorialHelper) x) (3 - 1)))
≡ 3 * ((λx.FactorialHelper (Z FactorialHelper) x) (3 - 1))
≡ 3 * ((λx.FactorialHelper (Z FactorialHelper) x) 2)
≡ 3 * (FactorialHelper (Z FactorialHelper) 2)
≡ 3 * (FactorialHelper (λx.FactorialHelper (Z FactorialHelper) x) 2)
≡ 3 * ((λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (λx.FactorialHelper (Z FactorialHelper) x) 2)
≡ 3 * ((λn.If (n == 0) (λx.1) (λx.n * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1)))) 2)
≡ 3 * (If (2 == 0) (λx.1) (λx.2 * ((λx.FactorialHelper (Z FactorialHelper) x) (2 - 1))))
≡ 3 * (If (False) (λx.1) (λx.2 * ((λx.FactorialHelper (Z FactorialHelper) x) (2 - 1))))
≡ 3 * (2 * ((λx.FactorialHelper (Z FactorialHelper) x) (2 - 1)))
≡ 3 * (2 * ((λx.FactorialHelper (Z FactorialHelper) x) 1))
≡ 3 * (2 * (FactorialHelper (Z FactorialHelper) 1))
≡ 3 * (2 * (FactorialHelper (λx.FactorialHelper (Z FactorialHelper) x) 1))
≡ 3 * (2 * ((λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (λx.FactorialHelper (Z FactorialHelper) x) 1))
≡ 3 * (2 * ((λn.If (n == 0) (λx.1) (λx.n * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1)))) 1))
≡ 3 * (2 * (If (1 == 0) (λx.1) (λx.1 * ((λx.FactorialHelper (Z FactorialHelper) x) (1 - 1)))))
≡ 3 * (2 * (If (False) (λx.1) (λx.1 * ((λx.FactorialHelper (Z FactorialHelper) x) (1 - 1)))))
≡ 3 * (2 * (1 * ((λx.FactorialHelper (Z FactorialHelper) x) (1 - 1))))
≡ 3 * (2 * (1 * ((λx.FactorialHelper (Z FactorialHelper) x) 0)))
≡ 3 * (2 * (1 * (FactorialHelper (Z FactorialHelper) 0)))
≡ 3 * (2 * (1 * (FactorialHelper (λx.FactorialHelper (Z FactorialHelper) x) 0)))
≡ 3 * (2 * (1 * ((λf.λn.If (n == 0) (λx.1) (λx.n * (f (n - 1)))) (λx.FactorialHelper (Z FactorialHelper) x) 0)))
≡ 3 * (2 * (1 * ((λn.If (n == 0) (λx.1) (λx.n * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1)))) 0)))
≡ 3 * (2 * (1 * (If (0 == 0) (λx.1) (λx.0 * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1))))))
≡ 3 * (2 * (1 * (If (True) (λx.1) (λx.0 * ((λx.FactorialHelper (Z FactorialHelper) x) (n - 1))))))
≡ 3 * (2 * (1 * 1))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, Z combinator can be implemented in the same pattern. Just eta expand f(g(g)) to x =&amp;gt; f(g(g))(x):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FixedPointCombinators&amp;lt;T, TResult&amp;gt;
{
    // Z = (g =&amp;gt; x =&amp;gt; f(g(g))(x))(g =&amp;gt; x =&amp;gt; f(g(g))(x))
    public static readonly Func&amp;lt;Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt;
        Z = f =&amp;gt; new SelfApplicableFunc&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt;(g =&amp;gt; x =&amp;gt; f(g(g))(x))(g =&amp;gt; x =&amp;gt; f(g(g))(x));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The types of the elements in above lambda expression are the same as in Y combinator, and x is of type T.&lt;/p&gt;
&lt;p&gt;Now Factorial can be defined with Z and above FactorialHelper:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;
using static FixedPointCombinators&amp;lt;Numeral, System.Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;;

public static partial class ChurchNumeral
{
    // DivideByHelper = divideBy =&amp;gt; dividend =&amp;gt; divisor =&amp;gt; If(dividend &amp;gt;= divisor)(_ =&amp;gt; 1 + divideBy(dividend - divisor)(divisor))(_ =&amp;gt; 0)
    private static readonly Func&amp;lt;Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;, Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;&amp;gt; DivideByHelper = divideBy =&amp;gt; dividend =&amp;gt; divisor =&amp;gt;
            If(dividend.IsGreaterThanOrEqualTo(divisor))
                (_ =&amp;gt; One.Add(divideBy(dividend.Subtract(divisor))(divisor)))
                (_ =&amp;gt; Zero);

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; 
        DivideBy = Z(DivideByHelper);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another recursion example is &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci&lt;/a&gt; number. The nth Fibonacci number is defined recursively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if n is greater than 1, then the nth Fibonacci number is the sum of the (n -1)th Fibonacci number and the (n -2)th Fibonacci number.&lt;/li&gt;
&lt;li&gt;if n is 1 or 0, then the nth Fibonacci number is n&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So naturally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fibonacci := λn.If (n &amp;gt; 1) (λx.(Fibonacci (n - 1)) + (Fibonacci (n - 2))) (λx.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the above recursive definition is illegal in lambda calculus, because the self reference does not work anonymously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λn.If (n &amp;gt; 1) (λx.(? (n - 1)) + (? (n - 2))) (λx.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following the same helper function pattern as FactorialHelper, a FibonacciHelper can be defined to pass the Fibonacci function as a variable/argument, then Fibonacci can be defined with Z and FibonacciHelper:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FibonacciHelper := λf.λn.If (n &amp;gt; 1) (λx.(f (n - 1)) + (f (n - 2))) (λx.n)
Fibonacci := Z FibonacciHelper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Fibonacci is recursive but still can go anonymous, without any self reference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fibonacci
≡ Z FibonacciHelper
≡ (λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)) FibonacciHelper
≡ (λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)) (λf.λn.If (n &amp;gt; 1) (λx.(f (n - 1)) + (f (n - 2))) (λx.n))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// FibonacciHelper  = fibonacci  =&amp;gt; n =&amp;gt; If(n &amp;gt; 1)(_ =&amp;gt; fibonacci(n - 1) + fibonacci(n - 2))(_ =&amp;gt; n)
private static readonly Func&amp;lt;Func&amp;lt;Numeral, Numeral&amp;gt;, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    FibonacciHelper = fibonacci =&amp;gt; n =&amp;gt;
        If(n.IsGreaterThan(One))
            (_ =&amp;gt; fibonacci(n.Subtract(One)).Add(fibonacci(n.Subtract(Two))))
            (_ =&amp;gt; n);

// Fibonacci = Z(FibonacciHelper)
public static readonly Func&amp;lt;Numeral, Numeral&amp;gt;
    Fibonacci = Z(FibonacciHelper);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Previously, in the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;Church numeral arithmetic&lt;/a&gt;, the following illegal DivideBy with self reference was temporarily used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideBy := λa.λb.If (a &amp;gt;= b) (λx.1 + (DivideBy (a - b) b)) (λx.0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, with Z, an legal DivideBy in lambda calculus can be defined, following the same helper function pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideByHelper := λf.λa.λb.If (a &amp;gt;= b) (λx.1 + (f (a - b) b)) (λx.0)
DivideBy := Z DivideByHelper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is the formal version of DivideBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideBy
≡ Z DivideByHelper
≡ (λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)) DivideByHelper
≡ (λf.(λg.λx.f (g g) x) (λg.λx.f (g g) x)) (λf.λa.λb.If (a &amp;gt;= b) (λx.1 + (f (a - b) b)) (λx.0))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// DivideByHelper = divideBy =&amp;gt; dividend =&amp;gt; divisor =&amp;gt; If(dividend &amp;gt;= divisor)(_ =&amp;gt; 1 + divideBy(dividend - divisor)(divisor))(_ =&amp;gt; 0)
private static readonly Func&amp;lt;Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;, Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;&amp;gt;
    DivideByHelper = divideBy =&amp;gt; dividend =&amp;gt; divisor =&amp;gt;
        If(dividend.IsGreaterThanOrEqualTo(divisor))
            (_ =&amp;gt; One.Add(divideBy(dividend.Subtract(divisor))(divisor)))
            (_ =&amp;gt; Zero);

// DivideBy = Z(DivideByHelper)
public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    DivideBy = Z(DivideByHelper);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following are a few examples&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NumeralExtensions
{
    public static Numeral Factorial(this Numeral n) =&amp;gt; ChurchNumeral.Factorial(n);

    public static Numeral Fibonacci(this Numeral n) =&amp;gt; ChurchNumeral.Fibonacci(n);

    public static Numeral DivideBy(this Numeral dividend, Numeral divisor) =&amp;gt; 
        ChurchNumeral.DivideBy(dividend)(divisor);
}

[TestClass]
public partial class FixedPointCombinatorTests
{
    [TestMethod]
    public void FactorialTest()
    {
        Func&amp;lt;uint, uint&amp;gt; factorial = null; // Must have to be compiled.
        factorial = x =&amp;gt; x == 0 ? 1U : x * factorial(x - 1U);

        Assert.AreEqual(factorial(0U), 0U.Church().Factorial().Unchurch());
        Assert.AreEqual(factorial(1U), 1U.Church().Factorial().Unchurch());
        Assert.AreEqual(factorial(2U), 2U.Church().Factorial().Unchurch());
        Assert.AreEqual(factorial(8U), 8U.Church().Factorial().Unchurch());
    }

    [TestMethod]
    public void FibonacciTest()
    {
        Func&amp;lt;uint, uint&amp;gt; fibonacci = null; // Must have. So that fibonacci can recursively refer itself.
        fibonacci = x =&amp;gt; x &amp;gt; 1U ? fibonacci(x - 1) + fibonacci(x - 2) : x;

        Assert.AreEqual(fibonacci(0U), 0U.Church().Fibonacci().Unchurch());
        Assert.AreEqual(fibonacci(1U), 1U.Church().Fibonacci().Unchurch());
        Assert.AreEqual(fibonacci(2U), 2U.Church().Fibonacci().Unchurch());
        Assert.AreEqual(fibonacci(8U), 8U.Church().Fibonacci().Unchurch());
    }

    [TestMethod]
    public void DivideByTest()
    {
        Assert.AreEqual(1U / 1U, 1U.Church().DivideBy(1U.Church()).Unchurch());
        Assert.AreEqual(1U / 2U, 1U.Church().DivideBy(2U.Church()).Unchurch());
        Assert.AreEqual(2U / 2U, 2U.Church().DivideBy(2U.Church()).Unchurch());
        Assert.AreEqual(2U / 1U, 2U.Church().DivideBy(1U.Church()).Unchurch());
        Assert.AreEqual(8U / 3U, 8U.Church().DivideBy(3U.Church()).Unchurch());
        Assert.AreEqual(3U / 8U, 3U.Church().DivideBy(8U.Church()).Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (6) Combinatory Logic</title><link>https://dixin.github.io/posts/lambda-calculus-via-csharp-6-combinatory-logic/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-csharp-6-combinatory-logic/</guid><description>In lambda calculus, the primitive is function, which can have free variables and bound variables.  was introduced by [Moses Schönfink</description><pubDate>Tue, 19 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;In lambda calculus, the primitive is function, which can have free variables and bound variables. &lt;a href=&quot;http://en.wikipedia.org/wiki/Combinatory_logic&quot;&gt;Combinatory logic&lt;/a&gt; was introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel&quot;&gt;Moses Schönfinkel&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt; in 1920s. It is equivalent variant lambda calculus, with combinator as primitive. A combinator can be viewed as an expression with no free variables in its body.&lt;/p&gt;
&lt;h2&gt;Combinator&lt;/h2&gt;
&lt;p&gt;The following is the simplest function definition expression, with only bound variable and no free variable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I := λx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In combinatory logic it is called I (Id) combinator. The following functions are combinators too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S := λx.λy.λz.x z (y z)
K := λx.λy.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here S (Slider) combinator slides z to between x and y (In some materials S is called Substitution; In &lt;a href=&quot;https://www.youtube.com/watch?v=7cPtCpyBPNI&quot;&gt;presentation&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Dana_Scott&quot;&gt;Dana Scott&lt;/a&gt; S is called Slider), and K (Killer) combinator kills y.&lt;/p&gt;
&lt;p&gt;In C#, just leave the each combinator’s variables as dynamic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static readonly Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;
        S = x =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y(z));

    public static readonly Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;
        K = x =&amp;gt; y =&amp;gt; x;

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        I = x =&amp;gt; x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ω is the self application combinator. It applies variable f to f itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ω := λf.f f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like above f, ω can also be applied with ω itself, which is the definition of Ω:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ω := ω ω ≡ (λf.f f) (λf.f f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here ω is a function definition expression without free variables, and Ω is a function application expression, which contains no free variables. For Ω, its function application can be beta reduced forever:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(λf.f f) (λf.f f)
≡ (λf.f f) (λf.f f)
≡ (λf.f f) (λf.f f)
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So ω ω is an infinite application. Ω is called the looping combinator.&lt;/p&gt;
&lt;p&gt;In C#, it is easy to define the type of self applicable function, like above f. Assume the function’s return type is TResult, then this function is of type input –&amp;gt; TResult:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;TResult&amp;gt;(?);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The input type is the function type itself, so it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; self)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above Func&amp;lt;TResult&amp;gt; is the self applicable function type. To be unambiguous with System.Func&amp;lt;TResult&amp;gt;, it can be renamed to SelfApplicableFunc&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult SelfApplicableFunc&amp;lt;TResult&amp;gt;(SelfApplicableFunc&amp;lt;TResult&amp;gt; self);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So SelfApplicableFunc&amp;lt;TResult&amp;gt; is equivalent to SelfApplicableFunc&amp;lt;TResult&amp;gt; -&amp;gt; TResult. Since f is of type SelfApplicableFunc&amp;lt;TResult&amp;gt;, f(f) returns TResult. And since ω accept f and returns TResult. ω is of type SelfApplicableFunc&amp;lt;TResult&amp;gt; -&amp;gt; TResult, which is the definition of SelfApplicableFunc&amp;lt;TResult&amp;gt;, so ω is still of type SelfApplicableFunc&amp;lt;TResult&amp;gt;, ω(ω) is still of type TResult:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class OmegaCombinators&amp;lt;TResult&amp;gt;
{
    public static readonly SelfApplicableFunc&amp;lt;TResult&amp;gt;
        ω = f =&amp;gt; f(f);

    public static readonly TResult
        Ω = ω(ω);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SKI combinator calculus&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/SKI_combinator_calculus&quot;&gt;SKI combinator calculus&lt;/a&gt; is a kind of combinatory logic. As a variant of lambda calculus, SKI combinatory logic has no general expression definition rules, or general expression reduction rules. It only has the above S, K, I combinators as the only 3 primitives, and the only 3 function application rules. It can be viewed as a reduced version of lambda calculus, and an extremely simple Turing complete language with only 3 elements: S, K, I.&lt;/p&gt;
&lt;p&gt;Take the Boolean values as a simple example. Remember in lambda calculus, True and False are defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λt.λf.t
False := λt.λf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that when they are applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True t f
≡ (λt.λf.t) t f
≡ t

  False t f
≡ (λt.λf.f) t f
≡ f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here in SKI combinator calculus, SKI combinators are the only primitives, so True and False can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := K
False := S K
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that when they are applied, they return the same result as the lambda calculus definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True t f
≡ K t f
≡ t

  False t f
≡ S K t f
≡ K f (t f) 
≡ f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember function composition is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f2 ∘ f1) x := f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SKI, the composition operator can be equivalently defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Compose := S (K S) K
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how it works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Compose f2 f1 x
≡ S (K S) K f2 f1 x
≡ (K S) f2 (K f2) f1 x
≡ S (K f2) f1 x
≡ (K f2) x (f1 x)
≡ f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In lambda calculus, numerals are defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f x
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SKI, numerals are equivalently defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := K I                     ≡ K I
1 := I                       ≡ I
2 := S Compose I             ≡ S (S (K S) K) I
3 := S Compose (S Compose I) ≡ S (S (K S) K) (S (S (K S) K) I)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When these numerals are applied, they return the same results as lambda calculus definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f x
≡ K I f x
≡ I x
≡ x

  1 f x
≡ I f x
≡ f x

  2 f x
≡ S Compose I f x
≡ Compose f (I f) x
≡ Compose f f x
≡ f (f x)

  3 f x
≡ S Compose (S Compose I) f x
≡ Compose f (S Compose I f) x
≡ Compose f (Compose f f) x
≡ f (f (f x))

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SKI, the self application combinator ω is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ω := S I I
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When it is applied with f, it returns f f:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S I I f
≡ I x (I f) 
≡ f f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So naturally, Ω is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ω := (S I I) (S I I)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it is infinite as in lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S I I (S I I)
≡ I (S I I) (I (S I I)) 
≡ I (S I I) (S I I) 
≡ S I I (S I I)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, I combinator can be defined with S and K in either of the following ways:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I := S K K
I := S K S
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And they work the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I x
≡ S K K x
≡ K x (K x)
≡ x

  I x
≡ S K S x
≡ K x (S x)
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I is just a syntactic sugar in SKI calculus.&lt;/p&gt;
&lt;p&gt;In C#, these combinators can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static SkiCombinators;

public static partial class SkiCalculus
{
    public static readonly Boolean
        True = new Boolean(K);

    public static readonly Boolean
        False = new Boolean(S(K));

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        Compose = S(K(S))(K);

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        Zero = K(I);

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        One = I;

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        Two = S(Compose)(I);

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        Three = S(Compose)(S(Compose)(I));

    // ...

    public static readonly Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;
        Increase = S(Compose);

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        ω = S(I)(I);

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        Ω = S(I)(I)(S(I)(I));

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        IWithSK = S(K)(K); // Or S(K)(S).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;SKI compiler: compile lambda calculus expression to SKI calculus combinator&lt;/h3&gt;
&lt;p&gt;The S, K, I combinators can be composed to new combinator that equivalent to any lambda calculus expression. An arbitrary expression in lambda calculus can be converted to combinator in SKI calculus. Assume v is a variable in lambda calculus, and E is an expression in lambda calculus, the conversion ToSki is defined as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ToSki (v) =&amp;gt; v&lt;/li&gt;
&lt;li&gt;ToSki (E1 E2) =&amp;gt; (ToSki (E1) (ToSki (E2)))&lt;/li&gt;
&lt;li&gt;ToSki (λv.E) =&amp;gt; (K (ToSki (E))), if x does not occur free in E&lt;/li&gt;
&lt;li&gt;ToSki (λv.v) =&amp;gt; I&lt;/li&gt;
&lt;li&gt;ToSki (λv1.λv2.E) =&amp;gt; ToSki (λv1.ToSki (λv2.E))&lt;/li&gt;
&lt;li&gt;ToSki (λv.(E1 E2)) =&amp;gt; (S (ToSki (λ.v.E1)) (ToSki (λv.E2)))&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Based on these rules, a compiler can be implemented to compile a expression in lambda calculus to combinator in SKI calculus. As mentioned before, the C# lambda expression can be compiled as function, and also expression tree data representing the logic of that function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctionAsData&amp;lt;T&amp;gt;()
{
    Func&amp;lt;T, T&amp;gt; idFunction = value =&amp;gt; value;
    Expression&amp;lt;Func&amp;lt;T, T&amp;gt;&amp;gt; idExpression = value =&amp;gt; value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above idFunction and idExpression shares the same lambda expression syntax, but is executable function, while the idExpression is a abstract syntax tree data structure, representing the logic of idFunction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, T&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;T, T&amp;gt;)
|_Parameters
| |_ParameterExpression (NodeType = Parameter, Type = T)
|   |_Name = &quot;value&quot;
|_Body
  |_ParameterExpression (NodeType = Parameter, Type = T)
    |_Name = &quot;value&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This metaprogramming feature provides great convenience for the conversion – just build the lambda calculus expression as .NET expression tree, traverse the tree and apply the above rules, and convert the tree to another tree representing the SKI calculus combinator.&lt;/p&gt;
&lt;p&gt;A SKI calculus combinator, like above Ω combinator (S I I) (S I I), is a composition of S, K, I. The S, K, I primitives can be represented with a constant expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class CombinatorExpression : Expression
{
    private CombinatorExpression(string name) =&amp;gt; this.Name = name;

    public static CombinatorExpression S { get; } = new CombinatorExpression(nameof(S));

    public static CombinatorExpression K { get; } = new CombinatorExpression(nameof(K));

    public static CombinatorExpression I { get; } = new CombinatorExpression(nameof(I));

    public string Name { get; }

    public override ExpressionType NodeType { get; } = ExpressionType.Constant;

    public override Type Type { get; } = typeof(object);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The composition can be represented with a function application expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ApplicationExpression : Expression
{
    internal ApplicationExpression(Expression function, Expression variable)
    {
        this.Function = function;
        this.Variable = variable;
    }

    public Expression Function { get; }

    public Expression Variable { get; }

    public override ExpressionType NodeType { get; } = ExpressionType.Invoke;

    public override Type Type { get; } = typeof(object);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the above Ω combinator (S I I) (S I I) can be represented by the following expression tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ApplicationExpression (NodeType = Invoke, Type = object)
|_Function
| |_ApplicationExpression (NodeType = Invoke, Type = object)
|   |_Function
|   | |_ApplicationExpression (NodeType = Invoke, Type = object)
|   |   |_Function
|   |   | |_CombinatorExpression (NodeType = Constant, Type = object)
|   |   |   |_Name = &quot;S&quot;
|   |   |_Variable
|   |     |_CombinatorExpression (NodeType = Constant, Type = object)
|   |       |_Name = &quot;I&quot;
|   |_Variable
|     |_CombinatorExpression (NodeType = Constant, Type = object)
|       |_Name = &quot;I&quot;
|_Variable
  |_ApplicationExpression (NodeType = Invoke, Type = object)
    |_Function
    | |_ApplicationExpression (NodeType = Invoke, Type = object)
    |   |_Function
    |   | |_CombinatorExpression (NodeType = Constant, Type = object)
    |   |   |_Name = &quot;S&quot;
    |   |_Variable
    |     |_CombinatorExpression (NodeType = Constant, Type = object)
    |       |_Name = &quot;I&quot;
    |_Variable
      |_CombinatorExpression (NodeType = Constant, Type = object)
        |_Name = &quot;I&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in the following SkiCompiler type, the ToSki is implemented to traverse the input abstract syntax tree recursively, and apply the above conversion rules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCompiler
{
    public static Expression ToSki(this Expression lambdaCalculus)
    {
        // Ignore type convertion specified in code or generated by C# compiler.
        lambdaCalculus = lambdaCalculus.IgnoreTypeConvertion();

        switch (lambdaCalculus.NodeType)
        {
            case ExpressionType.Constant:
                // 0. ToSki(S) = S, ToSki(K) = K, ToSki(I) = I.
                if (lambdaCalculus is CombinatorExpression)
                {
                    return lambdaCalculus;
                }
                break;

            case ExpressionType.Parameter:
                // 1. ToSki(v) = v.
                return lambdaCalculus;

            case ExpressionType.Invoke:
                // 2. ToSki(E1(E2)) = ToSki(E1)(ToSKi(E2)).
                ApplicationExpression application = lambdaCalculus.ToApplication();
                return new ApplicationExpression(ToSki(application.Function), ToSki(application.Variable));

            case ExpressionType.Lambda:
                LambdaExpression function = (LambdaExpression)lambdaCalculus;
                ParameterExpression variable = function.Parameters.Single();
                Expression body = function.Body.IgnoreTypeConvertion();

                // 3. ToSki(v =&amp;gt; E) = K(ToSki(E)), if v does not occur free in E.
                if (!variable.IsFreeIn(body))
                {
                    return new ApplicationExpression(CombinatorExpression.K, ToSki(body));
                }

                switch (body.NodeType)
                {
                    case ExpressionType.Parameter:
                        // 4. ToSki(v =&amp;gt; v) = I
                        if (variable == (ParameterExpression)body)
                        {
                            return CombinatorExpression.I;
                        }
                        break;

                    case ExpressionType.Lambda:
                        // 5. ToSki(v1 =&amp;gt; v2 =&amp;gt; E) = ToSki(v1 =&amp;gt; ToSki(v2 =&amp;gt; E)), if v1 occurs free in E.
                        LambdaExpression bodyFunction = (LambdaExpression)body;
                        if (variable.IsFreeIn(bodyFunction.Body))
                        {
                            return ToSki(Expression.Lambda(ToSki(bodyFunction), variable));
                        }
                        break;

                    case ExpressionType.Invoke:
                        // 6. ToSki(v =&amp;gt; E1(E2)) = S(ToSki(v =&amp;gt; E1))(ToSki(v =&amp;gt; E2)).
                        ApplicationExpression bodyApplication = body.ToApplication();
                        return new ApplicationExpression(
                            new ApplicationExpression(
                                CombinatorExpression.S,
                                ToSki(Expression.Lambda(bodyApplication.Function, variable))),
                            ToSki(Expression.Lambda(bodyApplication.Variable, variable)));
                }
                break;
        }
        throw new ArgumentOutOfRangeException(nameof(lambdaCalculus));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It calls a few helper functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Expression IgnoreTypeConvertion(this Expression lambdaCalculus) =&amp;gt;
    lambdaCalculus.NodeType == ExpressionType.Convert
        ? ((UnaryExpression)lambdaCalculus).Operand
        : lambdaCalculus;

private static ApplicationExpression ToApplication(this Expression expression)
{
    switch (expression)
    {
        case ApplicationExpression application:
            return application;
        case InvocationExpression invocation:
            return new ApplicationExpression(invocation.Expression, invocation.Arguments.Single());
    }
    throw new ArgumentOutOfRangeException(nameof(expression));
}

private static bool IsFreeIn(this ParameterExpression variable, Expression lambdaCalculus)
{
    // Ignore type convertion specified in code or generated by C# compiler.
    lambdaCalculus = lambdaCalculus.IgnoreTypeConvertion();

    switch (lambdaCalculus.NodeType)
    {
        case ExpressionType.Invoke:
            ApplicationExpression application = lambdaCalculus.ToApplication();
            return variable.IsFreeIn(application.Function) || variable.IsFreeIn(application.Variable);
        case ExpressionType.Lambda:
            LambdaExpression function = (LambdaExpression)lambdaCalculus;
            return variable != function.Parameters.Single() &amp;amp;&amp;amp; variable.IsFreeIn(function.Body);
        case ExpressionType.Parameter:
            return variable == (ParameterExpression)lambdaCalculus;
        case ExpressionType.Constant:
            return false;
    }
    throw new ArgumentOutOfRangeException(nameof(lambdaCalculus));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes, in order to make the lambda calculus expression be compiled, some type information has to be added manually or automatically by C# compiler. These type conversion information is not needed, and can be removed by IgnoreTypeConvertion. In lambda expression, function invocation is compiled as InvocationExpression node with node type Invoke, which is the same as ApplicationExpression. For convenience, ToApplication unifies all Invoke nodes to ApplicationExpression. And IsFreeIn recursively test whether the specified variable occurs free in the specified lambda calculus expression.&lt;/p&gt;
&lt;p&gt;Finally, for readability, the following ToSkiString method Converts the compiled SKI calculus expression to string representation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string ToSkiString(this Expression skiCalculus) =&amp;gt; skiCalculus.ToSkiString(false);

private static string ToSkiString(this Expression skiCalculus, bool parentheses)
{
    switch (skiCalculus.NodeType)
    {
        case ExpressionType.Invoke:
            ApplicationExpression application = (ApplicationExpression)skiCalculus;
            return parentheses
                ? $&quot;({application.Function.ToSkiString(false)} {application.Variable.ToSkiString(true)})&quot;
                : $&quot;{application.Function.ToSkiString(false)} {application.Variable.ToSkiString(true)}&quot;;
        case ExpressionType.Parameter:
            return ((ParameterExpression)skiCalculus).Name;
        case ExpressionType.Constant:
            return ((CombinatorExpression)skiCalculus).Name;
    }
    throw new ArgumentOutOfRangeException(nameof(skiCalculus));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates how to represent 2-tuple in SKI calculus combinator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Tuple&amp;lt;T1, T2&amp;gt;()
{
    Expression&amp;lt;Func&amp;lt;T1, Func&amp;lt;T2, Tuple&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;&amp;gt;
        createTupleLambda = item1 =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2);
    Expression createTupleSki = createTupleLambda.ToSki();
    createTupleSki.ToSkiString().WriteLine();
    // S (S (K S) (S (K K) (S (K S) (S (K (S I)) (S (K K) I))))) (K (S (K K) I))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To verify the result, a tuple can be created with x as first item, and y as the second item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateTuple x y
≡ S (S (K S) (S (K K) (S (K S) (S (K (S I)) (S (K K) I))))) (K (S (K K) I)) x y
≡ S (K S) (S (K K) (S (K S) (S (K (S I)) (S (K K) I)))) x (K (S (K K) I) x) y
≡ K S x (S (K K) (S (K S) (S (K (S I)) (S (K K) I))) x) (K (S (K K) I) x) y
≡ S (S (K K) (S (K S) (S (K (S I)) (S (K K) I))) x) (K (S (K K) I) x) y
≡ S (K K) (S (K S) (S (K (S I)) (S (K K) I))) x y (K (S (K K) I) x y)
≡ K K x (S (K S) (S (K (S I)) (S (K K) I)) x) y (K (S (K K) I) x y)
≡ K (S (K S) (S (K (S I)) (S (K K) I)) x) y (K (S (K K) I) x y)
≡ S (K S) (S (K (S I)) (S (K K) I)) x (K (S (K K) I) x y)
≡ K S x (S (K (S I)) (S (K K) I) x) (K (S (K K) I) x y)
≡ S (S (K (S I)) (S (K K) I) x) (K (S (K K) I) x y)
≡ S (K (S I) x (S (K K) I x)) (K (S (K K) I) x y)
≡ S (S I (S (K K) I x)) (K (S (K K) I) x y)
≡ S (S I ((K K) x (I x))) (K (S (K K) I) x y)
≡ S (S I (K (I x))) (K (S (K K) I) x y)
≡ S (S I (K x)) (K (S (K K) I) x y)
≡ S (S I (K x)) (S (K K) I y)
≡ S (S I (K x)) (K K y (I y))
≡ S (S I (K x)) (K (I y))
≡ S (S I (K x)) (K y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get the first/second item of the above tuple, apply it with True/False:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 (CreateTuple x y)
≡ (CreateTuple x y) True
≡ S (S I (K x)) (K y) True
≡ S (S I (K x)) (K y) K
≡ S I (K x) K (K y K)
≡ I K (K x K) (K y K)
≡ K (K x K) (K y K)
≡ K x K
≡ x

  Item2 (CreateTuple x y)
≡ (CreateTuple x y) False
≡ S (S I (K x)) (K y) False
≡ S (S I (K x)) (K y) (S K)
≡ S I (K x) (S K) (K y (S K))
≡ I (S K) (K x (S K)) (K y (S K))
≡ S K (K x (S K)) (K y (S K))
≡ K y (K x (S K) y)
≡ y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the compiled 2-tuple SKI calculus combinator is equivalent to the lambda calculus expression.&lt;/p&gt;
&lt;p&gt;Another example is the logic operator And:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;And := λa.λb.a b False ≡ λa.λb.a b (λt.λf.f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void And()
{
    Expression&amp;lt;Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;&amp;gt;
        andLambda = a =&amp;gt; b =&amp;gt; a(b)((Boolean)(@true =&amp;gt; @false =&amp;gt; @false));
    Expression andSki = andLambda.ToSki();
    andSki.ToSkiString().WriteLine();;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, above expression tree cannot be compiled, with error CS1963: An expression tree may not contain a dynamic operation. The reason is, Boolean is the alias of Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;, and C# compiler does not support dynamic operations in expression tree, like calling a(b) here. At compile time, dynamic is just object, so the solution is to replace dynamic with object, and replace Boolean with object –&amp;gt; object -&amp;gt; object, then the following code can be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void And()
{
    Expression&amp;lt;Func&amp;lt;Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;, Func&amp;lt;Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;, Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;
        andLambda = a =&amp;gt; b =&amp;gt; (Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;)a(b)((Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;)(@true =&amp;gt; @false =&amp;gt; @false));
    Expression andSki = andLambda.ToSki();
    andSki.ToSkiString().WriteLine();
    // S (S (K S) (S (S (K S) (S (K K) I)) (K I))) (K (K (K I)))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compilation result can be verified in similar way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;And True True
≡ S (S (K S) (S (S (K S) (S (K K) I)) (K I))) (K (K (K I))) True True
≡ S (S (K S) (S (S (K S) (S (K K) I)) (K I))) (K (K (K I))) K K
≡ S (K S) (S (S (K S) (S (K K) I)) (K I)) K (K (K (K I)) K) K
≡ K S K (S (S (K S) (S (K K) I)) (K I) K) (K (K (K I)) K) K
≡ S (S (S (K S) (S (K K) I)) (K I) K) (K (K (K I)) K) K
≡ S (S (K S) (S (K K) I)) (K I) K K (K (K (K I)) K K)
≡ S (K S) (S (K K) I) K (K I K) K (K (K (K I)) K K)
≡ K S K (S (K K) I K) (K I K) K (K (K (K I)) K K)
≡ S (S (K K) I K) (K I K) K (K (K (K I)) K K)
≡ S (K K) I K K (K I K K) (K (K (K I)) K K)
≡ K K K (I K) K (K I K K) (K (K (K I)) K K)
≡ K (I K) K (K I K K) (K (K (K I)) K K)
≡ I K (K I K K) (K (K (K I)) K K)
≡ K (K I K K) (K (K (K I)) K K)
≡ K I K K
≡ I K
≡ K
≡ True

  And True False
≡ S (S (K S) (S (S (K S) (S (K K) I)) (K I))) (K (K (K I))) True False
≡ S (S (K S) (S (S (K S) (S (K K) I)) (K I))) (K (K (K I))) K (S K)
≡ (S (K S)) (S (S (K S) (S (K K) I)) (K I)) K (K (K (K I)) K) (S K)
≡ K S K (S (S (K S) (S (K K) I)) (K I) K) (K (K (K I)) K) (S K)
≡ S (S (S (K S) (S (K K) I)) (K I) K) (K (K (K I)) K) (S K)
≡ S (S (K S) (S (K K) I)) (K I) K (S K) (K (K (K I)) K (S K))
≡ S (K S) (S (K K) I) K (K I K) (S K) (K (K (K I)) K (S K))
≡ K S K (S (K K) I K) (K I K) (S K) (K (K (K I)) K (S K))
≡ S (S (K K) I K) (K I K) (S K) (K (K (K I)) K (S K))
≡ S (K K) I K (S K) (K I K (S K)) (K (K (K I)) K (S K))
≡ K K K (I K) (S K) (K I K (S K)) (K (K (K I)) K (S K))
≡ K (I K) (S K) (K I K (S K)) (K (K (K I)) K (S K))
≡ I K (K I K (S K)) (K (K (K I)) K (S K))
≡ K (K I K (S K)) (K (K (K I)) K (S K))
≡ K I K (S K)
≡ I (S K)
≡ S K
≡ False

...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Iota combinator calculus&lt;/h2&gt;
&lt;p&gt;Another interesting example of combinator logic is &lt;a href=&quot;http://en.wikipedia.org/wiki/Iota_and_Jot&quot;&gt;Iota&lt;/a&gt; combinator calculus. It has only one combinator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ι := λf.f S K ≡ λf.f (λx.λy.λz.x z (y z)) (λx.λy.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s &lt;a href=&quot;https://web.archive.org/web/20150121065142/http://semarch.linguistics.fas.nyu.edu/barker/Iota/&quot;&gt;the whole combinatory logic&lt;/a&gt;. It is an &lt;a href=&quot;http://en.wikipedia.org/wiki/Esoteric_programming_language&quot;&gt;esoteric programming language&lt;/a&gt; with minimum element – only 1 single element, but still &lt;a href=&quot;http://en.wikipedia.org/wiki/Turing-complete&quot;&gt;Turing-complete&lt;/a&gt;. With Iota combinator, SKI can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S := ι (ι (ι (ι ι)))
K := ι (ι (ι ι))
I := ι ι
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Iota is as Turing-complete as SKI. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I x
≡ ι ι x
≡ (λf.f S K) (λf.f S K) x
≡ (λf.f S K) S K x
≡ (S S K) K x
≡ S K (K K) x
≡ K x ((K K) x)
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, these combinators can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class IotaCombinator
{
    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        ι = f =&amp;gt; f
            (new Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y(z)))) // S
            (new Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; x)); // K
}

public static class IotaCalculus
{
    public static readonly Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;
        S = ι(ι(ι(ι(ι))));

    public static readonly Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;
        K = ι(ι(ι(ι)));

    public static readonly Func&amp;lt;dynamic, dynamic&amp;gt;
        I = ι(ι);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (5) List</title><link>https://dixin.github.io/posts/lambda-calculus-via-csharp-5-list/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-csharp-5-list/</guid><description>In lambda calculus and Church encoding, there are various ways to represent a list with anonymous functions.</description><pubDate>Wed, 13 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;In lambda calculus and Church encoding, there are various ways to represent a list with anonymous functions.&lt;/p&gt;
&lt;h2&gt;Tuple as list node&lt;/h2&gt;
&lt;p&gt;With Church pair, it is easy to model Church list as a linked list, where each list node is a a Church pair (2-tuple) of current node’s value and the next node, So that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode := CreateTuple = λv.λn.λf.f v n
ListNode := Tuple = λf.f v n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here variable v is the value of the current node, so it is the first item of the tuple; And variable n is the next node of the current node, so it is the second item of the tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Value := Item1 = λl.l (λv.λn.v)
Next := Item2 = λl.l (λv.λn.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here variable l is the list node. The C# implementation is similar to tuple and signed numeral, except ListNode&amp;lt;T&amp;gt; function type now has 1 type parameter, which is the type of its value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ListNode&amp;lt;T&amp;gt; is the alias of Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;.
public delegate dynamic ListNode&amp;lt;out T&amp;gt;(Boolean f);

public static partial class ChurchList&amp;lt;T&amp;gt;
{
    // Create = value =&amp;gt; next =&amp;gt; (value, next)
    public static readonly Func&amp;lt;T, Func&amp;lt;ListNode&amp;lt;T&amp;gt;, ListNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
        Create = value =&amp;gt; next =&amp;gt; new ListNode&amp;lt;T&amp;gt;(ChurchTuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;.Create(value)(next));

    // Value = node =&amp;gt; node.Item1()
    public static readonly Func&amp;lt;ListNode&amp;lt;T&amp;gt;, T&amp;gt; 
        Value = node =&amp;gt; new Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(node).Item1();

    // Next = node =&amp;gt; node.Item2()
    public static readonly Func&amp;lt;ListNode&amp;lt;T&amp;gt;, ListNode&amp;lt;T&amp;gt;&amp;gt; 
        Next = node =&amp;gt; new Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(node).Item2();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usually, when a list ends, its last node’s next node is flagged as a special null node. Here in lambda calculus, since a node is an anonymous function, the null node is also an anonymous function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Null := λf.λx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And IsNull predicate returns a Church Boolean to indicate whether a list node is null:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull := λl.l (λv.λn.λx.False) True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When IsNull is applied with a null node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull Null
≡ (λl.l (λv.λn.λx.False) True) (λf.λx.x)
≡ (λf.λx.x) (λv.λn.λx.False) True
≡ (λx.x) True
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And when IsNull is applied with a non-null node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull (CreateListNode 0 Null)
≡ IsNull (λf.f 0 Null)
≡ (λl.l (λv.λn.λx.False) True) (λf.f 0 Null)
≡ (λf.f 0 Null) (λv.λn.λx.False) True
≡ (λv.λn.λx.False) 0 Null True
≡ (λn.λx.False) Null True
≡ (λx.False) True
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# implementation is noisy because a lot of type information has to be provided. This is Null:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;

public static partial class ChurchList&amp;lt;T&amp;gt;
{
    // Null = False;
    public static readonly ListNode&amp;lt;T&amp;gt;
        Null = new ListNode&amp;lt;T&amp;gt;(False);

    // IsNull = node =&amp;gt; node(value =&amp;gt; next =&amp;gt; _ =&amp;gt; False)(True)
    public static readonly Func&amp;lt;ListNode&amp;lt;T&amp;gt;, Boolean&amp;gt; 
        IsNull = node =&amp;gt; node(value =&amp;gt; next =&amp;gt; new Func&amp;lt;Boolean, Boolean&amp;gt;(_ =&amp;gt; False))(True);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the indexer for list can be easily defined with as a function accepts a start node and a Church numeral i as the specified index. To return the node at the specified index, just call Next function for i times from the start node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ListNodeAt := λl.λi.i Next l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Func&amp;lt;ListNode&amp;lt;T&amp;gt;, Func&amp;lt;Numeral, ListNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    ListNodeAt = start =&amp;gt; index =&amp;gt; index(node =&amp;gt; Next(node))(start);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following are the extension methods wrapping the list operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ListNodeExtensions
{
    public static T Value&amp;lt;T&amp;gt;(this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; ChurchList&amp;lt;T&amp;gt;.Value(node);

    public static ListNode&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;(this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; ChurchList&amp;lt;T&amp;gt;.Next(node);

    public static Boolean IsNull&amp;lt;T&amp;gt;(this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; ChurchList&amp;lt;T&amp;gt;.IsNull(node);

    public static ListNode&amp;lt;T&amp;gt; ListNodeAt&amp;lt;T&amp;gt;(this ListNode&amp;lt;T&amp;gt; start, Numeral index) =&amp;gt; ChurchList&amp;lt;T&amp;gt;.ListNodeAt(start)(index);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following code demonstrates how the list works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class ChurchListTests
{
    [TestMethod]
    public void CreateValueNextTest()
    {
        ListNode&amp;lt;int&amp;gt; node1 = ChurchList&amp;lt;int&amp;gt;.Create(1)(ChurchList&amp;lt;int&amp;gt;.Null);
        ListNode&amp;lt;int&amp;gt; node2 = ChurchList&amp;lt;int&amp;gt;.Create(2)(node1);
        ListNode&amp;lt;int&amp;gt; node3 = ChurchList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.AreEqual(1, node1.Value());
        Assert.AreEqual(ChurchList&amp;lt;int&amp;gt;.Null, node1.Next());
        Assert.AreEqual(2, node2.Value());
        Assert.AreEqual(node1, node2.Next());
        Assert.AreEqual(3, node3.Value());
        Assert.AreEqual(node2, node3.Next());
        Assert.AreEqual(node2.Value(), node3.Next().Value());
        Assert.AreEqual(node1.Value(), node3.Next().Next().Value());
        Assert.AreEqual(ChurchList&amp;lt;int&amp;gt;.Null, node3.Next().Next().Next());
        try
        {
            ChurchList&amp;lt;object&amp;gt;.Null.Next();
            Assert.Fail();
        }
        catch (InvalidCastException exception)
        {
            exception.WriteLine();
        }
    }

    [TestMethod]
    public void IsNullTest()
    {
        ListNode&amp;lt;int&amp;gt; node1 = ChurchList&amp;lt;int&amp;gt;.Create(1)(ChurchList&amp;lt;int&amp;gt;.Null);
        ListNode&amp;lt;int&amp;gt; node2 = ChurchList&amp;lt;int&amp;gt;.Create(2)(node1);
        ListNode&amp;lt;int&amp;gt; node3 = ChurchList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.IsTrue(ChurchList&amp;lt;object&amp;gt;.Null.IsNull().Unchurch());
        Assert.IsFalse(node1.IsNull().Unchurch());
        Assert.IsFalse(node2.IsNull().Unchurch());
        Assert.IsFalse(node3.IsNull().Unchurch());
        Assert.IsTrue(node1.Next().IsNull().Unchurch());
        Assert.IsFalse(node2.Next().IsNull().Unchurch());
        Assert.IsFalse(node3.Next().IsNull().Unchurch());
    }

    [TestMethod]
    public void IndexTest()
    {
        ListNode&amp;lt;int&amp;gt; node1 = ChurchList&amp;lt;int&amp;gt;.Create(1)(ChurchList&amp;lt;int&amp;gt;.Null);
        ListNode&amp;lt;int&amp;gt; node2 = ChurchList&amp;lt;int&amp;gt;.Create(2)(node1);
        ListNode&amp;lt;int&amp;gt; node3 = ChurchList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.AreEqual(node3, node3.NodeAt(0U.Church()));
        Assert.AreEqual(node2, node3.NodeAt(1U.Church()));
        Assert.AreEqual(node1, node3.NodeAt(2U.Church()));
        Assert.IsTrue(node3.NodeAt(3U.Church()).IsNull().Unchurch());
        try
        {
            node3.NodeAt(4U.Church());
            Assert.Fail();
        }
        catch (InvalidCastException exception)
        {
            exception.WriteLine();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Aggregate function as list node&lt;/h2&gt;
&lt;p&gt;Remember the LINQ Aggregate query method accepting a seed and a accumulator function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assume seed is x, and accumulator function is f:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When source is empty, the aggregation result is x&lt;/li&gt;
&lt;li&gt;When source is { 0 }, the aggregation result is f(x, 0)&lt;/li&gt;
&lt;li&gt;When source is { 1, 0 }, the aggregation result is f(f(x, 1), 0)&lt;/li&gt;
&lt;li&gt;When source is { 2, 1, 0 }, the aggregation result is f(f(f(x, 2), 1), 0)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Church list can also be encoded with a similar Aggregate function with seed and accumulator function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic AggregateListNode&amp;lt;T&amp;gt;(dynamic x, Func&amp;lt;dynamic, T, dynamic&amp;gt; f);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its type parameter T is the type of node value. And since the seed can be anything, just leave it as dynamic as usual. So the list node is of above aggregate function type (dynamic, (dynamic , T) -&amp;gt; dynamic) -&amp;gt; dynamic. After currying the aggregate function and the accumulator function, it becomes dynamic -&amp;gt; (dynamic –&amp;gt; T -&amp;gt; dynamic) -&amp;gt; dynamic. So this is the function type of list node, and an alias can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from: (dynamic, dynamic -&amp;gt; T -&amp;gt; dynamic) -&amp;gt; dynamic.
// AggregateListNode is the alias of: dynamic -&amp;gt; (dynamic -&amp;gt; T -&amp;gt; dynamic) -&amp;gt; dynamic.
public delegate Func&amp;lt;Func&amp;lt;dynamic, Func&amp;lt;T, dynamic&amp;gt;&amp;gt;, dynamic&amp;gt; AggregateListNode&amp;lt;out T&amp;gt;(dynamic x);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the creation and definition of list node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode := λv.λn.λx.λf.f (n x f) v
ListNode := λx.λf.f (n x f) v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchAggregateList&amp;lt;T&amp;gt;
{
    public static readonly Func&amp;lt;T, Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
        Create = value =&amp;gt; next =&amp;gt; x =&amp;gt; f =&amp;gt; f(next(x)(f))(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, here variable v is the value of current node, variable n is the next node of the current node. And variable x is the seed for aggregation, variable f is the accumulator function. The list is still modeled as a linked list, so Null is also needed to represent the end of list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Null := λx.λf.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Null is defined to call f for 0 times. For example, to create a linked list { 2, 1, 0 }, first create the last list node, with value 2 and Null as its next node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode 0 Null
≡ (λv.λn.λx.λf.f (n x f) v) 0 (λx.λf.x)
≡ (λn.λx.λf.f (n x f) 0) (λx.λf.x)
≡ λx.λf.f ((λx.λf.x) x f) 0
≡ λx.λf.f x 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the previous node can be created with value 1 and the above node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode 1 (CreateListNode 0 Null)
≡ CreateListNode 1 (λx.λf.f x 0)
≡ (λv.λn.λx.λf.f (n x f) v) 1 (λx.λf.f x 0)
≡ (λn.λx.λf.f (n x f) 1) (λx.λf.f x 0)
≡ λx.λf.f ((λx.λf.f x 0) x f) 1
≡ λx.λf.f (f x 0) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the first node has value 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode 2 (CreateListNode 1 (CreateListNode 0 Null))
≡ CreateListNode 2 (λx.λf.f (f x 0) 1)
≡ (λv.λn.λx.λf.f (n x f) v) 2 (λx.λf.f (f x 0) 1)
≡ (λn.λx.λf.f (n x f) 2) (λx.λf.f (f x 0) 1)
≡ λx.λf.f (λx.λf.f (f x 0) 1) x f) 2
≡ λx.λf.f (f (f x 0) 1) 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the list nodes are represented in the same pattern as LINQ aggregation.&lt;/p&gt;
&lt;p&gt;The IsNull predicate can be defined as following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull := λl.l True (λx.λv.False)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The variable l is the list node, which is an aggregate function, and is applied with seed True and accumulate function λv.λx.False. When IsNull is applied with a null node, the accumulate function is not applied, and seed True is directly returned:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull Null
≡ (λl.l True (λx.λv.False)) (λx.λf.x)
≡ (λx.λf.x) True (λx.λv.False)
≡ (λf.True) (λx.λv.False)
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And when IsNull is applied with a non null node, the accumulator function is applied and constantly returns False, so IsNull returns False:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull (CreateListNode 2 Null)
≡ IsNull (λx.λf.f x 2)
≡ (λl.l True (λx.λv.False)) (λx.λf.f x 2)
≡ (λx.λf.f x 2) True (λx.λv.False)
≡ (λf.f True 2) (λx.λv.False)
≡ (λx.λv.False) True 2
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;

public static partial class ChurchAggregateList&amp;lt;T&amp;gt;
{
    public static readonly AggregateListNode&amp;lt;T&amp;gt;
        Null = x =&amp;gt; f =&amp;gt; x;

    public static readonly Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, Boolean&amp;gt;
        IsNull = node =&amp;gt; node(True)(x =&amp;gt; value =&amp;gt; False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following function returns the value from the specified node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Value := λl.l Id (λx.λv.v)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Value is applied with a node, which has value v and next node n:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Value (CreateListNode v n)
≡ Value (λx.λf.f (n x f) v)
≡ (λl.l Id (λx.λv.v)) (λx.λf.f (n x f) v)
≡ (λx.λf.f (n x f) v) Id (λx.λv.v)
≡ (λf.f (n Id f) v) (λx.λv.v)
≡ (λx.λv.v) (n Id f) v
≡ (λv.v) v
≡ v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Value = node =&amp;gt; node(Id)(x =&amp;gt; value =&amp;gt; value)
public static readonly Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, T&amp;gt;
    Value = node =&amp;gt; node(Functions&amp;lt;T&amp;gt;.Id)(x =&amp;gt; value =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is not very intuitive to get a node’s next node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Next := λl.λx.λf.l (λf.x) (λx.λv.λg.g (x f) v) (λx.λv.v)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Next = node =&amp;gt; x =&amp;gt; f =&amp;gt; node(_ =&amp;gt; x)(accumulate =&amp;gt; value =&amp;gt; (g =&amp;gt; g(accumulate(f))(value)))(accumulate =&amp;gt; value =&amp;gt; accumulate);
public static readonly Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;
    Next = node =&amp;gt; x =&amp;gt; f =&amp;gt; node(new Func&amp;lt;Func&amp;lt;dynamic, Func&amp;lt;T, dynamic&amp;gt;&amp;gt;, dynamic&amp;gt;(_ =&amp;gt; x))(accumulate =&amp;gt; value =&amp;gt; new Func&amp;lt;Func&amp;lt;dynamic, Func&amp;lt;T, dynamic&amp;gt;&amp;gt;, dynamic&amp;gt;(g =&amp;gt; g(accumulate(f))(value)))(new Func&amp;lt;dynamic, Func&amp;lt;T, dynamic&amp;gt;&amp;gt;(accumulate =&amp;gt; value =&amp;gt; accumulate));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above definition is similar to the the pattern of initial version Subtract function for Church numeral. So it can be defined by shifting tuple too. Again, list node with value v and next node n is a aggregate function, it can be applied with a tuple of Null nodes as seed, and a accumulator function to swap the tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(CreateListNode v n) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (λx.λf.f (n x f) v) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (λf.f (n (Null, Null) f) v) (λt.λv.Shift (CreateListNode v) t)
≡ (λt.λv.Shift (CreateListNode v) t) (n (Null, Null) (λt.λv.Shift (CreateListNode v)) t) v
≡ (λv.Shift (CreateListNode v) (n (Null, Null) (λt.λv.Shift (CreateListNode v)) t)) v
≡ Shift (CreateListNode v) (n (Null, Null) (λt.λv.Shift (CreateListNode v)) t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take list { n, n – 1, …, 2, 1, 0 } as example, assume its nodes are ListNoden, ListNoden - 1, …, ListNode2, ListNode1, ListNode0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the last node is: CreateListNode 0 Null&lt;/li&gt;
&lt;li&gt;the second last node is: CreateListNode 1 (CreateListNode 0 Null)&lt;/li&gt;
&lt;li&gt;the third last node is: CreateListNode 2 (CreateListNode 1 (CreateListNode 0 Null))&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now apply these nodes with above tuple seed and tuple shifting accumulator function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ListNode0 (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (CreateListNode 0 Null) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ Shift (CreateListNode 0) (Null (Null, Null) (λt.λv.Shift (CreateListNode v)) t)
≡ Shift (CreateListNode 0) ((λx.λf.λx) (Null, Null) (λt.λv.Shift (CreateListNode v)) t)
≡ Shift (CreateListNode 0) (Null, Null)
≡ (Null, CreateListNode 0 Null)
≡ (Null, ListNode0)

  ListNode1 (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (CreateListNode 1 (CreateListNode 0 Null)) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ Shift (CreateListNode 1) ((CreateListNode 0 Null) (Null, Null) (λt.λv.Shift (CreateListNode v)) t)
≡ Shift (CreateListNode 1) (Null, Create ListNode 0 Null)
≡ (CreateListNode 0 Null, (CreateListNode 1 (CreateListNode 0 Null))
≡ (ListNode0, ListNode1)

  ListNode2 (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (CreateListNode 2 (CreateListNode 1 (CreateListNode 0 Null))) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ Shift (CreateListNode 2) ((CreateListNode 1 (CreateListNode 0 Null)) (Null, Null) (λt.λv.Shift (CreateListNode v)) t)
≡ Shift (CreateListNode 2) (CreateListNode 0 Null, (CreateListNode 1 (CreateListNode 0 Null))
≡ ((CreateListNode 1 (CreateListNode 0 Null), CreateListNode 2 (CreateListNode 1 (CreateListNode 0 Null)))
≡ (ListNode1, ListNode2)

...

  ListNoden (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (ListNoden - 1, ListNoden)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, there is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(CreateListNode v n) (Null, Null) (λt.λv.Shift (CreateListNode v) t)
≡ (n, Create v n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Next can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Next := λl.Item2 (l (CreateTuple Null Null) (λt.λv.Shift (CreateListNode v) t))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Next = node =&amp;gt; node((Null, Null))(tuple =&amp;gt; value =&amp;gt; tuple.Shift(ChurchTuple.Create(value))).Item1()
public static readonly Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;
    Next = node =&amp;gt;
        ((Tuple&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;)node
            (ChurchTuple&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;.Create(Null)(Null))
            (tuple =&amp;gt; value =&amp;gt; ((Tuple&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;)tuple).Shift(Create(value))))
        .Item1();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The indexer can be defined the same as above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ListNodeAt := λl.λi.i Next l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Func&amp;lt;AggregateListNode&amp;lt;T&amp;gt;, Func&amp;lt;Numeral, AggregateListNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    ListNodeAt = start =&amp;gt; index =&amp;gt; index(node =&amp;gt; Next(node))(start);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following are the extension methods wrapping the list operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class AggregateListNodeExtensions
{
    public static Boolean IsNull&amp;lt;T&amp;gt;(this AggregateListNode&amp;lt;T&amp;gt; node) =&amp;gt; ChurchAggregateList&amp;lt;T&amp;gt;.IsNull(node);

    public static T Value&amp;lt;T&amp;gt;(this AggregateListNode&amp;lt;T&amp;gt; node) =&amp;gt; ChurchAggregateList&amp;lt;T&amp;gt;.Value(node);

    public static AggregateListNode&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;(this AggregateListNode&amp;lt;T&amp;gt; node) =&amp;gt; 
        ChurchAggregateList&amp;lt;T&amp;gt;.Next(node);

    public static AggregateListNode&amp;lt;T&amp;gt; ListNodeAt&amp;lt;T&amp;gt;(this AggregateListNode&amp;lt;T&amp;gt; start, Numeral index) =&amp;gt; 
        ChurchAggregateList&amp;lt;T&amp;gt;.ListNodeAt(start)(index);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following code demonstrate how the list works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class ChurchAggregateListTests
{
    [TestMethod]
    public void CreateValueNextTest()
    {
        AggregateListNode&amp;lt;int&amp;gt; node1 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(1)(ChurchAggregateList&amp;lt;int&amp;gt;.Null);
        AggregateListNode&amp;lt;int&amp;gt; node2 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(2)(node1);
        AggregateListNode&amp;lt;int&amp;gt; node3 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.AreEqual(1, node1.Value());
        Assert.IsTrue(node1.Next().IsNull().Unchurch());
        Assert.AreEqual(2, node2.Value());
        Assert.AreEqual(node1.Value(), node2.Next().Value());
        Assert.AreEqual(3, node3.Value());
        Assert.AreEqual(node2.Value(), node3.Next().Value());
        Assert.AreEqual(node1.Value(), node3.Next().Next().Value());
        Assert.IsTrue(node3.Next().Next().Next().IsNull().Unchurch());
    }

    [TestMethod]
    public void IsNullTest()
    {
        AggregateListNode&amp;lt;int&amp;gt; node1 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(1)(ChurchAggregateList&amp;lt;int&amp;gt;.Null);
        AggregateListNode&amp;lt;int&amp;gt; node2 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(2)(node1);
        AggregateListNode&amp;lt;int&amp;gt; node3 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.IsTrue(ChurchAggregateList&amp;lt;int&amp;gt;.Null.IsNull().Unchurch());
        Assert.IsFalse(node1.IsNull().Unchurch());
        Assert.IsFalse(node2.IsNull().Unchurch());
        Assert.IsFalse(node3.IsNull().Unchurch());
        Assert.IsTrue(node1.Next().IsNull().Unchurch());
        Assert.IsFalse(node2.Next().IsNull().Unchurch());
        Assert.IsFalse(node3.Next().IsNull().Unchurch());
    }

    [TestMethod]
    public void IndexTest()
    {
        AggregateListNode&amp;lt;int&amp;gt; node1 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(1)(ChurchAggregateList&amp;lt;int&amp;gt;.Null);
        AggregateListNode&amp;lt;int&amp;gt; node2 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(2)(node1);
        AggregateListNode&amp;lt;int&amp;gt; node3 = ChurchAggregateList&amp;lt;int&amp;gt;.Create(3)(node2);
        Assert.AreEqual(node3.Value(), node3.NodeAt(0U.Church()).Value());
        Assert.AreEqual(node2.Value(), node3.NodeAt(1U.Church()).Value());
        Assert.AreEqual(node1.Value(), node3.NodeAt(2U.Church()).Value());
        Assert.IsTrue(node3.NodeAt(3U.Church()).IsNull().Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Model everything&lt;/h2&gt;
&lt;p&gt;Once again, in lambda calculus the only primitive is anonymous function. So far many data types and operations are modeled by anonymous functions, including Boolean, unsigned and signed numeral, tuple, list, logic, arithmetic (except division, which will be implemented later), predicate, etc. With these facilities, many other data types and operations can be modeled too. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Floating_point&quot;&gt;Floating point number&lt;/a&gt; can be represented in the form of significand * baseexponent. In &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_floating_point&quot;&gt;IEEE 754 (aka IEC 60559)&lt;/a&gt;, floating point numbers are &lt;a href=&quot;https://www.h-schmidt.net/FloatConverter/IEEE754.html&quot;&gt;represented&lt;/a&gt; as binary format (sign) significand * 2exponent (&lt;a href=&quot;http://www.ecma-international.org/publications/standards/Ecma-335.htm&quot;&gt;System.Single and System.Double&lt;/a&gt; in .NET), and decimal format (sign) significand * 10exponent (System.Decimal). So either representation can be modeled with a 3-tuple of (Boolean, unsigned numeral, signed numeral).&lt;/li&gt;
&lt;li&gt;Character (System.Char in .NET) can be represented by unsigned numeral.&lt;/li&gt;
&lt;li&gt;String (System.String in .NET) can be modeled by a list of characters.&lt;/li&gt;
&lt;li&gt;Tuple and list can represent other data structures, like tree, stack, queue, etc.&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And eventually everything can be modeled with anonymous function represented by lambda expression. Actually, lambda calculus is a classic example of &lt;a href=&quot;https://en.wikipedia.org/wiki/Turing_completeness&quot;&gt;Turing completeness&lt;/a&gt;. Lambda calculus is introduced by Alonzo Church before &lt;a href=&quot;https://en.wikipedia.org/wiki/Turing_machine&quot;&gt;Turing machine&lt;/a&gt; was introduced by Alan Turing, and they are equivalent. Lambda calculus, as a universal model of computation, is the rationale and foundations of functional programming. Functional languages (or the functional subset of languages) can be viewed as lambda calculus with more specific syntax, and the execution of functional program can be viewed as reduction of lambda calculus expression.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (4) Tuple and Signed Numeral</title><link>https://dixin.github.io/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral/</guid><description>Besides modeling values like Boolean and numeral, anonymous function can also model data structures. In Church encoding, Church pair is an approach to use functions to represent a tuple of 2 items.</description><pubDate>Sun, 10 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Besides modeling values like Boolean and numeral, anonymous function can also model data structures. In Church encoding, Church pair is an approach to use functions to represent a tuple of 2 items.&lt;/p&gt;
&lt;h2&gt;Church pair (2-tuple)&lt;/h2&gt;
&lt;p&gt;A tuple can be constructed with its first item x, its second item y, and a function f:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateTuple := λx.λy.λf.f x y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a tuple is can be created by partially applying CreateTuple with 2 items x and y:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple := CreateTuple x y
       ≡ (λx.λy.λf.f x y) x y
       ≡ λf.f x y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a tuple is a higher-order function, which accept a function f, and apply it with its 2 items. So f accepts 2 arguments, it is in the form of λx.λy.E.&lt;/p&gt;
&lt;p&gt;To get the tuple’s first item x, just apply the tuple function with a specific function f, where f simply accepts 2 items and returns the first item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple (λx.λy.x)
≡ (λf.f x y) (λx.λy.x)
≡ (λx.λy.x) x y
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, to get the tuple’s second item y, just apply tuple function with a specific function f, where f simply accepts 2 items and returns the first item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple (λx.λy.y)
≡ (λf.f x y) (λx.λy.y)
≡ (λx.λy.y) x y
≡ y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the following Item1 function is defined to accept a tuple, apply the tuple function with function λx.λy.x, and return the tuple’s first item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 := λt.t (λx.λy.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, this is how it works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 (CreateTuple x y)
≡ (λt.t (λx.λy.x)) (CreateTuple x y)
≡ (λt.t (λx.λy.x)) (λf.f x y)
≡ (λf.f x y) (λx.λy.x)
≡ (λx.λy.x) x y
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And Item2 function can ne defined in the same way to get the tuple’s second item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item2 := λt.t (λx.λy.y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice functions λx.λy.x and λx.λy.y can be alpha converted to λt.λf.t and λt.λf.f, which are just Church Boolean True and False. So Item1 and Item2 can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 := λt.t True
Item2 := λt.t False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement tuple in C#, its function type needs to be identified. The tuple function accepts argument f, which is either function True of function False, so f is of function type Boolean. In the body of tuple function, f is applied, and f returns dynamic. So tuple virtually is of function type Boolean -&amp;gt; dynamic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;

// Tuple is the alias of (dynamic -&amp;gt; dynamic -&amp;gt; dynamic) -&amp;gt; dynamic.
public delegate dynamic Tuple&amp;lt;out T1, out T2&amp;gt;(Boolean f);

public static partial class ChurchTuple&amp;lt;T1, T2&amp;gt;
{
    public static readonly Func&amp;lt;T1, Func&amp;lt;T2, Tuple&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt; 
        Create = item1 =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2);

    // Item1 = tuple =&amp;gt; tuple(True)
    public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;, T1&amp;gt; 
        Item1 = tuple =&amp;gt; (T1)(object)tuple(True);

    // Item2 = tuple =&amp;gt; tuple(False)
    public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;, T2&amp;gt; 
        Item2 = tuple =&amp;gt; (T2)(object)tuple(False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are type conversions in Item1/Item2 functions. At compiled time, the tuple function returns dynamic, and at runtime it actually it calls True/False function to return either item1 or item2 . So the type conversions are always safe. Also notice here tuple function’s return value cannot be directly converted to T1 or T2, because of a &lt;a href=&quot;http://stackoverflow.com/questions/37392566/&quot;&gt;bug of C# runtime binding layer&lt;/a&gt;. The workaround is to convert dynamic to object first, then convert to T1 or T2.&lt;/p&gt;
&lt;p&gt;The following are the extension methods for convenience:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TupleExtensions
{
    public static T1 Item1&amp;lt;T1, T2&amp;gt;(this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2&amp;gt;.Item1(tuple);

    public static T2 Item2&amp;lt;T1, T2&amp;gt;(this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2&amp;gt;.Item2(tuple);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, a point can be a tuple of 2 numerals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Point(Numeral x, Numeral y)
{
    Tuple&amp;lt;Numeral, Numeral&amp;gt; point1 = ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(x)(y);
    Numeral x1 = point1.Item1();
    Numeral y1 = point1.Item1();

    // Move up.
    Numeral y2 = y1.Increase();
    Tuple&amp;lt;Numeral, Numeral&amp;gt; point2 = ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(x1)(y2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Tuple operators&lt;/h3&gt;
&lt;p&gt;The Swap function accepts a tuple (x, y), swaps its first item and second item, and returns a new tuple (y, x):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Swap := λt.CreateTuple (Item2 t)(Item1 t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, Swap is of function type Tuple&amp;lt;T1, T2&amp;gt; -&amp;gt; Tuple&amp;lt;T2, T1&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Swap = tuple =&amp;gt; Create(tuple.Item2())(tuple.Item1())
public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;, Tuple&amp;lt;T2, T1&amp;gt;&amp;gt;
    Swap = tuple =&amp;gt; ChurchTuple&amp;lt;T2, T1&amp;gt;.Create(tuple.Item2())(tuple.Item1());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Shift function accepts a tuple (x, y) and a function f, and returns a new tuple (y, f y):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shift := λf.λt.CreateTuple (Item2 t) (f (Item2 t))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here assume the argument tuple (x, y) is of type Tuple&amp;lt;T1, T2&amp;gt;, regarding f is applied with y, assume f returns TResult type, then f is of function type T2 -&amp;gt; TResult, so that the returned new tuple (y, f y) is of type Tuple&amp;lt;T2, TResult&amp;gt;. As a result, Shift is of type Tuple&amp;lt;T1, T2&amp;gt; -&amp;gt; (T2 -&amp;gt; TResult) -&amp;gt; Tuple&amp;lt;T2, TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchTuple&amp;lt;T1, T2, TResult&amp;gt;
{
    // Shift = f =&amp;gt; tuple =&amp;gt; Create(tuple.Item2())(f(tuple.Item1()))
    public static readonly Func&amp;lt;Func&amp;lt;T2, TResult&amp;gt;, Func&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;, Tuple&amp;lt;T2, TResult&amp;gt;&amp;gt;&amp;gt;
        Shift = f =&amp;gt; tuple =&amp;gt; ChurchTuple&amp;lt;T2, TResult&amp;gt;.Create(tuple.Item2())(f(tuple.Item2()));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And their extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Tuple&amp;lt;T2, T1&amp;gt; Swap&amp;lt;T1, T2&amp;gt;(this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2&amp;gt;.Swap(tuple);

public static Tuple&amp;lt;T2, TResult&amp;gt; Shift&amp;lt;T1, T2, TResult&amp;gt;(this Tuple&amp;lt;T1, T2&amp;gt; tuple, Func&amp;lt;T2, TResult&amp;gt; f) =&amp;gt; 
    ChurchTuple&amp;lt;T1, T2, TResult&amp;gt;.Shift(f)(tuple);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Shift function can be used to define the Subtract function for Church numerals. Remember a Church numeral n can be viewed as to apply Increase n times from 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n Increase 0
≡ n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying Shift with Increase and a tuple of Church numerals, it returns a new tuple of Church numerals, so this application can repeat forever:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shift Increase (0, 0)
≡ (0, Increase 0)
≡ (0, 1)

  Shift Increase (0, 1)
≡ (1, Increase 1)
≡ (1, 2)

  Shift Increase (1, 2)
≡ (2, Increase 2)
≡ (2, 3)

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In another word, partially applying Shift with Increase is a function that can be repeatedly applied with a tuple of Church numerals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(Shift Increase) (0, 0)                                       ≡ (Shift Increase)1 (0, 0) ≡ 1 (Shift Increase) (0, 0) 
≡ (0, 1)

  (Shift Increase) (0, 1)
≡ (Shift Increase) ((Shift Increase) (0, 0))
≡ (Shift Increase) ∘ (Shift Increase) (0, 0)                    ≡ (Shift Increase)2 (0, 0) ≡ 2 (Shift Increase) (0, 0) 
≡ (1, 2)

  (Shift Increase) (1, 2)
≡ (Shift Increase) ((Shift Increase) ∘ (Shift Increase) (0, 0))
≡ (Shift Increase) ∘ (Shift Increase) ∘ (Shift Increase) (0, 0) ≡ (Shift Increase)3 (0, 0) ≡ 3 (Shift Increase) (0, 0) 
≡ (2, 3)

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n (Shift Increase) (0, 0)
≡ (n - 1, n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, to decrease n to n – 1, just apply n with function (Shift Increase) and tuple (0, 0), get the result tuple (n – 1, n), and return its first item:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 (n (Shift Increase) (0, 0))
≡ Item1 (n - 1, n)
≡ n - 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Decrease can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease := λn.Item1 (n (Shift Increase) (CreateTuple 0 0))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Decrease = n =&amp;gt; n(tuple =&amp;gt; tuple.Shift(Increase))(0, 0).Item1();
public static readonly Func&amp;lt;Numeral, Numeral&amp;gt; Decrease = n =&amp;gt;
    ((Tuple&amp;lt;Numeral, Numeral&amp;gt;)n
        (tuple =&amp;gt; ((Tuple&amp;lt;Numeral, Numeral&amp;gt;)tuple).Shift(Increase))
        (ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(Zero)(Zero)))
    .Item1();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;N-tuple&lt;/h2&gt;
&lt;p&gt;An easy way is to model n-tuple as a 2-tuple of the first value and a (n-1)-tuple of the rest values. A 3 tuple of values 1, 2, 3 can be represented by nested 2-tuples as (a, (b, c)), a 4-tuple of values 1, 2, 3, 4 can be represented by nested 2-tuples (1, (2, (3, 4))), etc., and a n tuple of values 1, 2, 3, …, n can be represented by nested 2 tuples (1, (2, (3, (…(n-1, n)…)))). For example, the following is the definition of 3 tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Create3Tuple := λx.λy.λz.CreateTuple x (CreateTuple y z)

3TupleItem1 := λt.Item1 t
3TupleItem2 := λt.Item1 (Item2 t)
3TupleItem3 := λt.Item2 (Item2 t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate dynamic Tuple&amp;lt;out T1, out T2, out T3&amp;gt;(Boolean f);

public static partial class ChurchTuple&amp;lt;T1, T2, T3&amp;gt;
{
    // Create = item1 =&amp;gt; item2 =&amp;gt; item3 =&amp;gt; Create(item1)(Create(item2)(item3))
    public static readonly Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Tuple&amp;lt;T1, T2, T3&amp;gt;&amp;gt;&amp;gt;&amp;gt;
        Create = item1 =&amp;gt; item2 =&amp;gt; item3 =&amp;gt; new Tuple&amp;lt;T1, T2, T3&amp;gt;(ChurchTuple&amp;lt;T1, Tuple&amp;lt;T2, T3&amp;gt;&amp;gt;.Create(item1)(ChurchTuple&amp;lt;T2, T3&amp;gt;.Create(item2)(item3)));

    // Item1 = tuple.Item1()
    public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2, T3&amp;gt;, T1&amp;gt;
        Item1 = tuple =&amp;gt; new Tuple&amp;lt;T1, Tuple&amp;lt;T2, T3&amp;gt;&amp;gt;(tuple).Item1();

    // Item2 = tuple.Item2().Item1()
    public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2, T3&amp;gt;, T2&amp;gt;
        Item2 = tuple =&amp;gt; new Tuple&amp;lt;T1, Tuple&amp;lt;T2, T3&amp;gt;&amp;gt;(tuple).Item2().Item1();

    // Item3 = tuple.Item2().Item2()
    public static readonly Func&amp;lt;Tuple&amp;lt;T1, T2, T3&amp;gt;, T3&amp;gt;
        Item3 = tuple =&amp;gt; new Tuple&amp;lt;T1, Tuple&amp;lt;T2, T3&amp;gt;&amp;gt;(tuple).Item2().Item2();
}

public static partial class TupleExtensions
{
    public static T1 Item1&amp;lt;T1, T2, T3&amp;gt;(this Tuple&amp;lt;T1, T2, T3&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2, T3&amp;gt;.Item1(tuple);

    public static T2 Item2&amp;lt;T1, T2, T3&amp;gt;(this Tuple&amp;lt;T1, T2, T3&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2, T3&amp;gt;.Item2(tuple);

    public static T3 Item3&amp;lt;T1, T2, T3&amp;gt;(this Tuple&amp;lt;T1, T2, T3&amp;gt; tuple) =&amp;gt; ChurchTuple&amp;lt;T1, T2, T3&amp;gt;.Item3(tuple);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Signed numeral&lt;/h2&gt;
&lt;p&gt;With tuple, a signed numeral (integer) can be modeled by a pair of Church numerals (natural numbers), where the first item represents the positive value, and the second item represents the negative value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SignedNumeral := Tuple
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example (1, 0) and (2, 1) models 1, (0, 2) and (1, 3) models –2, (0, 0) and (1, 1) models 0, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 := (1, 0) ≡ (2, 1) ≡ (3, 2) ≡ (4, 3) ≡ ...
 0 := (0, 0) ≡ (1, 1) ≡ (2, 2) ≡ (3, 3) ≡ ...
-2 := (0, 2) ≡ (1, 3) ≡ (2, 4) ≡ (3, 5) ≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, the function type SignedNumeral is the same as Tuple, except SignedNumeral is not open generic type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SignedNumeral is the alias of Tuple&amp;lt;Numeral, Numeral&amp;gt;.
public delegate dynamic SignedNumeral(Boolean f);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Church numeral represents natural number. So Converting a Church numeral n to signed number is easy, just make it a tuple (n, 0):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sign := λn.CreateTuple n 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To negate a signed numeral, just swap its positive value and negative value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Negate := Swap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it is straightforward to get the positive value and the negative value from a signed number:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Positive := Item1
Negative := Item2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Signed numeral like (4, 3), (3, 3), (3, 5) can be formatted to have at least one 0: (1, 0), (0, 0), (0, 2). For a signed number s represented by (p, n), If p &amp;gt;= n, then it is (p - n, 0), otherwise it is (0, n – p):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Format := λs.If (sp &amp;gt;=  sn) (λx.(sp - sn, 0)) (λx.(0, sn - sp))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Sp is the positive value of s, and sn the the negative value of s.&lt;/p&gt;
&lt;p&gt;The following are these function’s C# implementation, and the extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;
using static ChurchNumeral;

public static partial class ChurchSignedNumeral
{
    // Sign = n =&amp;gt; (n, 0)
    public static readonly Func&amp;lt;Numeral, SignedNumeral&amp;gt;
        Sign = n =&amp;gt; new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(n)(Zero));

    // Negate = signed =&amp;gt; signed.Swap()
    public static readonly Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;
        Negate = signed =&amp;gt; new SignedNumeral(new Tuple&amp;lt;Numeral, Numeral&amp;gt;(signed).Swap());

    // Positive = signed =&amp;gt; signed.Item1()
    public static readonly Func&amp;lt;SignedNumeral, Numeral&amp;gt;
        Positive = signed =&amp;gt; new Tuple&amp;lt;Numeral, Numeral&amp;gt;(signed).Item1();

    // Negative = signed =&amp;gt; signed.Item2()
    public static readonly Func&amp;lt;SignedNumeral, Numeral&amp;gt;
        Negative = signed =&amp;gt; new Tuple&amp;lt;Numeral, Numeral&amp;gt;(signed).Item2();

    // Format = signed =&amp;gt;
    //    If(positive &amp;gt;= negative)
    //        (_ =&amp;gt; (positive - negative, 0))
    //        (_ =&amp;gt; (0, negative - positive))
    public static readonly Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;
        Format = signed =&amp;gt;
            If(signed.Positive().IsGreaterThanOrEqualTo(signed.Negative()))
                (_ =&amp;gt; signed.Positive().Subtract(signed.Negative()).Sign())
                (_ =&amp;gt; signed.Negative().Subtract(signed.Positive()).Sign().Negate());
}

public static partial class SignedNumeralExtensions
{
    public static SignedNumeral Sign(this Numeral n) =&amp;gt; ChurchSignedNumeral.Sign(n);

    public static SignedNumeral Negate(this SignedNumeral signed) =&amp;gt; ChurchSignedNumeral.Negate(signed);

    public static Numeral Positive(this SignedNumeral signed) =&amp;gt; ChurchSignedNumeral.Positive(signed);

    public static Numeral Negative(this SignedNumeral signed) =&amp;gt; ChurchSignedNumeral.Negative(signed);

    public static SignedNumeral Format(this SignedNumeral signed) =&amp;gt; ChurchSignedNumeral.Format(signed);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Arithmetic operators&lt;/h3&gt;
&lt;p&gt;Naturally, for signed numbers a, b:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a + b
≡ (ap, an) + (bp, bn)
≡ (ap - an) + (bp - bn)
≡ (ap + bp, an + bn)

  a - b
≡ (ap, an) - (bp, bn)
≡ (ap - an) - (bp - bn)
≡ (ap + bn, an + bp)

  a * b
≡ (ap, an) * (bp, bn)
≡ (ap - an) * (bp - bn)
≡ (ap * bp + an * bn, ap * bn + an * bp)

  a / b
≡ (ap, an) / (bp, bn)
≡ (ap - an) / (bp - bn)
≡ (ap / bp + an / bn, ap / bn + an / bp)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AddSigned := λa.λb.Format (CreateTuple (ap + bp) (an + bn))
SubtractSigned := λa.λb.Format (CreateTuple (ap + bn) (an + bp))
MultiplySigned := λa.λb.Format (CreateTuple (ap * bp + an * bn) (ap * bn + an * bp))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Division is more tricky because a and b’s positive and negative values can be 0. In this case, just return 0 when dividing by 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideByIgnoreZero := λa.λb.If (IsZero b) (λx.0) (λx.DivideBy a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the DivideBy function for Church numeral is used. As fore mentioned, this DivideBy function is not well defined. It is temporarily used here and will be revisited later. So division can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideBySigned := λa.λb.Format (CreateTuple ((DivideByIgnoreZero ap bp) + (DivideByIgnoreZero an bn)) ((DivideByIgnoreZero ap bn) + (DivideByIgnoreZero an bp)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following are the C# implementations and the extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchSignedNumeral
{
    // Add = a =&amp;gt; b =&amp;gt; (a.Positive() + b.Positive(), a.Negative() + b.Negative()).Format()
    public static readonly Func&amp;lt;SignedNumeral, Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;&amp;gt;
        Add = a =&amp;gt; b =&amp;gt; new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create
                (a.Positive().Add(b.Positive()))
                (a.Negative().Add(b.Negative())))
            .Format();

    // Subtract = a =&amp;gt; b =&amp;gt; (a.Positive() + b.Negative(), a.Negative() + b.Positive()).Format()
    public static readonly Func&amp;lt;SignedNumeral, Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;&amp;gt;
        Subtract = a =&amp;gt; b =&amp;gt; new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create
                (a.Positive().Add(b.Negative()))
                (a.Negative().Add(b.Positive())))
            .Format();

    // Multiply = a =&amp;gt; b =&amp;gt; (a.Positive() * b.Positive() + a.Negative() * b.Negative(), a.Positive() * b.Negative() + a.Negative() * b.Positive()).Format()
    public static readonly Func&amp;lt;SignedNumeral, Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;&amp;gt;
        Multiply = a =&amp;gt; b =&amp;gt; new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create
                (a.Positive().Multiply(b.Positive()).Add(a.Negative().Multiply(b.Negative())))
                (a.Positive().Multiply(b.Negative()).Add(a.Negative().Multiply(b.Positive()))))
            .Format();

    // / = dividend =&amp;gt; divisor =&amp;gt; If(divisor.IsZero())(_ =&amp;gt; 0)(_ =&amp;gt; dividend.DivideBy(divisor))
    private static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; 
        DivideByIgnoreZero = dividend =&amp;gt; divisor =&amp;gt;
            ChurchBoolean&amp;lt;Numeral&amp;gt;.If(divisor.IsZero())
                (_ =&amp;gt; Zero)
                (_ =&amp;gt; dividend.DivideBy(divisor));

    // DivideBy = dividend =&amp;gt; divisor =&amp;gt; (dividend.Positive() / divisor.Positive() + dividend.Negative() / divisor.Negative(), dividend.Positive() / divisor.Negative() + dividend.Negative() / divisor.Positive()).Format();
    public static readonly Func&amp;lt;SignedNumeral, Func&amp;lt;SignedNumeral, SignedNumeral&amp;gt;&amp;gt;
        DivideBy = dividend =&amp;gt; divisor =&amp;gt; new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create
                (DivideByIgnoreZero(dividend.Positive())(divisor.Positive()).Add(DivideByIgnoreZero(dividend.Negative())(divisor.Negative())))
                (DivideByIgnoreZero(dividend.Positive())(divisor.Negative()).Add(DivideByIgnoreZero(dividend.Negative())(divisor.Positive()))))
            .Format();
}

public static partial class SignedNumeralExtensions
{
    public static SignedNumeral Add(this SignedNumeral a, SignedNumeral b) =&amp;gt; ChurchSignedNumeral.Add(a)(b);

    public static SignedNumeral Subtract(this SignedNumeral a, SignedNumeral b) =&amp;gt; ChurchSignedNumeral.Subtract(a)(b);

    public static SignedNumeral Multiply(this SignedNumeral a, SignedNumeral b) =&amp;gt; ChurchSignedNumeral.Multiply(a)(b);

    public static SignedNumeral DivideBy(this SignedNumeral dividend, SignedNumeral divisor) =&amp;gt; ChurchSignedNumeral.DivideBy(dividend)(divisor);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following code demonstrate how these operators work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class ChurchSignedNumeralTests
{
    [TestMethod]
    public void SignNegatePositiveNegativeTest()
    {
        SignedNumeral signed = 0U.Church().Sign();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());

        signed = 1U.Church().Sign();
        Assert.IsTrue(1U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(1U == signed.Negative().Unchurch());

        signed = 2U.Church().Sign();
        Assert.IsTrue(2U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(2U == signed.Negative().Unchurch());

        signed = 123U.Church().Sign();
        Assert.IsTrue(123U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(123U == signed.Negative().Unchurch());

        signed = new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(12U.Church())(23U.Church()));
        Assert.IsTrue(12U == signed.Positive().Unchurch());
        Assert.IsTrue(23U == signed.Negative().Unchurch());
        signed = signed.Negate();
        Assert.IsTrue(23U == signed.Positive().Unchurch());
        Assert.IsTrue(12U == signed.Negative().Unchurch());
    }

    [TestMethod]
    public void FormatWithZeroTest()
    {
        SignedNumeral signed = new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(12U.Church())(23U.Church()));
        signed = signed.Format();
        Assert.IsTrue(0U == signed.Positive().Unchurch());
        Assert.IsTrue(11U == signed.Negative().Unchurch());

        signed = new SignedNumeral(ChurchTuple&amp;lt;Numeral, Numeral&amp;gt;.Create(23U.Church())(12U.Church()));
        signed = signed.Format();
        Assert.IsTrue(11U == signed.Positive().Unchurch());
        Assert.IsTrue(0U == signed.Negative().Unchurch());
    }

    [TestMethod]
    public void AddTest()
    {
        SignedNumeral a = 0U.Church().Sign();
        SignedNumeral b = 0U.Church().Sign();
        SignedNumeral result = a.Add(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 1U.Church().Sign();
        b = 1U.Church().Sign().Negate();
        result = a.Add(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 3U.Church().Sign();
        b = 5U.Church().Sign().Negate();
        result = a.Add(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(2U == result.Negative().Unchurch());
    }

    [TestMethod]
    public void SubtractTest()
    {
        SignedNumeral a = 0U.Church().Sign();
        SignedNumeral b = 0U.Church().Sign();
        SignedNumeral result = a.Subtract(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 1U.Church().Sign();
        b = 1U.Church().Sign().Negate();
        result = a.Subtract(b);
        Assert.IsTrue(2U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 3U.Church().Sign();
        b = 5U.Church().Sign().Negate();
        result = a.Subtract(b);
        Assert.IsTrue(8U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());
    }

    [TestMethod]
    public void MultiplyTest()
    {
        SignedNumeral a = 0U.Church().Sign();
        SignedNumeral b = 0U.Church().Sign();
        SignedNumeral result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 1U.Church().Sign();
        b = 1U.Church().Sign().Negate();
        result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(1U == result.Negative().Unchurch());

        a = 3U.Church().Sign();
        b = 5U.Church().Sign().Negate();
        result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(15U == result.Negative().Unchurch());
    }

    [TestMethod]
    public void DivideByTest()
    {
        SignedNumeral a = 0U.Church().Sign();
        SignedNumeral b = 0U.Church().Sign();
        SignedNumeral result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(0U == result.Negative().Unchurch());

        a = 1U.Church().Sign();
        b = 1U.Church().Sign().Negate();
        result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(1U == result.Negative().Unchurch());

        a = 11U.Church().Sign();
        b = 5U.Church().Sign().Negate();
        result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive().Unchurch());
        Assert.IsTrue(2U == result.Negative().Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (3) Numeral, Arithmetic and Predicate</title><link>https://dixin.github.io/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate/</guid><description>Anonymous functions can also model numerals and their arithmetic. In Church encoding, a natural number n is represented by a function that calls a given function for n times. This representation is ca</description><pubDate>Thu, 07 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Anonymous functions can also model numerals and their arithmetic. In Church encoding, a natural number n is represented by a function that calls a given function for n times. This representation is called Church Numeral.&lt;/p&gt;
&lt;h2&gt;Church numerals&lt;/h2&gt;
&lt;p&gt;Church numerals are defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λfx.x                  ≡ λf.λx.x
1 := λfx.f x                ≡ λf.λx.f x
2 := λfx.f (f x)            ≡ λf.λx.f (f x)
3 := λfx.f (f (f x))        ≡ λf.λx.f (f (f x))
...
n := λfx.f (f ... (f x)...) ≡ λf.λx.f (f .u.. (f x)...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a Church numeral n is a &lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;higher order function&lt;/a&gt;, it accepts a function f and an argument x. When n is applied, it repeatedly applies f for n times by starting with x, and returns the result. If n is 0, f is not applied (in another word, f is applied 0 times), and x is directly returned.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f x ≡ x
1 f x ≡ f x
2 f x ≡ f (f x)
3 f x ≡ f (f (f x))
...
n f x ≡ f (f (... (f x)...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to the definition of function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f (f x) ≡ (f ∘ f) x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This definition is equivalent to compose f for n time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λfx.x                  ≡ λf.λx.x                   ≡ λf.λx.f0 x
1 := λfx.f x                ≡ λf.λx.f x                 ≡ λf.λx.f1 x
2 := λfx.f (f x)            ≡ λf.λx.(f ∘ f) x           ≡ λf.λx.f2 x
3 := λfx.f (f (f x))        ≡ λf.λx.(f ∘ f ∘ f) x       ≡ λf.λx.f3 x
...
n := λfx.f (f ... (f x)...) ≡ λf.λx.(f ∘ f ∘ ... ∘ f) x ≡ λf.λx.fn x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The partial application with f is the composition of f, so Church numeral n can be simply read as – do something n times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f ≡ f0
1 f ≡ f1
2 f ≡ f2
3 f ≡ f3
...
n f ≡ fn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, x can be anything, so leave its type as dynamic. f can be viewed as a function accept a value x and returns something, and f can also accept its returned value again, so f is of type dynamic -&amp;gt; dynamic. And n’ return type is the same as f’s return type, so n returns dynamic too. As a result, n can be virtually viewed as curried function type (dynamic -&amp;gt; dynamic) –&amp;gt; dynamic -&amp;gt; dynamic, which in C# is represented by Func&amp;lt;Func&amp;lt;dynamic, dynamic&amp;gt;, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;. Similar to the C# implementation of Church Boolean, a alias Numeral can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from (dynamic -&amp;gt; dynamic, dynamic) -&amp;gt; dynamic.
// Numeral is the alias of (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic -&amp;gt; dynamic.
public delegate Func&amp;lt;dynamic, dynamic&amp;gt; Numeral(Func&amp;lt;dynamic, dynamic&amp;gt; f);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Based on the definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchNumeral
{
    public static readonly Numeral
        Zero = f =&amp;gt; x =&amp;gt; x;

    public static readonly Numeral
        One = f =&amp;gt; x =&amp;gt; f(x);

    public static readonly Numeral
        Two = f =&amp;gt; x =&amp;gt; f(f(x));

    public static readonly Numeral
        Three = f =&amp;gt; x =&amp;gt; f(f(f(x)));

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also since n f ≡ fn, n can be also implemented with composition of f:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Numeral
    OneWithComposition = f =&amp;gt; f;

// Two = f =&amp;gt; f o f
public static readonly Numeral
    TwoWithComposition = f =&amp;gt; f.o(f);

// Three = f =&amp;gt; f o f o f
public static readonly Numeral
    ThreeWithComposition = f =&amp;gt; f.o(f).o(f);

// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the o operator is the forward composition extension method defined previously. Actually, instead of defining each number individually, Church numeral can be defined recursively by increase or decrease.&lt;/p&gt;
&lt;h2&gt;Increase and decrease&lt;/h2&gt;
&lt;p&gt;By observing the definition and code, there are some patterns when the Church numeral increases from 0 to 3. In the definitions of Church numerals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f (x)
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The expressions in the parenthesis can be reduced from the following function applications expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f x ≡ x
1 f x ≡ f x
2 f x ≡ f (f x)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With substitution, Church numerals’ definition become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f (0 f x)
2 := λf.λx.f (1 f x)
3 := λf.λx.f (2 f x)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows how the the Church numerals increases. Generally, given a Church numeral n, the next numeral n + 1 is λf.λx.f (n f x). So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase := λn.λf.λx.f (n f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, this is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;Numeral, Numeral&amp;gt; 
    Increase = n =&amp;gt; f =&amp;gt; x =&amp;gt; f(n(f)(x));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the other way, Church numeral n is to compose f for n times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n f ≡ fn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So increasing n means to compose f for one more time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase := λn.λf.f ∘ fn ≡ λn.λf.f ∘ (n f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Func&amp;lt;Numeral, Numeral&amp;gt; 
    IncreaseWithComposition = n =&amp;gt; f =&amp;gt; f.o(n(f));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To decrease a Church numeral n, when n is 0, the result is defined as 0, when n is positive, the result is n – 1. The Decrease function is more complex:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease := λn.λf.λx.n (λg.λh.h (g f)) (λv.x) Id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When n is 0, regarding n f ≡ fn, applying Decrease with 0 can be reduced as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease 0
≡ λf.λx.0 (λg.λh.h (g f)) (λv.x) Id
≡ λf.λx.(λg.λh.h (g f))0 (λv.x) Id
≡ λf.λx.(λv.x) Id
≡ λf.λx.x
≡ λf.λx.f0 x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last expression is the definition of 0.&lt;/p&gt;
&lt;p&gt;When n is positive, regarding function function composition is associative, the expression n (λg.λh.h (g f)) (λu.x) can be reduced first. When n is 1, 2, 3, ...:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 (λg.λh.h (g f)) (λv.x)
≡ (λg.λh.h (g f))1 (λv.x)
≡ (λg.λh.h (g f)) (λv.x)
≡ λh.h ((λv.x) f)
≡ λh.h x
≡ λh.h (f0 x) 

  2 (λg.λh.h (g f)) (λv.x)
≡ (λg.λh.h (g f))2 (λv.x)
≡ (λg.λh.h (g f)) ∘ (λg.λh.h (g f))1 (λv.x)
≡ (λg.λh.h (g f)) (λh.h (f0 x))
≡ λh.h (λh.h (f0 x) f)
≡ λh.h (f (f0 x))
≡ λh.h (f1 x)

  3 (λg.λh.h (g f)) (λv.x)
≡ (λg.λh.h (g f))3 (λv.x)
≡ (λg.λh.h (g f)) ∘ (λg.λh.h (g f))2 (λv.x)
≡ (λg.λh.h (g f)) (λh.h (f1 x))
≡ λh.h ((λh.h (f1 x)) f)
≡ λh.h (f (f1 x))
≡ λh.h (f2 x)

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n (λg.λh.h (g f)) (λv.x)
≡ λh.h (fn - 1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when Decrease is applied with positive n:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease n
≡ λf.λx.n (λg.λh.h (g f)) (λv.x) Id
≡ λf.λx.(λh.h (fn - 1 x)) Id
≡ λf.λx.Id (fn - 1 x)
≡ λf.λx.fn - 1 x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The returned result is the definition of n – 1. In the following C# implementation, a lot of noise of type information is involved to implement complex lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Decrease = n =&amp;gt; f =&amp;gt; x =&amp;gt; n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(Id)
public static readonly Func&amp;lt;Numeral, Numeral&amp;gt; 
    Decrease = n =&amp;gt; f =&amp;gt; x =&amp;gt; n(g =&amp;gt; new Func&amp;lt;Func&amp;lt;dynamic, dynamic&amp;gt;, dynamic&amp;gt;(h =&amp;gt; h(g(f))))(new Func&amp;lt;Func&amp;lt;dynamic, dynamic&amp;gt;, dynamic&amp;gt;(_ =&amp;gt; x))(new Func&amp;lt;dynamic, dynamic&amp;gt;(Functions&amp;lt;dynamic&amp;gt;.Id));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the actual types of the elements in above lambda expression at runtime:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;g: (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;h: dynamic -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;g(f): dynamic&lt;/li&gt;
&lt;li&gt;h(g(f)): dynamic&lt;/li&gt;
&lt;li&gt;h =&amp;gt; h(g(f)): (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;g =&amp;gt; h =&amp;gt; h(g(f)): ((dynamic -&amp;gt; dynamic) -&amp;gt; dynamic) -&amp;gt; (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;n(g =&amp;gt; h =&amp;gt; h(g(f))): ((dynamic -&amp;gt; dynamic) -&amp;gt; dynamic) -&amp;gt; (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;_ =&amp;gt; x: (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x): (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;Id: dynamic -&amp;gt; dynamic&lt;/li&gt;
&lt;li&gt;n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(Id): dynamic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At compile time, function types must be provided for a few elements. When n is applied, C# compiler expects its first argument g =&amp;gt; h =&amp;gt; h(g(f)) to be of type dynamic =&amp;gt; dynamic. So C# compiler infers g to dynamic, but cannot infer the type of h =&amp;gt; h(g(f)), which can be expression tree or anonymous function, so the constructor call syntax is used here to specify it is a function of type (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic. Similarly, C# compiler expects n’s second argument to be dynamic, and C# compiler cannot infer the type of _ =&amp;gt; x, so the constructor syntax is used again for _ =&amp;gt; x. Also, Functions&amp;lt;dynamic&amp;gt;.Id is of Unit&amp;lt;dynamic&amp;gt; type, while at runtime a dynamic -&amp;gt; dynamic function is expected. Unit&amp;lt;dynamic&amp;gt; is alias of function type dynamic –&amp;gt; dynamic, but the conversion does not happen automatically at runtime, so the constructor syntax is used once again to indicate the function type conversion.&lt;/p&gt;
&lt;p&gt;Later after introducing Church pair, a cleaner version of Decrease will be implemented.&lt;/p&gt;
&lt;h2&gt;Arithmetic operators&lt;/h2&gt;
&lt;p&gt;To implement add operation, according to the definition, Church numeral a adding Church numeral b means to apply f for a times, then apply f again for b times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add := λa.λb.λf.λx.b f (a f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the definition of function composition, Add can be also defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add := λa.λb.λf.fa ∘ fb ≡ λa.λb.λf.(a f) ∘ (b f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;  
    Add = a =&amp;gt; b =&amp;gt; f =&amp;gt; x =&amp;gt; b(f)(a(f)(x));

public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; 
    AddWithComposition = a =&amp;gt; b =&amp;gt; f =&amp;gt; a(f).o(b(f));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With Increase function, Add can also be defined as increase a for b times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add := λa.λb.b Increase a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, there are some noise of type information again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    AddWithIncrease = a =&amp;gt; b =&amp;gt; b(Increase)(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, the above code cannot be compiled, because b is a function of type (dynamic -&amp;gt; dynamic) -&amp;gt; dynamic x -&amp;gt; dynamic. So its first argument f must be a function of type dynamic -&amp;gt; dynamic. Here, Increase is of type Numeral -&amp;gt; Numeral, and b(Increase) cannot be compiled. The solution is to eta convert Increase to a wrapper function λn.Increase n:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add := λa.λb.a (λn.Increase n) b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Add = a =&amp;gt; b =&amp;gt; b(Increase)(a)
// η conversion:
// Add = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Increase(n))(a)
public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    AddWithIncrease = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Increase(n))(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since a dynamic -&amp;gt; dynamic function is expected and the wrapper function n =&amp;gt; Increase(n), n inferred to be of type dynamic. Increase(n) still returns Numeral, so the wrapper function is of type dynamic -&amp;gt; Numeral. Regarding dynamic is just object, and Numeral derives from object, with support covariance in C#, the wrapper function is implicitly converted to dynamic -&amp;gt; dynamic, so calling b with the wrapper function can be compiled.&lt;/p&gt;
&lt;p&gt;Similarly, Church numeral a subtracting b can be defined as decrease a for b times, a multiplying b can be defined as adding a for b times to 0, and raising a to the power b can be defined as multiplying a for n times with 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Subtract := λa.λb.b Decrease a
Multiply := λa.λb.b (Add a) 0
Power := λa.λb.b (Multiply a) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# implementation are in the same pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Subtract = a =&amp;gt; b =&amp;gt; b(Decrease)(a)
// η conversion:
// Subtract = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Decrease(n))(a)
public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    Subtract = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Decrease(n))(a);

// Multiply = a =&amp;gt; b =&amp;gt; b(Add(a))(a)
// η conversion:
// Multiply = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Add(a)(n))(Zero)
public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    Multiply = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Add(a)(n))(Zero);

// Pow = a =&amp;gt; b =&amp;gt; b(Multiply(a))(a)
// η conversion:
// Pow = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Multiply(a)(n))(1)
public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
    Pow = a =&amp;gt; b =&amp;gt; b(n =&amp;gt; Multiply(a)(n))(One);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to Church Boolean operators, the above arithmetic operators can also be wrapped as extension method for convenience:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NumeralExtensions
{
    public static Numeral Increase(this Numeral n) =&amp;gt; ChurchNumeral.Increase(n);

    public static Numeral Decrease(this Numeral n) =&amp;gt; ChurchNumeral.Decrease(n);

    public static Numeral Add(this Numeral a, Numeral b) =&amp;gt; ChurchNumeral.Add(a)(b);

    public static Numeral Subtract(this Numeral a, Numeral b) =&amp;gt; ChurchNumeral.Subtract(a)(b);

    public static Numeral Multiply(this Numeral a, Numeral b) =&amp;gt; ChurchNumeral.Multiply(a)(b);

    public static Numeral Pow(this Numeral mantissa, Numeral exponent) =&amp;gt; ChurchNumeral.Pow(mantissa)(exponent);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Predicate and relational operators&lt;/h2&gt;
&lt;p&gt;Predicate is function returning Church Boolean. For example, the following function predicate whether a Church numeral n is 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsZero := λn.n (λx.False) True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When n is 0, (λx.False) is not applied, and IsZero directly returns True. When n is positive, (λx.False) is applied for n times. (λx.False) always return False, so IsZero returns False. The following are the implementation and extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchPredicate
{
    public static readonly Func&amp;lt;Numeral, Boolean&amp;gt; 
        IsZero = n =&amp;gt; n(_ =&amp;gt; False)(True);
}

public static partial class NumeralExtensions
{
    public static Boolean IsZero(this Numeral n) =&amp;gt; ChurchPredicate.IsZero(n);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With IsZero, it is easy to define functions to compare 2 Church numerals a and b. According the to definition of Decrease and Subtract, when a – b is 0, a is either equal to b, or less than b. So IsLessThanOrEqualTo can be defined with IsZero and Subtract:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsLessThanOrEqualTo := λa.λb.IsZero (Subtract a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IsGreaterThanOrEqualTo is similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsGreaterThanOrEqualTo := λa.λb.IsZero (Subtract b a)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then these 2 functions can define IsEqualTo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsEqualTo := λa.λb.And (IsLessThanOrEqualTo a b) (IsGreaterThanOrEqualTo a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The opposite of these functions are IsGreaterThan, IsLessThan, IsNotEqual. They can be defined with Not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsGreaterThan := λa.λb.Not (IsLessThanOrEqualTo a b)
IsLessThan := λa.λb.Not (IsGreaterThanOrEqualTo a b)
IsNotEqualTo := λa.λb.Not (IsEqualTo a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following are the C# implementation of these 6 predicates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchPredicate
{
    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt; 
        IsLessThanOrEqualTo = a =&amp;gt; b =&amp;gt; a.Subtract(b).IsZero();

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt; 
        IsGreaterThanOrEqualTo = a =&amp;gt; b =&amp;gt; b.Subtract(a).IsZero();

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt;
        IsEqualTo = a =&amp;gt; b =&amp;gt; IsLessThanOrEqualTo(a)(b).And(IsGreaterThanOrEqualTo(a)(b));

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt;
        IsGreaterThan = a =&amp;gt; b =&amp;gt; IsLessThanOrEqualTo(a)(b).Not();

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt; 
        IsLessThan = a =&amp;gt; b =&amp;gt; IsGreaterThanOrEqualTo(a)(b).Not();

    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Boolean&amp;gt;&amp;gt;
        IsNotEqualTo = a =&amp;gt; b =&amp;gt; IsEqualTo(a)(b).Not();
}

public static partial class NumeralExtensions
{
    public static Boolean IsLessThanOrEqualTo(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsLessThanOrEqualTo(a)(b);

    public static Boolean IsGreaterThanOrEqualTo(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsGreaterThanOrEqualTo(a)(b);

    public static Boolean IsEqualTo(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsEqualTo(a)(b);

    public static Boolean IsGreaterThan(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsGreaterThan(a)(b);

    public static Boolean IsLessThan(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsLessThan(a)(b);

    public static Boolean IsNotEqualTo(this Numeral a, Numeral b) =&amp;gt; ChurchPredicate.IsNotEqualTo(a)(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Attempt of recursion&lt;/h3&gt;
&lt;p&gt;The division of natural numbers can be defined with arithmetic and relation operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a / b := if a &amp;gt;= b then 1 + (a – b) / b else 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a recursive definition. If defining division in this way lambda calculus, the function name is referred in its own body:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideBy := λa.λb.If (IsGreaterThanOrEqualTo a b) (λx.Add One (DivideBy (Subtract a b) b)) (λx.Zero)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, in lambda calculus, functions are anonymously by default, and names are just for readability. Here the self reference does not work with anonymous function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λa.λb.If (IsGreaterThanOrEqualTo a b) (λx.Add One (? (Subtract a b) b)) (λx.Zero)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the above DivideBy function definition is illegal in lambda calculus. The recursion implementation with anonymous function will be discussed later in this chapter.&lt;/p&gt;
&lt;p&gt;In C#, recursion is a basic feature, so the following self reference is supported:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;

public static partial class ChurchNumeral
{
    // Divide = dividend =&amp;gt; divisor =&amp;gt; 
    //    If(dividend &amp;gt;= divisor)
    //        (_ =&amp;gt; 1 + DivideBy(dividend - divisor)(divisor))
    //        (_ =&amp;gt; 0);
    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt;
        DivideBy = dividend =&amp;gt; divisor =&amp;gt;
            If(dividend.IsGreaterThanOrEqualTo(divisor))
                (_ =&amp;gt; One.Add(DivideBy(dividend.Subtract(divisor))(divisor)))
                (_ =&amp;gt; Zero);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here using static directive is used so that ChurchBoolean.If function can be called directly. DivideBy is compiled to a field definition and field initialization code in static constructor, and apparently referencing to a field in the constructor is allowed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static ChurchBoolean;
using static ChurchNumeral;

public static partial class CompiledChurchNumeral
{
    public static readonly Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; DivideBySelfReference;

    static CompiledChurchNumeral()
    {
        DivideBySelfReference = dividend =&amp;gt; divisor =&amp;gt;
            If(dividend.IsGreaterThanOrEqualTo(divisor))
                (_ =&amp;gt; One.Add(DivideBySelfReference(dividend.Subtract(divisor))(divisor)))
                (_ =&amp;gt; Zero);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The self reference also works for named function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchNumeral
{
    public static Func&amp;lt;Numeral, Numeral&amp;gt; DivideByMethod(Numeral dividend) =&amp;gt; divisor =&amp;gt;
        If(dividend.IsGreaterThanOrEqualTo(divisor))
            (_ =&amp;gt; One.Add(DivideByMethod(dividend.Subtract(divisor))(divisor)))
            (_ =&amp;gt; Zero);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only exception is, when this function is a local variable instead of field, then the inline self reference cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Inline()
{
    Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; divideBy = dividend =&amp;gt; divisor =&amp;gt;
        If(dividend.IsGreaterThanOrEqualTo(divisor))
            (_ =&amp;gt; One.Add(divideBy(dividend.Subtract(divisor))(divisor)))
            (_ =&amp;gt; Zero);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason is, the value of the local variable is compiled before the local variable is compiled. when the anonymous function is compiled, the referenced divideBy function is not defined yet, and C# compiler gives CS0165 error: Use of unassigned local variable &apos;divideBy&apos;. To resolve this problem, divideBy can be first initialized with default value null. When divideBy is initialized again with the anonymous function, it is already defined, so the lambda expression can be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Inline()

{
    Func&amp;lt;Numeral, Func&amp;lt;Numeral, Numeral&amp;gt;&amp;gt; divideBy = null;
    divideBy = dividend =&amp;gt; divisor =&amp;gt;
        If(dividend.IsGreaterThanOrEqualTo(divisor))
            (_ =&amp;gt; One.Add(divideBy(dividend.Subtract(divisor))(divisor)))
            (_ =&amp;gt; Zero);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above division operator DivideBy will be used temporarily. Later after introducing fixed point combinator, the division can be implemented with an anonymous function without self reference at all.&lt;/p&gt;
&lt;h2&gt;Conversion between Church numeral and System.UInt32&lt;/h2&gt;
&lt;p&gt;In .NET, natural number can be represented with unit (System.UInt32). It would be intuitive if Church numeral and uint can be converted to each other. Similar to the conversion between Church Boolean and bool, the following extension methods can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchEncoding
{
    public static Numeral Church(this uint n) =&amp;gt; n == 0U ? ChurchNumeral.Zero : Church(n - 1U).Increase();

    public static uint Unchurch(this Numeral n) =&amp;gt; (uint)n(x =&amp;gt; (uint)x + 1U)(0U);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Converting uint to Church numeral is recursive. When n is 0, Zero is returned directly. When n is positive, n is decreased and converted recursively. The recursion terminates when n is decreased to 0, then Increase is called for n times with Zero, and Church numeral n is calculated. And converting Church numeral n to uint just need to add 1U for n times to 0U.&lt;/p&gt;
&lt;p&gt;The following code demonstrate how the operators and conversions work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public partial class ChurchNumeralTests
{
    [TestMethod]
    public void IncreaseTest()
    {
        Numeral numeral = 0U.Church();
        Assert.AreEqual(0U + 1U, (numeral = numeral.Increase()).Unchurch());
        Assert.AreEqual(1U + 1U, (numeral = numeral.Increase()).Unchurch());
        Assert.AreEqual(2U + 1U, (numeral = numeral.Increase()).Unchurch());
        Assert.AreEqual(3U + 1U, (numeral = numeral.Increase()).Unchurch());
        numeral = 123U.Church();
        Assert.AreEqual(123U + 1U, numeral.Increase().Unchurch());
    }

    [TestMethod]
    public void AddTest()
    {
        Assert.AreEqual(0U + 0U, 0U.Church().Add(0U.Church()).Unchurch());
        Assert.AreEqual(0U + 1U, 0U.Church().Add(1U.Church()).Unchurch());
        Assert.AreEqual(10U + 0U, 10U.Church().Add(0U.Church()).Unchurch());
        Assert.AreEqual(0U + 10U, 0U.Church().Add(10U.Church()).Unchurch());
        Assert.AreEqual(1U + 1U, 1U.Church().Add(1U.Church()).Unchurch());
        Assert.AreEqual(10U + 1U, 10U.Church().Add(1U.Church()).Unchurch());
        Assert.AreEqual(1U + 10U, 1U.Church().Add(10U.Church()).Unchurch());
        Assert.AreEqual(3U + 5U, 3U.Church().Add(5U.Church()).Unchurch());
        Assert.AreEqual(123U + 345U, 123U.Church().Add(345U.Church()).Unchurch());
    }

    [TestMethod]
    public void DecreaseTest()
    {
        Numeral numeral = 3U.Church();
        Assert.AreEqual(3U - 1U, (numeral = numeral.Decrease()).Unchurch());
        Assert.AreEqual(2U - 1U, (numeral = numeral.Decrease()).Unchurch());
        Assert.AreEqual(1U - 1U, (numeral = numeral.Decrease()).Unchurch());
        Assert.AreEqual(0U, (numeral = numeral.Decrease()).Unchurch());
        numeral = 123U.Church();
        Assert.AreEqual(123U - 1U, numeral.Decrease().Unchurch());
    }

    [TestMethod]
    public void SubtractTest()
    {
        Assert.AreEqual(0U - 0U, 0U.Church().Subtract(0U.Church()).Unchurch());
        Assert.AreEqual(0U, 0U.Church().Subtract(1U.Church()).Unchurch());
        Assert.AreEqual(10U - 0U, 10U.Church().Subtract(0U.Church()).Unchurch());
        Assert.AreEqual(0U, 0U.Church().Subtract(10U.Church()).Unchurch());
        Assert.AreEqual(1U - 1U, 1U.Church().Subtract(1U.Church()).Unchurch());
        Assert.AreEqual(10U - 1U, 10U.Church().Subtract(1U.Church()).Unchurch());
        Assert.AreEqual(0U, 1U.Church().Subtract(10U.Church()).Unchurch());
        Assert.AreEqual(0U, 3U.Church().Subtract(5U.Church()).Unchurch());
        Assert.AreEqual(0U, 123U.Church().Subtract(345U.Church()).Unchurch());
    }

    [TestMethod]
    public void MultiplyTest()
    {
        Assert.AreEqual(0U*0U, 0U.Church().Multiply(0U.Church()).Unchurch());
        Assert.AreEqual(0U*1U, 0U.Church().Multiply(1U.Church()).Unchurch());
        Assert.AreEqual(10U*0U, 10U.Church().Multiply(0U.Church()).Unchurch());
        Assert.AreEqual(0U*10U, 0U.Church().Multiply(10U.Church()).Unchurch());
        Assert.AreEqual(1U*1U, 1U.Church().Multiply(1U.Church()).Unchurch());
        Assert.AreEqual(10U*1U, 10U.Church().Multiply(1U.Church()).Unchurch());
        Assert.AreEqual(1U*10U, 1U.Church().Multiply(10U.Church()).Unchurch());
        Assert.AreEqual(3U*5U, 3U.Church().Multiply(5U.Church()).Unchurch());
        Assert.AreEqual(12U*23U, 12U.Church().Multiply(23U.Church()).Unchurch());
    }

    [TestMethod]
    public void PowTest()
    {
        Assert.AreEqual(Math.Pow(0U, 1U), 0U.Church().Pow(1U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(10U, 0U), 10U.Church().Pow(0U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(0U, 10U), 0U.Church().Pow(10U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(1U, 1U), 1U.Church().Pow(1U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(10U, 1U), 10U.Church().Pow(1U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(1U, 10U), 1U.Church().Pow(10U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(3U, 5U), 3U.Church().Pow(5U.Church()).Unchurch());
        Assert.AreEqual(Math.Pow(5U, 3U), 5U.Church().Pow(3U.Church()).Unchurch());
    }

    [TestMethod]
    public void DivideByRecursionTest()
    {
        Assert.AreEqual(1U / 1U, 1U.Church().DivideBy(1U.Church()).Unchurch());
        Assert.AreEqual(1U / 2U, 1U.Church().DivideBy(2U.Church()).Unchurch());
        Assert.AreEqual(2U / 2U, 2U.Church().DivideBy(2U.Church()).Unchurch());
        Assert.AreEqual(2U / 1U, 2U.Church().DivideBy(1U.Church()).Unchurch());
        Assert.AreEqual(10U / 3U, 10U.Church().DivideBy(3U.Church()).Unchurch());
        Assert.AreEqual(3U / 10U, 3U.Church().DivideBy(10U.Church()).Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (2) Church Encoding: Boolean and Logic</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-2-boolean-and-logic/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-2-boolean-and-logic/</guid><description>Lambda calculus is a formal system for function definition and function application, so in lambda calculus, the only primitive is anonymous function. Anonymous function is actually very powerful. With</description><pubDate>Mon, 04 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Lambda calculus is a formal system for function definition and function application, so in lambda calculus, the only primitive is anonymous function. Anonymous function is actually very powerful. With an approach called Church encoding. data and operation can be modeled by higher-order anonymous functions and their application. Church encoding is named after &lt;a href=&quot;http://en.wikipedia.org/wiki/Alonzo_Church&quot;&gt;Alonzo Church&lt;/a&gt;, who first discovered this approach. This part discusses Church Boolean - modeling Boolean values and logic operators with functions.&lt;/p&gt;
&lt;h2&gt;Church Boolean&lt;/h2&gt;
&lt;p&gt;Boolean values True and False can be both represented by anonymous function with 2 parameters. True function simply output the first parameter, and False function output the second parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λtf.t
False := λtf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, λtf.E is just the abbreviation of λt.λf.E, so these definitions actually are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λt.λf.t
False := λt.λf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this tutorial, for consistency and intuition, function definition with multiple variables is always represented in the latter curried form. In C#, they can be viewed as t =&amp;gt; f =&amp;gt; t and t =&amp;gt; f =&amp;gt; f, which are curried from (t, f) =&amp;gt; t and (t, f) =&amp;gt; f. Here t and f can be of any type, so leave their types as dynamic for convenience. In C#, at compile time dynamic is viewed as object and also supports any operation; at runtime if the operation is actually not supported, an exception is thrown. So, the function type of t =&amp;gt; f =&amp;gt; t and t =&amp;gt; f =&amp;gt; f is dynamic –&amp;gt; dynamic –&amp;gt; dynamic, which is represented as Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt; in C#. For convenience, an alias Boolean can be defined for such function type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from (dynamic, dynamic) -&amp;gt; dynamic.
// Boolean is the alias of dynamic -&amp;gt; dynamic -&amp;gt; dynamic.
public delegate Func&amp;lt;dynamic, dynamic&amp;gt; Boolean(dynamic @true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that True and False can be defined with lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    public static readonly Boolean
        True = @true =&amp;gt; @false =&amp;gt; @true;

    public static readonly Boolean
        False = @true =&amp;gt; @false =&amp;gt; @false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# does not support defining function directly in the global scope, so True and False are defined as static filed member of a type. In other functional languages like F#, functions can directly defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let True t f = t
let False t f = f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no noise and the function currying is default. Actually this F# code is compiled to CIL code similar to above C# structure (static member of a type).&lt;/p&gt;
&lt;h2&gt;Logical operators&lt;/h2&gt;
&lt;p&gt;After defining Boolean values True and False with functions, now the Boolean logics can be represented by functions too. And can be defined by the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;And := λa.λb.a b False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying function True with Boolean a and b:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a is True, the application is beta reduced to True b False, which applies True function with b and False, and the first argument b is returned. In C#, this can be viewed that true &amp;amp;&amp;amp; b is the same as b.&lt;/li&gt;
&lt;li&gt;When a is False, the application is beta reduced to False b False, which applies False function with b and False, and the second argument False is returned. In C#, this can be viewed as false &amp;amp;&amp;amp; b is always false.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;And True b
≡ (λa.λb.a b False) True b
≡ (λb.True b False) b
≡ True b False
≡ b

  And False b
≡ (λa.λb.a b False) False b
≡ (λb.False b False) b
≡ False b False
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, And can be viewed as a =&amp;gt; b =&amp;gt; a(b)(False), it is of curried function type Boolean –&amp;gt; Boolean -&amp;gt; Boolean:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    public static readonly Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;
        And = a =&amp;gt; b =&amp;gt; a(b)(False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This demonstrates that the Boolean alias improves the readability. Without this alias, the type of And becomes (dynamic –&amp;gt; dynamic –&amp;gt; dynamic) –&amp;gt; (dynamic –&amp;gt; dynamic –&amp;gt; dynamic) –&amp;gt; (dynamic –&amp;gt; dynamic –&amp;gt; dynamic), which is Func&amp;lt;Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;, Func&amp;lt;Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;&amp;gt; in C#.&lt;/p&gt;
&lt;p&gt;This also demonstrates that dynamic type simplifies type conversion. If Boolean is defined as object –&amp;gt; object -&amp;gt; object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate Func&amp;lt;object, object&amp;gt; Boolean(object @true);

public static partial class ChurchBoolean
{
    public static readonly Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;
        And = a =&amp;gt; b =&amp;gt; (Boolean)a(b)(False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And must return Boolean, but a(b)(False) returns object, so a type conversion is required. Here a is either True or False, according to the definition of True and False, a(b)(False) returns either b or False. Since b and False are both of type Boolean, so here it is safe to convert a(b)(False) to Boolean. In contrast, when Boolean is defined as dynamic –&amp;gt; dynamic -&amp;gt; dynamic, a(b)(False) returns dynamic, which is viewed as supporting any operation at compile time, including implicitly conversion to Boolean, so the explicit type conversion is not required. At run time, a(b)(False) always return Boolean, and converting Boolean to Boolean always succeeds, so And works smoothly without any exception.&lt;/p&gt;
&lt;p&gt;In the above lambda function and C# function, a function name False is referenced. Again, function is anonymous by default in lambda calculus. This tutorial uses function name only for for readability. By substituting function name, And can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;And := λa.λb.a b (λt.λf.f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the C# implementation becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;
    And = a =&amp;gt; b =&amp;gt; a(b)(new Boolean(@true =&amp;gt; @false =&amp;gt; @false));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function body is longer and less readable. Also, a is of type dynamic –&amp;gt; dynamic -&amp;gt; dynamic, the second argument of a is expected to be object. When function reference False is given, False is a Boolean delegate instance, apparently it is an object and works there, However, when an inline C# lambda expression is given. C# compiler cannot infer the the type of this lambda expression – it could be anonymous function, or expression tree, and the type information of @true and @false cannot be inferred either. So here the constructor syntax is used to indicate this inline lambda expression is a function of type dynamic –&amp;gt; dynamic -&amp;gt; dynamic.&lt;/p&gt;
&lt;p&gt;Again, C# does not support defining custom operators for functions, so a &amp;amp;&amp;amp; operator cannot be defined for Boolean type. However, extension method can be defined for Boolean type, also And can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class BooleanExtensions
{
    public static Boolean And(this Boolean a, Boolean b) =&amp;gt; ChurchBoolean.And(a)(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now And can be used fluently like an infix operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallAnd()
{
    Boolean result1 = True.And(True);

    Boolean x = True;
    Boolean y = False;
    Boolean result2 = x.And(y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, the function name And is only for readability, without refereeing to the function name., the function application (And x y) has to be written as (λa.λb.a b (λt.λf.f)) x y, and in C#, calling And anonymously works but is also less readable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallAnonymousAnd()
{
    Boolean result1 = new Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;(a =&amp;gt; b =&amp;gt; (Boolean)a(b)(False))(True)(True);

    Boolean x = True;
    Boolean y = False;
    Boolean result2 = new Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;(a =&amp;gt; b =&amp;gt; (Boolean)a(b)(False))(x)(y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Or :=  λa.λb.a True b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a is True, True True b returns the first argument True; When a is False, False True b returns the second argument b. In C#, this can be viewed as true || b is always true, and false || b is the same as b.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Or True b
≡ (λa.λb.a True b) True b
≡ (λb.True True b) b
≡ True True b
≡ True
 
  Or False b
≡ (λa.λb.a True b) False b
≡ (λb.False True b) b
≡ False True b
≡ b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Not := λa.a False True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a is True, True False True returns the first argument False; when a is False, False False True returns the second argument True:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Not True
≡ (λa.a False True) True
≡ True False True
≡ False
 
  Not False
≡ (λa.a False True) False
≡ False False True
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Xor is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Xor := λa.λb.a (Not b) b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a is True, True (Not b) b returns the first argument Not b; when a is False, True (Not b) b returns the second argument b:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Xor True b
≡ (λa.λb.a (Not b) b) True b
≡ (λb.True (Not b) b) b
≡ True (Not b) b
≡ Not b
 
  Xor False b
≡ (λa.λb.a (Not b) b) True b
≡ (λb.False (Not b) b) b
≡ False (Not b) b
≡ b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 3 operators can be simply implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt; 
    Or = a =&amp;gt; b =&amp;gt; a(True)(b);

public static Func&amp;lt;Boolean, Boolean&amp;gt; 
    Not = boolean =&amp;gt; boolean(False)(True);

public static Func&amp;lt;Boolean, Func&amp;lt;Boolean, Boolean&amp;gt;&amp;gt;
    Xor = a =&amp;gt; b =&amp;gt; a(Not(b))(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, they can be wrapped as extension methods too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Boolean Or(this Boolean a, Boolean b) =&amp;gt; ChurchBoolean.Or(a)(b);

public static Boolean Not(this Boolean a) =&amp;gt; ChurchBoolean.Not(a);

public static Boolean Xor(this Boolean a, Boolean b) =&amp;gt; ChurchBoolean.Xor(a)(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conversion between Church Boolean and System.Boolean&lt;/h2&gt;
&lt;p&gt;It could be intuitive if the Church Boolean function can be directly compared with .NET bool value. The following methods can be defined to convert between them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchEncoding
{
    // System.Boolean structure to Boolean function.
    public static Boolean Church(this bool boolean) =&amp;gt; boolean ? True : False;

    // Boolean function to System.Boolean structure.
    public static bool Unchurch(this Boolean boolean) =&amp;gt; boolean(true)(false);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the help of conversion, the following code demonstrate how to use the logical operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public partial class ChurchBooleanTests
{
    [TestMethod]
    public void NotTest()
    {
        Assert.AreEqual((!true).Church(), True.Not());
        Assert.AreEqual((!false).Church(), False.Not());
    }

    [TestMethod]
    public void AndTest()
    {
        Assert.AreEqual((true &amp;amp;&amp;amp; true).Church(), True.And(True));
        Assert.AreEqual((true &amp;amp;&amp;amp; false).Church(), True.And(False));
        Assert.AreEqual((false &amp;amp;&amp;amp; true).Church(), False.And(True));
        Assert.AreEqual((false &amp;amp;&amp;amp; false).Church(), False.And(False));
    }

    [TestMethod]
    public void OrTest()
    {
        Assert.AreEqual((true || true).Church(), True.Or(True));
        Assert.AreEqual((true || false).Church(), True.Or(False));
        Assert.AreEqual((false || true).Church(), False.Or(True));
        Assert.AreEqual((false || false).Church(), False.Or(False));
    }

    [TestMethod]
    public void XorTest()
    {
        Assert.AreEqual((true ^ true).Church(), True.Xor(True));
        Assert.AreEqual((true ^ false).Church(), True.Xor(False));
        Assert.AreEqual((false ^ true).Church(), False.Xor(True));
        Assert.AreEqual((false ^ false).Church(), False.Xor(False));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;If&lt;/h2&gt;
&lt;p&gt;The if logic is already built in Church Booleans. Church Booleans is a function that can be applied with 2 argument. If this Church Boolean function is True, the first argument is returned, else the second argument is returned. So naturedly, the following is the If function, which is just a wrapper of Church Boolean function application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If := λb.λt.λf.b t f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first argument b is a Church Boolean. when b is True, If returns second argument t. When b is False, If returns third argument f. In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// EagerIf = condition =&amp;gt; then =&amp;gt; @else =&amp;gt; condition(then)(@else)
public static readonly Func&amp;lt;Boolean, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;
    EagerIf = condition =&amp;gt; then =&amp;gt; @else =&amp;gt;
        condition    // if (condition)
            (then)   // then { ... }
            (@else); // else { ... }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is one issue with this C# implementation. As fore mentioned, C#’s reduction strategy is applicative order, when C# function is called, arguments are evaluated, then function is called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallEagerIf(Boolean condition, Boolean a, Boolean b)
{
    Boolean result = EagerIf(condition)
        (a.And(b)) // then branch.
        (a.Or(b)); // else branch.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, disregarding condition is True or False, the then branch a.And(b) and else branch a.Or(b) are both executed. If would be better if one branch is executed for a certain condition. The solution is to make If’s second and third arguments of type T to a factory of type Unit&amp;lt;T&amp;gt; –&amp;gt; T:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// If = condition =&amp;gt; thenFactory =&amp;gt; elseFactory =&amp;gt; condition(thenFactory, elseFactory)(Id)
public static readonly Func&amp;lt;Boolean, Func&amp;lt;Func&amp;lt;Unit&amp;lt;dynamic&amp;gt;, dynamic&amp;gt;, Func&amp;lt;Func&amp;lt;Unit&amp;lt;dynamic&amp;gt;, dynamic&amp;gt;, dynamic&amp;gt;&amp;gt;&amp;gt;
    If = condition =&amp;gt; thenFactory =&amp;gt; elseFactory =&amp;gt;
        condition
            (thenFactory)
            (elseFactory)(Functions&amp;lt;dynamic&amp;gt;.Id);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In lambda calculus this is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If := λb.λt.λf.b t f Id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now calling If becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallLazyIf(Boolean condition, Boolean a, Boolean b)
{
    Boolean result = If(condition)
        (id =&amp;gt; a.And(b)) // then.
        (id =&amp;gt; a.Or(b)); // else.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When condition is True, only a.And(b) is executed. When condition is False, only a.Or(b) is executed. Now the then and else branches are represented by factory functions id =&amp;gt; a.And(b) and id =&amp;gt; a.Or(b), where the id argument is the Id function. This argument usually is not used by the function body, it can be named as _ to indicate “don’t care”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallLazyIf(Boolean condition, Boolean a, Boolean b)
{
    Boolean result = If(condition)
        (_ =&amp;gt; a.And(b)) // then.
        (_ =&amp;gt; a.Or(b)); // else.
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (1) Fundamentals</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-1-fundamentals/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-1-fundamentals/</guid><description>Lambda calculus (aka λ-calculus) is a theoretical framework to describe function definition, function application, function recursion, and uses functions and function application to express computatio</description><pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;FP &amp;amp; LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Lambda calculus (aka λ-calculus) is a theoretical framework to describe function definition, function application, function recursion, and uses functions and function application to express computation. It is a mathematics formal system, but can also be viewed as a smallest programming language that can express and evaluate any computable function. As an universal model of computation, lambda calculus is important in programming language theory, and especially it is the foundation of functional programming. The knowledge of lambda calculus greatly helps understanding functional programming, LINQ, C# and other functional languages.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.spreadshirt.com/lambda-calculus-college-t-shirt-C3376A5017163#/detail/5017163T812A231PC121706255PA1663&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-1_CA43/Lambda-Calculus_3.png&quot; alt=&quot;Lambda-Calculus&quot; title=&quot;Lambda-Calculus&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Expression&lt;/h2&gt;
&lt;p&gt;The core concept of lambda calculus is expression. There are 3 kinds of expressions in lambda calculus: variable, function, application. Expression can be &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursive_definition&quot;&gt;defined recursively&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If v is a variable, then v is expression&lt;/li&gt;
&lt;li&gt;If v is a variable and E is expression, then function λv.E is expression. The function syntax λv.E can be viewed as the the C# anonymous function syntax v =&amp;gt; E, where v is the parameter and E is the function body expression.&lt;/li&gt;
&lt;li&gt;If E1 is expression and E2 is expression, then E1 E2 is expression, which is called application. The application syntax E1 E2 can be viewed as C# function call syntax E1(E2), where E1 is the function definition expression and E2 is the argument expression.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By default, lambda calculus treat function anonymously. There is only variable name in lambda calculus. There is no function name involved in function definition expression. In C# language, lambda expression representing anonymous function is a feature introduced in C# 3.0 with .NET Framework 3.5 years back. Actually the theory of lambda expression and lambda calculus were introduced as early as 1930s by &lt;a href=&quot;http://en.wikipedia.org/wiki/Alonzo_Church&quot;&gt;Alonzo Church&lt;/a&gt;, a mathematician and the doctoral advisor of &lt;a href=&quot;http://en.wikipedia.org/wiki/Alan_Turing&quot;&gt;Alan Turing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The following are &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Notation&quot;&gt;conventions&lt;/a&gt; of expression:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Outermost parentheses can be dropped, e.g. E1 E2 means (E1 E2), in C# it can be viewed as (E1(E2)): call function E1 with argument E2&lt;/li&gt;
&lt;li&gt;A sequence of functions is contracted: , e.g. sequence of function λx.(λy.(λz.E)) is contracted as λxyz.E, in another word, expression λxyz.E actually means λx.(λy.(λz.E)), which is identical to λx.λy.λz.E because the parentheses are not required. In C# it can be viewed that (x, y, z) =&amp;gt; E is always curried to x =&amp;gt; (y =&amp;gt; (z =&amp;gt; E)), which is identical to x =&amp;gt; y =&amp;gt; z =&amp;gt; E because =&amp;gt; operator is right associative&lt;/li&gt;
&lt;li&gt;Application is left associative, e.g. E1 E2 E3 means ((E1 E2) E3), in C# it can be viewed as ((E1(E2))(E3)): call function E1 with argument E2, then call the returned function with argument E3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Bound variable vs. free variable&lt;/h3&gt;
&lt;p&gt;In function, its body expression can use variables. There are 2 kinds of variables used in function body expression, &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Free_and_bound_variables&quot;&gt;bound variable and free variable&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When function’s variable (variables before . symbol) occurs in the function body expression, these these variable occurrences (after the . symbol) are bound variables. In C# this can be viewed as declared function parameter’s occurrences in function body.&lt;/li&gt;
&lt;li&gt;All other variables are free variables, in C# it can be viewed as outer variable or closure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, for function λx.f x, its body expression f x has bound variable x, and free variable f. This can be viewed as x =&amp;gt; f(x) in C# syntax, in the body x is parameter and f is closure.&lt;/p&gt;
&lt;p&gt;A variable is bound by its &quot;nearest&quot; function. For example, in λx.g x (λx.h x), the first occurrence of x in the body expression is bound by the outer function, and the second occurrence of x is bound by the inner function. In C#, x =&amp;gt; g(x)(x =&amp;gt; h(x)) cannot be compiled for this reason - the outer function parameter has the same name as the inner function parameter, which is disallowed by C# compiler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class Expression
{
    internal static Func&amp;lt;T, T&amp;gt; Variable&amp;lt;T&amp;gt;(Func&amp;lt;T, Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt; g, Func&amp;lt;T, T&amp;gt; h) =&amp;gt; 
        x =&amp;gt; g(x)(x =&amp;gt; h(x));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expression without free variables are also called combinator, which will be discussed later.&lt;/p&gt;
&lt;h2&gt;Reduction&lt;/h2&gt;
&lt;p&gt;In lambda calculus, there are 3 substitution rules for expression to be &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Reduction&quot;&gt;reduced&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;α-conversion&lt;/h3&gt;
&lt;p&gt;In lambda calculus, lambda expression’s bound variables can be substituted with different name. This is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B1-conversion&quot;&gt;alpha-conversion, or alpha-renaming&lt;/a&gt;. In C#, this can be viewed as function parameter can be renamed, for example, x =&amp;gt; f(x) is equivalent to y =&amp;gt; f(y).&lt;/p&gt;
&lt;p&gt;In the above example of λx.g x (λx.h x), the inner function λx.h x has variable x, which can be substituted with a different name y, along with its appearance in the body h x. Then the inner function becomes λy.h y, so the outer function becomes λx.g x (λy.h y). Now it becomes intuitive how x and y are bound by the “nearest” function. In C#, x =&amp;gt; g(x)(y =&amp;gt; h(y)) can be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;T, T&amp;gt; Variable&amp;lt;T&amp;gt;(Func&amp;lt;T, Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt; g, Func&amp;lt;T, T&amp;gt; h) =&amp;gt; 
    x =&amp;gt; g(x)(y =&amp;gt; h(y));
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;β-reduction&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B2-reduction&quot;&gt;Beta-reduction&lt;/a&gt; of function application expression (λv.E) R is denoted E[v := R]. It means to &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Substitution&quot;&gt;substitute&lt;/a&gt; all free occurrences of the variable v in the expression E with expression R. In C#, this can be viewed as when function is called with argument, in the body all parameter occurrences are substituted by argument. For Example, when function x =&amp;gt; x + 2 is called with 1, in the body x + 2, parameter x is substituted with argument 1, so the function is evaluated to 1 + 2.&lt;/p&gt;
&lt;h3&gt;η-conversion&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-conversion&quot;&gt;Eta-conversion&lt;/a&gt; means 2 functions are the same &lt;a href=&quot;http://en.wikipedia.org/wiki/If_and_only_if&quot;&gt;if and only if&lt;/a&gt; they always give the same result for the same argument. For example λx.f x can be substituted with f, if x does not appear free in f. In C#, this can be viewed as that function x =&amp;gt; f(x) is equivalent to function f. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqQuery()
{
    Func&amp;lt;int, bool&amp;gt; isEven = value =&amp;gt; value % 2 == 0;
    Enumerable.Range(0, 5).Where(value =&amp;gt; isEven(value)).ForEach(value =&amp;gt; Console.WriteLine(value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here function value =&amp;gt; isEven(value) and function isEven always have the same result for the same argument, so value=&amp;gt; isEven(value) can be substituted with isEven. Similarly value =&amp;gt; Console.WriteLine(value) can be substituted by Console.WriteLine. The above LINQ query is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EtaConvertion()
{
    Func&amp;lt;int, bool&amp;gt; isEven = value =&amp;gt; value % 2 == 0;
    Enumerable.Range(0, 5).Where(isEven).ForEach(Console.WriteLine);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/52298759@N04/4889071497&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-1-Fundamental---Cl_1274C/4889071497_7ee9f43a08_b_3.jpg&quot; alt=&quot;4889071497_7ee9f43a08_b&quot; title=&quot;4889071497_7ee9f43a08_b&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Normal order&lt;/h3&gt;
&lt;p&gt;The above reduction rules can be applied to expression with different order. With normal order, the leftmost, outermost expression is reduced first. For function application expression, this means the function is beta reduced first, then the arguments are reduced, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(λx.λy.y) ((λa.λb.a) (λv.v))
≡ λy.λy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this expression, function (λx.λy.y) is applied with argument, expression ((λa.λb.a) (λv.v)). The leftmost, outermost expression is the function expression (λx.λy.y). So in its body λy.y, all free occurrences of x should be substituted by ((λa.λb.a) (λv.v)). And since there is no any occurrences of x, the substitution result is still λy.y. In normal order reduction, the argument expression ((λa.λb.a) (λv.v)) is not reduced at all.&lt;/p&gt;
&lt;p&gt;Here λy.y cannot be further reduced. An expression that cannot be reduced any further with above 3 rules is called in normal form. Here λy.λy is the normal form of (λx.λy.y) ((λa.λb.a) (λv.v)). Some lambda expressions can be reduced infinitely so does not have normal form, which will be discussed later.&lt;/p&gt;
&lt;h3&gt;Applicative order&lt;/h3&gt;
&lt;p&gt;With applicative order, the rightmost, innermost expression is reduced first. For function application expression, this means the arguments are reduced first, then the function is beta reduced. Take the above expression as example again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(λx.λy.y) ((λa.λb.a) (λv.v))
≡ (λx.λy.y) (λb.λv.v)
≡ λy.λy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The argument expression ((λa.λb.a) (λv.v)) is righter than the function definition expression (λx.λy.y), so ((λa.λb.a) (λv.v)) is reduced first. It can be beta reduced to normal form (λb.λv.v), which cannot be further reduced. Then (λx.λy.y) is applied with (λb.λv.v), which can be beta reduced to normal form λy.λy. In application order reduction, argument must be reduced before function application. This is the strategy of C#.&lt;/p&gt;
&lt;p&gt;In lambda calculus, reducing expression in any order produces the same result, which is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Church%E2%80%93Rosser_theorem&quot;&gt;Church–Rosser theorem&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Function composition&lt;/h2&gt;
&lt;p&gt;In lambda calculus &lt;a href=&quot;http://en.wikipedia.org/wiki/Function_composition_(computer_science)&quot;&gt;function composition&lt;/a&gt; means to combine simple functions into a more complicated function, which can be viewed the same as fore mentioned C# function composition. The composition of f1 and f2 is denoted f2 ∘ f1. This new function (f2 ∘ f1)’s application is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f2 ∘ f1) x := f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the function names f1 and f2 indicate the order of being applied. f2 ∘ f1 can also be read as f2 after f1. in C#, this can be viewed as the forward composition discussed before:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static Func&amp;lt;T, TResult2&amp;gt; After&amp;lt;T, TResult1, TResult2&amp;gt;(
        this Func&amp;lt;TResult1, TResult2&amp;gt; function2, Func&amp;lt;T, TResult1&amp;gt; function1) =&amp;gt;
            value =&amp;gt; function2(function1(value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, some other functional languages have built in composition operator for functions, like &amp;gt;&amp;gt; in F#, . in Haskell, etc. C# does not support defining custom operators for functions. As a workaround, an extension method o can be defined to represent this ∘ operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T, TResult2&amp;gt; o&amp;lt;T, TResult1, TResult2&amp;gt;(
    this Func&amp;lt;TResult1, TResult2&amp;gt; function2, Func&amp;lt;T, TResult1&amp;gt; function1) =&amp;gt;
        value =&amp;gt; function2(function1(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that f3 ∘ f2 ∘ f1 becomes f3.o(f2).o(f1) in C#, which is more intuitive, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Compose()
{
    Func&amp;lt;double, double&amp;gt; sqrt = Math.Sqrt;
    Func&amp;lt;double, double&amp;gt; abs = Math.Abs;

    Func&amp;lt;double, double&amp;gt; absSqrt1 = sqrt.o(abs); // Composition: sqrt after abs.
    absSqrt1(-2D).WriteLine(); // 1.4142135623731
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Associativity&lt;/h3&gt;
&lt;p&gt;Function composition is &lt;a href=&quot;http://en.wikipedia.org/wiki/Associative&quot;&gt;associative&lt;/a&gt;. That means (f3 ∘ f2) ∘ f1 and f3 ∘ (f2 ∘ f1) are equivalent.&lt;/p&gt;
&lt;p&gt;When applying x to (f3 ∘ f2) ∘ f1, according to the definition of ∘:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;((f3 ∘ f2) ∘ f1) x
≡ (f3 ∘ f2) (f1 x)
≡ f3 (f2 (f1 x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And when applying x to f3 ∘ (f2 ∘ f1):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f3 ∘ (f2 ∘ f1) x
≡ f3 ∘ (f2 (f1 x))
≡ f3 (f2 (f1 x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, this means f3.o(f2).o(f1) and f3.o(f2.o(f1)) are equivalent:’&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Associativity()
{
    Func&amp;lt;double, double&amp;gt; sqrt = Math.Sqrt;
    Func&amp;lt;double, double&amp;gt; abs = Math.Abs;
    Func&amp;lt;double, double&amp;gt; log = Math.Log;

    Func&amp;lt;double, double&amp;gt; absSqrtLog1 = log.o(sqrt).o(abs); // Composition: (log o sqrt) o abs.
    absSqrtLog1(-2D).WriteLine(); // 0.34642256747438094
    Func&amp;lt;double, double&amp;gt; absSqrtLog2 = log.o(sqrt.o(abs)); // Composition: log o (sqrt o abs).
    absSqrtLog2(-2D).WriteLine(); // 0.34642256747438094
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Unit&lt;/h3&gt;
&lt;p&gt;There is a unit function Id for function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Id := λx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that f ∘ Id and Id ∘ f are both equivalent to f:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f ∘ Id = f
Id ∘ f = f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to the definition of ∘ and Id:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f ∘ Id) x
≡ f (Id x)
≡ f x

  (Id ∘ f) x
≡ Id (f x)
≡ f x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, Id can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Unit&amp;lt;T&amp;gt; is the alias of Func&amp;lt;T, T&amp;gt;.
public delegate T Unit&amp;lt;T&amp;gt;(T value);

public static partial class Functions&amp;lt;T&amp;gt;
{
    public static readonly Unit&amp;lt;T&amp;gt;
        Id = x =&amp;gt; x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here function expression (λx.x) is given a name Id, this is only for readability. Later, when refereeing to this function, its name Id will used, which is more intuitive than the lambda expression.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ via C#</title><link>https://dixin.github.io/posts/linq-via-csharp/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-via-csharp/</guid><description>!</description><pubDate>Wed, 14 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/LINQ-via-C_955C/ezgif-1-93576e9d87_3.jpg&quot; alt=&quot;ezgif-1-93576e9d87&quot; title=&quot;ezgif-1-93576e9d87&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#acclaim&quot;&gt;Acclaim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#contentsataglance&quot;&gt;Contents at a Glance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#contents&quot;&gt;Table of Contents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a book on functional programming and LINQ programming via C# language. It discusses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functional programming via C# in-depth&lt;/li&gt;
&lt;li&gt;Use functional LINQ to work with local data and cloud data&lt;/li&gt;
&lt;li&gt;The underlying mathematics theories of functional programming and LINQ, including Lambda Calculus and Category Theory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Acclaim&lt;/h3&gt;
&lt;p&gt;Microsoft:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“An excellent book for those of us who need to get in-depth understanding on LINQ and functional programming with latest C# language. The author made sure this book includes the latest and cross-platform knowledge for the language, the framework, as well as the underlying mathematical theories.” &lt;strong&gt;Hongfei Guo Partner Group Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This book explains practical and in-depth material clearly, concisely and accurately to the areas of the C# language, functional programming, and LINQ on .NET Framework and .NET Core. This is a great book for anyone wanting to understand the whys and hows behind these important technologies.” &lt;strong&gt;Samer Boshra Principal Software Development Engineer at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book for developers who want to go functional programming. It&apos;s one-stop shopping for serious developers who have to get up to speed with LINQ and functional programming quickly and in-depth. I&apos;ll keep this book on my desk not on my bookshelf.” &lt;strong&gt;Roshan Kommusetty Principal Software Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book for C# developers, it covers both basic C# programming concepts for the beginners new to the .NET world, and C# advanced constructs for experienced .NET programmers. The book is up to date, talks C# 7.0 new language features and demonstrates how you can use them for functional programming. Thanks for the awesome work!” &lt;strong&gt;Mark Zhou Principal Software Engineering Manager at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“I like the way the author presented the detailed knowledge with a lot of examples. As a data scientist with statistics background in a number of industries, I can pick up C# programming and LINQ quickly when I followed the book. The book was concise and easy to read. It was a pleasant experience for me to spend my time emerging myself in the book in the sunshine weekday afternoon.” &lt;strong&gt;Xue Liu Senior Data Scientist at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“Functional Programming and LINQ in C# language, have been fully and clearly unraveled in this book, with many practical examples. The author has not saved any effort to go beyond scratching the surface of C# language and has successfully explained the magic behind the scene. This book is a must-have for anyone who wants to understand functional programming using C#.” &lt;strong&gt;Jie Mei Data &amp;amp; Applied Scientist at Microsoft&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Academy and more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“This book provides comprehensive and in-depth information about the C# functional programming and LINQ technologies to application developers on both .NET Framework and .NET Core. The detailed text and wealth of examples will give a developer a clear and solid understanding of C# language, functional programming and using LINQ to work with different data domains.” &lt;strong&gt;Dong Si Assistant Professor, Department of Computer Science, University of Washington, Bothell&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This book offers a comprehensive, in-depth, yet easy-to-understand tutorial to functional C# programming and LINQ. Filled with detailed explanations and real-world examples, this book is highly valuable for beginners and experienced developers alike.” &lt;strong&gt;Shuang Zhao Assistant Professor, Department of Computer Science, University of California, Irvine&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This excellent book is an in-depth and also readable exploration of C# functional programming and LINQ programming. It covers .NET Framework and .NET Core in great detail.” &lt;strong&gt;Yang Sha Engineering Manager at Google&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“Great book! It takes a hands-on approach to LINQ and functional programming in an easy to understand format. I would highly recommend this book to developers looking to develop expertise in C#, functional programming, and LINQ.” &lt;strong&gt;Himanshu Lal Software Engineering Manager at Facebook&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“This is a great book that combines practical examples with in-depth analysis of LINQ and functional programming in C#. Dixin leverages his expertise in .NET to provide a well written tutorial on the effective use of LINQ and an overview of the theoretical principles behind it. A must read for anyone working on these technologies!” &lt;strong&gt;Dimitrios Soulios Director at Goldman Sachs&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Contents at a Glance&lt;/h3&gt;
&lt;p&gt;The contents are organized as the following chapters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1 Code&lt;/strong&gt; - covers functional programming via C#, and fundamentals of LINQ.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 1 Functional programming and LINQ paradigm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;What is LINQ, how LINQ uses language to work with many different data domains.&lt;/li&gt;
&lt;li&gt;Programming paradigm, imperative vs. declarative programming, object-oriented vs. functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 2 Functional programming in depth&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C# fundamentals for beginners.&lt;/li&gt;
&lt;li&gt;Aspects of functional programming via C#, including function type, named/anonymous/local function, closure, lambda, higher-order function, currying, partial application, first class function, function composition, query expression, covariance/contravariance, immutability, tuple, purity, async function, pattern matching, etc., including how C# is processed at compile time and runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 2 Data&lt;/strong&gt; - covers how to use functional LINQ to work with different data domains in the real world, and how LINQ works internally.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 3 LINQ to Objects&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use functional LINQ queries to work with objects, covering all LINQ and Ix.&lt;/li&gt;
&lt;li&gt;How the LINQ to Objects query methods are implemented, how to implement useful custom LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 4 LINQ to XML&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to modeling XML data, and use functional LINQ queries to work with XML data.&lt;/li&gt;
&lt;li&gt;How to use the other LINQ to XML APIs to manipulate XML data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 5 Parallel LINQ&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use parallelized functional LINQ queries to work with objects.&lt;/li&gt;
&lt;li&gt;Performance analysis for parallel/sequential LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 6 Entity Framework/Core and LINQ to Entities&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to model database with object-relational mapping, and use functional LINQ queries to work with relational data in database.&lt;/li&gt;
&lt;li&gt;How the C# LINQ to Entities queries are implemented to work with database.&lt;/li&gt;
&lt;li&gt;How to change data in database, and handle concurrent conflicts.&lt;/li&gt;
&lt;li&gt;Performance tips and asynchrony.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 3 Theories&lt;/strong&gt; - demystifies the abstract mathematics theories, which are the rationale and foundations of LINQ and functional programming.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 7 Lambda Calculus via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of lambda calculus, bound and free variables, reduction (α-conversion, β-reduction, η-conversion), etc.&lt;/li&gt;
&lt;li&gt;How to use lambda functions to represent values, data structures and computation, including Church Boolean, Church numbers, Church pair, Church list, and their operations.&lt;/li&gt;
&lt;li&gt;Combinators and combinatory logic, including SKI combinator calculus, fixed point combinator for function recursion, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 8 Category Theory via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of category theory, including category, object, morphism, monoid, functor, natural transformation, applicative functor, monad, and their laws.&lt;/li&gt;
&lt;li&gt;How these concepts are applied in functional programming and LINQ.&lt;/li&gt;
&lt;li&gt;How to manage I/O, state, exception handling, shared environment, logging, and continuation, etc., in functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial delivers highly reusable knowledge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It covers C# language in depth, which can be generally applied in any programming paradigms besides functional programming.&lt;/li&gt;
&lt;li&gt;It is a cross platform tutorial, covering both .NET Framework for Windows and .NET Core for Windows, Mac, Linux.&lt;/li&gt;
&lt;li&gt;It demonstrates both usage and implementation of LINQ for mainstream data domains, which also enables developer to use the LINQ technologies for other data domains, or build custom LINQ APIs for specific data scenarios.&lt;/li&gt;
&lt;li&gt;It also demystifies the abstract mathematics knowledge for functional programming, which applies to general functional programming, so it greatly helps developers understanding any other functional languages too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a fun of functional programming, LINQ, C#, and .NET technologies, hope this helps.&lt;/p&gt;
&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;p&gt;All code examples are available on GitHub: https://github.com/Dixin/CodeSnippets.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Introducing%20LINQ&quot;&gt;Functional programming and LINQ paradigm&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-via-csharp-introduction&quot;&gt;Cross platform C# and .NET&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Introducing cross platform .NET, C# and LINQ
&lt;ul&gt;
&lt;li&gt;.NET Framework, C#, and LINQ&lt;/li&gt;
&lt;li&gt;.NET Core, UWP, Mono, Xamarin and Unity&lt;/li&gt;
&lt;li&gt;.NET Standard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Introducing this book
&lt;ul&gt;
&lt;li&gt;Book structure&lt;/li&gt;
&lt;li&gt;Code examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Start coding
&lt;ul&gt;
&lt;li&gt;Start coding with Visual Studio (Windows)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio Code (Windows, macOS and Linux)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio for Mac (macOS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-3-waht-is-functional-programming&quot;&gt;Programming paradigms and functional programming&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Programming paradigms&lt;/li&gt;
&lt;li&gt;Imperative programming vs. declarative programming&lt;/li&gt;
&lt;li&gt;Object-oriented programming vs. functional programming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-2-what-is-linq&quot;&gt;LINQ to data sources&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One language for different data domains
&lt;ul&gt;
&lt;li&gt;LINQ to Objects&lt;/li&gt;
&lt;li&gt;Parallel LINQ&lt;/li&gt;
&lt;li&gt;LINQ to XML&lt;/li&gt;
&lt;li&gt;LINQ to DataSets&lt;/li&gt;
&lt;li&gt;LINQ to Entities&lt;/li&gt;
&lt;li&gt;LINQ to SQL&lt;/li&gt;
&lt;li&gt;LINQ to NoSQL (LINQ to CosmosDB)&lt;/li&gt;
&lt;li&gt;LINQ to JSON&lt;/li&gt;
&lt;li&gt;LINQ to Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequential query vs. parallel query&lt;/li&gt;
&lt;li&gt;Local query vs. remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;Functional programming in depth&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;C# language basics&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Types and members
&lt;ul&gt;
&lt;li&gt;Types and members&lt;/li&gt;
&lt;li&gt;Built-in types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reference type vs. value type
&lt;ul&gt;
&lt;li&gt;ref local variable and immutable ref local variable&lt;/li&gt;
&lt;li&gt;Array and stack-allocated array&lt;/li&gt;
&lt;li&gt;Default value&lt;/li&gt;
&lt;li&gt;ref structure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static class&lt;/li&gt;
&lt;li&gt;Partial type&lt;/li&gt;
&lt;li&gt;Interface and implementation
&lt;ul&gt;
&lt;li&gt;IDisposable interface and using declaration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generic type
&lt;ul&gt;
&lt;li&gt;Type parameter&lt;/li&gt;
&lt;li&gt;Type parameter constraints&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nullable value type&lt;/li&gt;
&lt;li&gt;Auto property&lt;/li&gt;
&lt;li&gt;Property initializer&lt;/li&gt;
&lt;li&gt;Object initializer&lt;/li&gt;
&lt;li&gt;Collection initializer&lt;/li&gt;
&lt;li&gt;Index initializer&lt;/li&gt;
&lt;li&gt;Null coalescing operator&lt;/li&gt;
&lt;li&gt;Null conditional operator&lt;/li&gt;
&lt;li&gt;throw expression&lt;/li&gt;
&lt;li&gt;Exception filter&lt;/li&gt;
&lt;li&gt;String interpolation&lt;/li&gt;
&lt;li&gt;nameof operator&lt;/li&gt;
&lt;li&gt;Digit separator and leading underscore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-type-and-delegate&quot;&gt;Named function and function polymorphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Constructor, static constructor and finalizer&lt;/li&gt;
&lt;li&gt;Static method and instance method&lt;/li&gt;
&lt;li&gt;Extension method&lt;/li&gt;
&lt;li&gt;More named functions&lt;/li&gt;
&lt;li&gt;Function polymorphisms
&lt;ul&gt;
&lt;li&gt;Ad hoc polymorphism: method overload&lt;/li&gt;
&lt;li&gt;Parametric polymorphism: generic method
&lt;ul&gt;
&lt;li&gt;Type argument inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static import&lt;/li&gt;
&lt;li&gt;Partial method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;Local function and closure&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Local function&lt;/li&gt;
&lt;li&gt;Closure
&lt;ul&gt;
&lt;li&gt;Outer variable&lt;/li&gt;
&lt;li&gt;Implicit reference&lt;/li&gt;
&lt;li&gt;Static local function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-parameter-and-return-value&quot;&gt;Function input and output&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Input by copy vs. input by alias (ref parameter)
&lt;ul&gt;
&lt;li&gt;Input by immutable alias (in parameter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Output parameter (out parameter) and out variable
&lt;ul&gt;
&lt;li&gt;Discarding out variable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Parameter array&lt;/li&gt;
&lt;li&gt;Positional argument vs. named argument&lt;/li&gt;
&lt;li&gt;Required parameter vs. optional parameter&lt;/li&gt;
&lt;li&gt;Caller information parameter&lt;/li&gt;
&lt;li&gt;Output by copy vs. output by alias
&lt;ul&gt;
&lt;li&gt;Output by immutable alias&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;Delegate: Function type, instance, and group&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Delegate type as function type
&lt;ul&gt;
&lt;li&gt;Function type&lt;/li&gt;
&lt;li&gt;Generic delegate type&lt;/li&gt;
&lt;li&gt;Unified built-in delegate types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delegate instance as function instance&lt;/li&gt;
&lt;li&gt;Delegate instance as function group
&lt;ul&gt;
&lt;li&gt;Event and event handler&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-anonymous-function-and-lambda-expression&quot;&gt;Anonymous function and lambda expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Anonymous method&lt;/li&gt;
&lt;li&gt;Lambda expression as anonymous function
&lt;ul&gt;
&lt;li&gt;IIFE (Immediately-invoked function expression)&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Expression bodied function member&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-as-data-and-expression-tree&quot;&gt;Expression tree: Function as data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lambda expression as expression tree
&lt;ul&gt;
&lt;li&gt;Metaprogramming: function as abstract syntax tree&lt;/li&gt;
&lt;li&gt;.NET expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Compile expression tree at runtime
&lt;ul&gt;
&lt;li&gt;Traverse expression tree&lt;/li&gt;
&lt;li&gt;Expression tree to CIL at runtime&lt;/li&gt;
&lt;li&gt;Expression tree to executable function at runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Expression tree and LINQ remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-higher-order-function-currying-and-first-class-function&quot;&gt;Higher-order function, currying and first class function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First order function vs. higher-order function
&lt;ul&gt;
&lt;li&gt;Convert first-order function to higher-order function&lt;/li&gt;
&lt;li&gt;Lambda operator =&amp;gt; associativity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Curry function
&lt;ul&gt;
&lt;li&gt;Uncurry function&lt;/li&gt;
&lt;li&gt;Partial applying function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;First-class function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-composition-and-method-chaining&quot;&gt;Function composition and chaining&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Forward composition vs. backward composition&lt;/li&gt;
&lt;li&gt;Forward piping&lt;/li&gt;
&lt;li&gt;Method chaining and fluent interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-query-expression&quot;&gt;LINQ query expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Syntax and compilation&lt;/li&gt;
&lt;li&gt;Query expression pattern&lt;/li&gt;
&lt;li&gt;LINQ query expression
&lt;ul&gt;
&lt;li&gt;Forward piping with LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query expression vs. query method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-covariance-and-contravariance&quot;&gt;Covariance and contravariance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Subtyping and type polymorphism&lt;/li&gt;
&lt;li&gt;Variances of non-generic function type&lt;/li&gt;
&lt;li&gt;Variances of generic function type&lt;/li&gt;
&lt;li&gt;Variances of generic interface&lt;/li&gt;
&lt;li&gt;Variances of generic higher-order function type&lt;/li&gt;
&lt;li&gt;Covariance of array&lt;/li&gt;
&lt;li&gt;Variances in .NET and LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-immutability-anonymous-type-and-tuple&quot;&gt;Immutability, anonymous type and tuple&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Immutable value
&lt;ul&gt;
&lt;li&gt;Constant local&lt;/li&gt;
&lt;li&gt;Enumeration&lt;/li&gt;
&lt;li&gt;using declaration and foreach statement&lt;/li&gt;
&lt;li&gt;Immutable alias (immutable ref local variable)&lt;/li&gt;
&lt;li&gt;Function’s immutable input and immutable output&lt;/li&gt;
&lt;li&gt;Range variable in LINQ query expression&lt;/li&gt;
&lt;li&gt;this reference for class&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable state (immutable type)
&lt;ul&gt;
&lt;li&gt;Constant field&lt;/li&gt;
&lt;li&gt;Immutable class with readonly instance field&lt;/li&gt;
&lt;li&gt;Immutable structure (readonly structure)&lt;/li&gt;
&lt;li&gt;Immutable anonymous type
&lt;ul&gt;
&lt;li&gt;Local variable type inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable tuple vs. mutable tuple
&lt;ul&gt;
&lt;li&gt;Construction, element name and element inference&lt;/li&gt;
&lt;li&gt;Deconstruction&lt;/li&gt;
&lt;li&gt;Tuple assignment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable collection vs. readonly collection&lt;/li&gt;
&lt;li&gt;Shallow immutability vs. deep immutability&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pure-function&quot;&gt;Pure function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pure function vs. impure function
&lt;ul&gt;
&lt;li&gt;Referential transparency and side effect free&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Purity in .NET&lt;/li&gt;
&lt;li&gt;Purity in LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-asynchronous-function&quot;&gt;Asynchronous function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Task, Task&amp;lt;TResult&amp;gt; and asynchrony&lt;/li&gt;
&lt;li&gt;Named async function&lt;/li&gt;
&lt;li&gt;Awaitable-awaiter pattern&lt;/li&gt;
&lt;li&gt;Async state machine&lt;/li&gt;
&lt;li&gt;Runtime context capture&lt;/li&gt;
&lt;li&gt;Generalized async return type and async method builder
&lt;ul&gt;
&lt;li&gt;ValueTask&amp;lt;TResult&amp;gt; and performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Anonymous async function&lt;/li&gt;
&lt;li&gt;Asynchronous sequence: IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;async using declaration: IAsyncDispose&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pattern-matching&quot;&gt;Pattern matching&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Is expression&lt;/li&gt;
&lt;li&gt;switch statement and switch expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects: Querying objects in memory&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-local-sequential-query&quot;&gt;Local sequential LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Iteration pattern and foreach statement&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;foreach loop vs. for loop&lt;/li&gt;
&lt;li&gt;Non-generic sequence vs. generic sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ to Objects queryable types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-operators-and-query-expressions&quot;&gt;LINQ to Objects standard queries and query expressions&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType, where&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany, from, let, select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy, group, by, into&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, join, on, equals&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, join, into, on, equals&lt;/li&gt;
&lt;li&gt;Cross join: SelectMany, Join, from select, join, on, equals&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse, orderby, ascending, descending, into&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queries in other languages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-generator&quot;&gt;Generator&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Implementing iterator pattern&lt;/li&gt;
&lt;li&gt;Generating sequence and iterator&lt;/li&gt;
&lt;li&gt;Yield statement and generator&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation&quot;&gt;Deferred execution, lazy evaluation and eager Evaluation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Immediate execution vs. Deferred execution
&lt;ul&gt;
&lt;li&gt;Cold IEnumerable&amp;lt;T&amp;gt; vs. hot IEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-implementation&quot;&gt;LINQ to Objects internals: Standard queries implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Argument check and deferred execution&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join: SelectMany, Join, GroupJoin&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-interactive-extensions-ix&quot;&gt;Advanced queries in Microsoft Interactive Extensions (Ix)&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: Defer, Create, Return, Repeat&lt;/li&gt;
&lt;li&gt;Filtering: IgnoreElements, DistinctUntilChanged&lt;/li&gt;
&lt;li&gt;Mapping: SelectMany, Scan, Expand&lt;/li&gt;
&lt;li&gt;Concatenation: Concat, StartWith&lt;/li&gt;
&lt;li&gt;Set: Distinct&lt;/li&gt;
&lt;li&gt;Partitioning: TakeLast, SkipLast&lt;/li&gt;
&lt;li&gt;Conversion: Hide&lt;/li&gt;
&lt;li&gt;Buffering: Buffer, Share, Publish, Memoize&lt;/li&gt;
&lt;li&gt;Exception: Throw, Catch, Finally, OnErrorResumeNext, Retry&lt;/li&gt;
&lt;li&gt;Imperative: If, Case, Using, While, DoWhile, Generate, For&lt;/li&gt;
&lt;li&gt;Iteration: Do&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Aggregation: Min, Max, MinBy, MaxBy&lt;/li&gt;
&lt;li&gt;Quantifiers: isEmpty&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Void queries
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-custom-query-methods&quot;&gt;Building custom queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries (deferred execution)
&lt;ul&gt;
&lt;li&gt;Generation: Create, RandomInt32, RandomDouble, FromValue, FromValues, EmptyIfNull&lt;/li&gt;
&lt;li&gt;Filtering: Timeout&lt;/li&gt;
&lt;li&gt;Concatenation: Join, Append, Prepend, AppendTo, PrependTo&lt;/li&gt;
&lt;li&gt;Partitioning: Subsequence&lt;/li&gt;
&lt;li&gt;Exception: Catch, Retry&lt;/li&gt;
&lt;li&gt;Comparison: OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;List: Insert, Remove, RemoveAll, RemoveAt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries
&lt;ul&gt;
&lt;li&gt;Comparison: ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;List: IndexOf, LastIndexOf&lt;/li&gt;
&lt;li&gt;Aggregation: PercentileExclusive, PercentileInclusive, Percentile&lt;/li&gt;
&lt;li&gt;Quantifiers: IsNullOrEmpty, IsNotNullOrEmpty&lt;/li&gt;
&lt;li&gt;Comparison: Contains, SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Void queries
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML: Querying XML&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-1-modeling-xml&quot;&gt;Modeling XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Imperative vs. declarative paradigm&lt;/li&gt;
&lt;li&gt;Types, conversions and operators&lt;/li&gt;
&lt;li&gt;Read and deserialize XML&lt;/li&gt;
&lt;li&gt;Serialize and write XML&lt;/li&gt;
&lt;li&gt;Deferred construction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-2-query-methods&quot;&gt;LINQ to XML standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;li&gt;Comparison&lt;/li&gt;
&lt;li&gt;More useful queries&lt;/li&gt;
&lt;li&gt;XPath
&lt;ul&gt;
&lt;li&gt;Generate XPath expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-3-manipulating-xml&quot;&gt;Manipulating XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Clone&lt;/li&gt;
&lt;li&gt;Adding, deleting, replacing, updating, and events&lt;/li&gt;
&lt;li&gt;Annotation&lt;/li&gt;
&lt;li&gt;Validating XML with XSD&lt;/li&gt;
&lt;li&gt;Transforming XML with XSL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ: Querying objects in parallel&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-1-local-parallel-query-and-visualization&quot;&gt;Parallel LINQ query and visualization&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Parallel query vs. sequential query&lt;/li&gt;
&lt;li&gt;Parallel query execution&lt;/li&gt;
&lt;li&gt;Visualizing parallel query execution
&lt;ul&gt;
&lt;li&gt;Using Concurrency Visualizer&lt;/li&gt;
&lt;li&gt;Visualizing sequential and parallel LINQ queries&lt;/li&gt;
&lt;li&gt;Visualizing chaining query methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-2-partitioning&quot;&gt;Parallel LINQ internals: data partitioning&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Partitioning and load balancing
&lt;ul&gt;
&lt;li&gt;Range partitioning&lt;/li&gt;
&lt;li&gt;Chunk partitioning&lt;/li&gt;
&lt;li&gt;Hash partitioning&lt;/li&gt;
&lt;li&gt;Stripped partitioning&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implement custom partitioner
&lt;ul&gt;
&lt;li&gt;Static partitioner&lt;/li&gt;
&lt;li&gt;Dynamic partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-3-query-methods&quot;&gt;Parallel LINQ standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Query settings
&lt;ul&gt;
&lt;li&gt;Cancellation&lt;/li&gt;
&lt;li&gt;Degree of parallelism&lt;/li&gt;
&lt;li&gt;Execution mode&lt;/li&gt;
&lt;li&gt;Merge the values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ordering
&lt;ul&gt;
&lt;li&gt;Preserving the order&lt;/li&gt;
&lt;li&gt;Order and correctness&lt;/li&gt;
&lt;li&gt;Orderable partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregation
&lt;ul&gt;
&lt;li&gt;Commutativity, associativity and correctness&lt;/li&gt;
&lt;li&gt;Partitioning and merging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-4-performance&quot;&gt;Parallel query performance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequential query vs. parallel query&lt;/li&gt;
&lt;li&gt;CPU bound operation vs. IO bound operation&lt;/li&gt;
&lt;li&gt;Factors to impact performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework/Core and LINQ to Entities: Querying relational data&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-1-remote-query&quot;&gt;Remote LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Entity Framework and Entity Framework Core&lt;/li&gt;
&lt;li&gt;SQL database&lt;/li&gt;
&lt;li&gt;Remote query vs. local query&lt;/li&gt;
&lt;li&gt;Function vs. expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&quot;&gt;Modeling database with object-relational mapping&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data types&lt;/li&gt;
&lt;li&gt;Database
&lt;ul&gt;
&lt;li&gt;Connection resiliency and execution retry strategy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Relationships
&lt;ul&gt;
&lt;li&gt;One-to-one&lt;/li&gt;
&lt;li&gt;One-to-many&lt;/li&gt;
&lt;li&gt;Many-to-many&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Views&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&quot;&gt;Logging and tracing LINQ to Entities queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Application side logging&lt;/li&gt;
&lt;li&gt;Database side tracing with Extended Events&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-4-query-methods&quot;&gt;LINQ to Entities standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries
&lt;ul&gt;
&lt;li&gt;Generation: DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, GroupJoin, Select&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, Select, SelectMany&lt;/li&gt;
&lt;li&gt;Cross join and self join: SelectMany, Join&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsQueryable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&quot;&gt;LINQ to Entities internals: Query translation implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Code to LINQ expression tree
&lt;ul&gt;
&lt;li&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/li&gt;
&lt;li&gt;Standard remote queries&lt;/li&gt;
&lt;li&gt;Building LINQ to Entities abstract syntax tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;.NET expression tree to database expression tree
&lt;ul&gt;
&lt;li&gt;Database query abstract syntax tree&lt;/li&gt;
&lt;li&gt;Compiling LINQ expressions to database expressions&lt;/li&gt;
&lt;li&gt;Compiling LINQ queries&lt;/li&gt;
&lt;li&gt;Compiling .NET API calls&lt;/li&gt;
&lt;li&gt;Remote API call vs. local API call&lt;/li&gt;
&lt;li&gt;Compile database functions and operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Database expression tree to database query language
&lt;ul&gt;
&lt;li&gt;SQL generator and SQL command&lt;/li&gt;
&lt;li&gt;Generating SQL from database expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading&quot;&gt;Loading query data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deferred execution
&lt;ul&gt;
&lt;li&gt;Iterator pattern&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Explicit loading&lt;/li&gt;
&lt;li&gt;Eager loading&lt;/li&gt;
&lt;li&gt;Lazy loading
&lt;ul&gt;
&lt;li&gt;The N + 1 problem&lt;/li&gt;
&lt;li&gt;Disabling lazy loading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&quot;&gt;Manipulating relational data: Data change and transaction&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repository pattern and unit of work pattern&lt;/li&gt;
&lt;li&gt;Tracking entities and changes
&lt;ul&gt;
&lt;li&gt;Tracking entities&lt;/li&gt;
&lt;li&gt;Tracking entity changes and property changes&lt;/li&gt;
&lt;li&gt;Tracking relationship changes&lt;/li&gt;
&lt;li&gt;Enabling and disabling tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Change data
&lt;ul&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Delete&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Transaction
&lt;ul&gt;
&lt;li&gt;Transaction with connection resiliency and execution strategy&lt;/li&gt;
&lt;li&gt;EF Core transaction&lt;/li&gt;
&lt;li&gt;ADO.NET transaction&lt;/li&gt;
&lt;li&gt;Transaction scope&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&quot;&gt;Resolving optimistic concurrency&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Detecting concurrent conflicts&lt;/li&gt;
&lt;li&gt;Resolving concurrent conflicts
&lt;ul&gt;
&lt;li&gt;Retaining database values (database wins)&lt;/li&gt;
&lt;li&gt;Overwriting database values (client wins)&lt;/li&gt;
&lt;li&gt;Merging with database values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Saving changes with concurrent conflict handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C#: The foundation of all functional programming&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-1-fundamentals&quot;&gt;Basics&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Expression
&lt;ul&gt;
&lt;li&gt;Bound variable vs. free variable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reductions
&lt;ul&gt;
&lt;li&gt;α-conversion (alpha-conversion)&lt;/li&gt;
&lt;li&gt;β-reduction (beta-reduction)&lt;/li&gt;
&lt;li&gt;η-conversion (eta-conversion)&lt;/li&gt;
&lt;li&gt;Normal order&lt;/li&gt;
&lt;li&gt;Applicative order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Function composition
&lt;ul&gt;
&lt;li&gt;Associativity&lt;/li&gt;
&lt;li&gt;Unit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-2-boolean-and-logic&quot;&gt;Church encoding: Function as boolean and logic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church encoding&lt;/li&gt;
&lt;li&gt;Church Boolean&lt;/li&gt;
&lt;li&gt;Logical operators&lt;/li&gt;
&lt;li&gt;Conversion between Church Boolean and System.Boolean&lt;/li&gt;
&lt;li&gt;If&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;Church encoding: Function as numeral, arithmetic and predicate&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church numerals&lt;/li&gt;
&lt;li&gt;Increase and decrease&lt;/li&gt;
&lt;li&gt;Arithmetic operators&lt;/li&gt;
&lt;li&gt;Predicate and relational operators
&lt;ul&gt;
&lt;li&gt;Attempt of recursion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conversion between Church numeral and System.UInt32&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&quot;&gt;Church encoding: Function as tuple and signed numeral&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church pair (2-tuple)
&lt;ul&gt;
&lt;li&gt;Tuple operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;N-tuple&lt;/li&gt;
&lt;li&gt;Signed numeral
&lt;ul&gt;
&lt;li&gt;Arithmetic operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-5-list&quot;&gt;Church encoding: Function as list&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tuple as list node
&lt;ul&gt;
&lt;li&gt;List operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregation function as list node
&lt;ul&gt;
&lt;li&gt;List operators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Model everything&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-6-combinatory-logic&quot;&gt;Combinatory logic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Combinator&lt;/li&gt;
&lt;li&gt;SKI combinator calculus
&lt;ul&gt;
&lt;li&gt;SKI compiler: compile lambda calculus expression to SKI calculus combinator&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Iota combinator calculus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion&quot;&gt;Fixed point combinator and recursion&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Normal order fixed point combinator (Y combinator) and recursion&lt;/li&gt;
&lt;li&gt;Applicative order fixed point combinator (Z combinator) and recursion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-24-undecidability-of-equivalence&quot;&gt;Undecidability of equivalence&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Halting problem&lt;/li&gt;
&lt;li&gt;Equivalence problem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C#: The essentials and design of LINQ&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-1-fundamentals&quot;&gt;Basics: Category and morphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Category and category laws&lt;/li&gt;
&lt;li&gt;DotNet category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-2-monoid&quot;&gt;Monoid&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoid and monoid laws&lt;/li&gt;
&lt;li&gt;Monoid as category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;Functor and LINQ to Functors&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functor and functor laws
&lt;ul&gt;
&lt;li&gt;Endofunctor&lt;/li&gt;
&lt;li&gt;Type constructor and higher-kinded type&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ to Functors
&lt;ul&gt;
&lt;li&gt;Built-in IEnumerable&amp;lt;&amp;gt; functor&lt;/li&gt;
&lt;li&gt;Functor pattern of LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;More LINQ to Functors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-4-natural-transformation&quot;&gt;Natural transformation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Natural transformation and naturality&lt;/li&gt;
&lt;li&gt;Functor Category
&lt;ul&gt;
&lt;li&gt;Endofunctor category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-5-bifunctor&quot;&gt;Bifunctor&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bifunctor&lt;/li&gt;
&lt;li&gt;Monoidal category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;Monoidal functor and applicative functor&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoidal functor
&lt;ul&gt;
&lt;li&gt;IEnumeable&amp;lt;&amp;gt; monoidal functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Applicative functor
&lt;ul&gt;
&lt;li&gt;IEnumeable&amp;lt;&amp;gt; applicative functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monoidal functor vs. applicative functor&lt;/li&gt;
&lt;li&gt;More Monoidal functors and applicative functors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;Monad and LINQ to Monads&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monad&lt;/li&gt;
&lt;li&gt;LINQ to Monads and monad laws
&lt;ul&gt;
&lt;li&gt;Built-in IEnumerable&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Monad laws and Kleisli composition&lt;/li&gt;
&lt;li&gt;Kleisli category&lt;/li&gt;
&lt;li&gt;Monad pattern of LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monad vs. monoidal/applicative functor&lt;/li&gt;
&lt;li&gt;More LINQ to Monads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;Advanced LINQ to Monads&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IO monad&lt;/li&gt;
&lt;li&gt;State monad&lt;/li&gt;
&lt;li&gt;Try monad&lt;/li&gt;
&lt;li&gt;Reader monad&lt;/li&gt;
&lt;li&gt;Writer monad&lt;/li&gt;
&lt;li&gt;Continuation monad&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>EntityFramework.Functions: Code First Functions for Entity Framework</title><link>https://dixin.github.io/posts/entityframeworkfunctions/</link><guid isPermaLink="true">https://dixin.github.io/posts/entityframeworkfunctions/</guid><description>EntityFramework.Functions library implements  code first support for:</description><pubDate>Fri, 19 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;EntityFramework.Functions library implements &lt;a href=&quot;https://en.wikipedia.org/wiki/Entity_Framework&quot;&gt;Entity Framework&lt;/a&gt; code first support for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stored procedures, with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;single result type&lt;/li&gt;
&lt;li&gt;multiple result types&lt;/li&gt;
&lt;li&gt;output parameter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Table-valued functions, returning&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;entity type&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;complex type&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scalar-valued functions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;composable&lt;/li&gt;
&lt;li&gt;non-composable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregate functions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Built-in functions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Niladic functions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Model defined functions&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;EntityFramework.Functions library works on .NET Standard with Entity Framework 6.4.0. It also works on .NET 4.0, .NET 4.5, .NET 4.6, .NET 4.7, .NET 4.8 with &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj574253.aspx&quot;&gt;Entity Framework 6.1.0 and later&lt;/a&gt;. Entity Framework is the only dependency of this library.&lt;/p&gt;
&lt;p&gt;It can be installed through &lt;a href=&quot;https://www.nuget.org/packages/EntityFramework.Functions&quot;&gt;Nuget&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet add package EntityFramework.Functions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-Package EntityFramework.Functions -DependencyVersion Highest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Document: &lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions&quot;&gt;https://weblogs.asp.net/Dixin/EntityFramework.Functions&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Source_code&quot;&gt;Source code&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#APIs&quot;&gt;APIs&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#%5BFunction%5D&quot;&gt;[Function]&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#%5BParameter%5D&quot;&gt;[Parameter]&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#%5BResultType%5D&quot;&gt;[ResultType]&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#FunctionConvention_and_FunctionConvention%3CTFunctions%3E&quot;&gt;FunctionConvention and FunctionConvention&amp;lt;TFunctions&amp;gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Examples&quot;&gt;Examples&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Add_functions_to_entity_model&quot;&gt;Add functions to entity model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Stored procedure, with single result type](https://weblogs.asp.net/Dixin/EntityFramework.Functions#Stored procedure,_with_single_result_type)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Stored_procedure,_with_output_parameter&quot;&gt;Stored procedure, with output parameter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Stored_procedure,_with_multiple_result_types&quot;&gt;Stored procedure, with multiple result types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Table-valued_function&quot;&gt;Table-valued function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Scalar-valued_function,_non-composable&quot;&gt;Scalar-valued function, non-composable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Scalar-valued_function,_composable&quot;&gt;Scalar-valued function, composable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Aggregate_function&quot;&gt;Aggregate function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Built-in_function&quot;&gt;Built-in function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Niladic_function&quot;&gt;Niladic function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Model_defined_function&quot;&gt;Model defined function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions#Version_history&quot;&gt;Version history&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Source code: &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions&quot;&gt;https://github.com/Dixin/EntityFramework.Functions&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nuget package: &lt;a href=&quot;https://www.nuget.org/packages/EntityFramework.Functions&quot;&gt;https://www.nuget.org/packages/EntityFramework.Functions&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Source code&lt;/h2&gt;
&lt;p&gt;The source can be opened and built in Visual Studio 2015.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/fbe9b9b8-34ae-47b5-a751-cb71a16f7e96&quot;&gt;Nuget package project&lt;/a&gt; is used to build the &lt;a href=&quot;https://www.nuget.org/packages/EntityFramework.Functions&quot;&gt;nuget package&lt;/a&gt; from a &lt;a href=&quot;http://nuproj.net/&quot;&gt;.nuproj&lt;/a&gt;. It is already included in the source.&lt;/p&gt;
&lt;p&gt;To view &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions/tree/master/Data&quot;&gt;the sample database&lt;/a&gt;, or run the unit test against the sample database, please install &lt;a href=&quot;https://www.microsoft.com/en-us/download/details.aspx?id=42299&quot;&gt;SQL Server 2014 LocalDB&lt;/a&gt; or &lt;a href=&quot;https://www.microsoft.com/en-us/download/details.aspx?id=52679&quot;&gt;SQL Server 2016 LocalDB&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;APIs&lt;/h2&gt;
&lt;p&gt;EntityFramework.Functions library provides a few simple APIs, following the pattern of Entity Framework and LINQ to SQL.&lt;/p&gt;
&lt;h3&gt;[Function]&lt;/h3&gt;
&lt;p&gt;[Function(FunctionType type, string name)] attribute derives from &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.entity.dbfunctionattribute.aspx&quot;&gt;DbFunctionAttribute&lt;/a&gt; provided in Entity Framework. It is also similar to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.linq.mapping.functionattribute.aspx&quot;&gt;FunctionAttribute&lt;/a&gt; in &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb386976.aspx&quot;&gt;LINQ to SQL&lt;/a&gt;. When a method is tagged with [Function], it maps to a database function or stored procedure. The FunctionType parameter is an enumeration, with the following members:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;StoredProcedure&lt;/li&gt;
&lt;li&gt;TableValuedFunction&lt;/li&gt;
&lt;li&gt;ComposableScalarValuedFunction&lt;/li&gt;
&lt;li&gt;NonComposableScalarValuedFunction&lt;/li&gt;
&lt;li&gt;AggregateFunction&lt;/li&gt;
&lt;li&gt;BuiltInFunction,&lt;/li&gt;
&lt;li&gt;NiladicFunction,&lt;/li&gt;
&lt;li&gt;ModelDefinedFunction&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples for each function type can be found below.&lt;/p&gt;
&lt;p&gt;The other name parameter specifies the database function/stored procedure that is mapped to. Even when C# method name is exactly the same as the mapped database function/stored procedure, this name string still has to be provided. This is required by Entity Framework.&lt;/p&gt;
&lt;p&gt;[Function] has 2 settable properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Schema: It specifies the schema of the mapped database function/stored procedure, e.g. “dbo”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ParameterTypeSemantics: It is of &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.metadata.edm.parametertypesemantics.aspx&quot;&gt;ParameterTypeSemantics&lt;/a&gt; type provided in Entity Framework. It defines the type semantics used to resolve function overloads. ParameterTypeSemantics is an enumeration of 3 members:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AllowImplicitConversion (the default)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AllowImplicitPromotion&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ExactMatchOnly&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides general [Function] attribute, a specific attribute is also provided for each function type:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[StoredProcedure]&lt;/li&gt;
&lt;li&gt;[TableValuedFunction]&lt;/li&gt;
&lt;li&gt;[ComposableScalarValuedFunction]&lt;/li&gt;
&lt;li&gt;[NonComposableScalarValuedFunction]&lt;/li&gt;
&lt;li&gt;[AggregateFunction]&lt;/li&gt;
&lt;li&gt;[BuiltInFunction]&lt;/li&gt;
&lt;li&gt;[NiladicFunction]&lt;/li&gt;
&lt;li&gt;[ModelDefinedFunction]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;[Parameter]&lt;/h3&gt;
&lt;p&gt;[Parameter] tags the function parameter to specify the mapped database function/stored procedure’s parameter name and type. It is similar to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.linq.mapping.parameterattribute.aspx&quot;&gt;ParameterAttribute&lt;/a&gt; in LINQ to SQL.&lt;/p&gt;
&lt;p&gt;[Parameter] has 3 settable properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Name: the name of the mapped parameter in database.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbType: the tyoe of the mapped parameter in database, like “money”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ClrType: the type of the mapping .NET parameter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Entity Framework, when a parameter is a output parameter, it has to be of ObjectParameter type. In this case, the mapping CLR type cannot be predicted and has to be provided by [Parameter]’s ClrType property.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In other cases, ClrType property can be omitted. At runtime, If ClrType conflicts with CLR parameter’s actual declaration CLR type, an exception will be thrown.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[Parameter] can be omitted. when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the parameter is not an output parameter&lt;/li&gt;
&lt;li&gt;and its name is the same as the mapped database parameter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[Parameter] can also be used to tag the return value of method, to specify the DbType of the mapped database function return value, which is also the same as LINQ to SQL. Please see examples below.&lt;/p&gt;
&lt;h3&gt;[ResultType]&lt;/h3&gt;
&lt;p&gt;[ResultType(Type type)] is exactly the same as &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.linq.mapping.resulttypeattribute.aspx&quot;&gt;ResultTypeAttribute&lt;/a&gt; in LINQ to SQL. Its constructor accepts a Type parameter to specify the return type of stored procedure. Typically, when the stored procedure has multiple result types, the mapping method can be tagged with multiple [ResultType]s.&lt;/p&gt;
&lt;p&gt;[ResultType] cannot be used for functions.&lt;/p&gt;
&lt;h3&gt;FunctionConvention and FunctionConvention&amp;lt;TFunctions&amp;gt;&lt;/h3&gt;
&lt;p&gt;FunctionConvention and FunctionConvention&amp;lt;TFunctions&amp;gt; implements Entity Framework’s &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn338062.aspx&quot;&gt;IStoreModelConvention&lt;/a&gt;&amp;lt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.metadata.edm.entitycontainer.aspx&quot;&gt;EntityContainer&lt;/a&gt;&amp;gt; contract. They must be added to specify in what Type the mapping methods are located.&lt;/p&gt;
&lt;p&gt;When the functions are added to entity model, the entity types and complex types used by functions should be added to entity model too. Entity Framework does not take care of types tagged with [&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.complextypeattribute.aspx&quot;&gt;ComplexType&lt;/a&gt;], so this library provides a AddComplexTypesFromAssembly extension method for this.&lt;/p&gt;
&lt;p&gt;For convenience, 2 extension methods AddFunctions/AddFunction&amp;lt;TFunctions&amp;gt; are provided. When they are called:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FunctionConvention/FunctionConvention&amp;lt;TFunctions&amp;gt; is added to entity model.&lt;/li&gt;
&lt;li&gt;AddComplexTypesFromAssembly is automatically called. In the assembly of TFunction, types tagged with [ComplextType] are added to entity model.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
&lt;p&gt;The following examples uses Microsoft’s &lt;a href=&quot;https://msftdbprodsamples.codeplex.com/&quot;&gt;AdventureWorks sample database&lt;/a&gt; for SQL Server 2014. The database can also be found in this library’s &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions/tree/master/Data&quot;&gt;source repository&lt;/a&gt; on &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Add functions to entity model&lt;/h3&gt;
&lt;p&gt;Before calling any code first function, FunctionConvention or FunctionConvention&amp;lt;TFunctions&amp;gt; must be added to DbModelBuilder of the DbContext, so are the complex types used by functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Add functions on AdventureWorks to entity model.
        modelBuilder.Conventions.Add(new FunctionConvention&amp;lt;AdventureWorks&amp;gt;());

        // Add all complex types used by functions.
        modelBuilder.ComplexType&amp;lt;ContactInformation&amp;gt;();
        modelBuilder.ComplexType&amp;lt;ManagerEmployee&amp;gt;();
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here new FunctionConvention&amp;lt;T&amp;gt;() is equivalent to new FunctionConvention(typeof(T)). The non-generic version is provided because in C# static class cannot be used as type argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Add functions on AdventureWorks and StaticClass to entity model.
        modelBuilder.Conventions.Add(new FunctionConvention&amp;lt;AdventureWorks&amp;gt;());
        modelBuilder.Conventions.Add(new FunctionConvention(typeof(StaticClass)));

        // Add all complex types in the assembly of AdventureWorks.
        modelBuilder.AddComplexTypesFromAssembly(typeof(AdventureWorks).Assembly);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, AddFunctions/AddFunction&amp;lt;TFunctions&amp;gt; extension methods are provided as a shortcut, which automatically add all complex types in the assembly of TFunctions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Add functions and complex types to model.
        modelBuilder.AddFunctions&amp;lt;AdventureWorks&amp;gt;();
        modelBuilder.AddFunctions(typeof(AdventureWorksFunctions));
        modelBuilder.AddFunctions(typeof(BuiltInFunctions));
        modelBuilder.AddFunctions(typeof(NiladicFunctions));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Stored procedure, with single result type&lt;/h3&gt;
&lt;p&gt;The AdventureWorks database has a sample stored procedure uspGetManagerEmployees. Its return type can be viewed with &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff878258.aspx&quot;&gt;dm_exec_describe_first_result_set&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM sys.dm_exec_describe_first_result_set(N&apos;dbo.uspGetManagerEmployees&apos;, NULL, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framewotk_FE46/image_5.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framewotk_FE46/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An entity type or a complex type can be defined to represent above return type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ComplexType]
public class ManagerEmployee
{
    public int? RecursionLevel { get; set; }

    public string OrganizationNode { get; set; }

    public string ManagerFirstName { get; set; }

    public string ManagerLastName { get; set; }

    public int? BusinessEntityID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is tagged with [&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.complextypeattribute.aspx&quot;&gt;ComplexType&lt;/a&gt;], which is provided in System.ComponentModel.DataAnnotations.dll, and used by Entity Framework. When calling AddFunctions(typeof(TFunctions))/AddFunction&amp;lt;TFunctions&amp;gt;(), types tagged with [ComplexType] in the same assembly are added to entity model too.&lt;/p&gt;
&lt;p&gt;Now the mapping method can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public const string dbo = nameof(dbo);

    // Defines stored procedure returning a single result type: 
    // - a ManagerEmployee sequence.
    [Function(FunctionType.StoredProcedure, nameof(uspGetManagerEmployees), Schema = dbo)]
    public ObjectResult&amp;lt;ManagerEmployee&amp;gt; uspGetManagerEmployees(int? BusinessEntityID)
    {
        ObjectParameter businessEntityIdParameter = BusinessEntityID.HasValue
            ? new ObjectParameter(nameof(BusinessEntityID), BusinessEntityID)
            : new ObjectParameter(nameof(BusinessEntityID), typeof(int));

        return this.ObjectContext().ExecuteFunction&amp;lt;ManagerEmployee&amp;gt;(
            nameof(this.uspGetManagerEmployees), businessEntityIdParameter);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In its body, it should call ExecuteFunction on ObjectContext. Here ObjectContext method is an extension method provided by this library.&lt;/p&gt;
&lt;p&gt;Then it can be called as following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void CallStoredProcedureWithSingleResult()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        ObjectResult&amp;lt;ManagerEmployee&amp;gt; employees = database.uspGetManagerEmployees(2);
        Assert.IsTrue(employees.Any());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above call is translated to the following SQL, which can be viewed with SQL Server Profiler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec [dbo].[uspGetManagerEmployees] @BusinessEntityID=2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Stored procedure, with output parameter&lt;/h3&gt;
&lt;p&gt;As fore mentioned, stored procedure’s output parameter is represented by ObjectParameter and must be tagged with [Parameter], with ClrType provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private const string uspLogError = nameof(uspLogError);

// Defines stored procedure accepting an output parameter.
// Output parameter must be ObjectParameter, with ParameterAttribute.ClrType provided.
[Function(FunctionType.StoredProcedure, uspLogError, Schema = dbo)]
public int LogError([Parameter(DbType = &quot;int&quot;, ClrType = typeof(int))]ObjectParameter ErrorLogID) =&amp;gt;
    this.ObjectContext().ExecuteFunction(uspLogError, ErrorLogID);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then it can be called as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void CallStoreProcedureWithOutParameter()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        ObjectParameter errorLogId = new ObjectParameter(&quot;ErrorLogID&quot;, typeof(int)) { Value = 5 };
        int? rows = database.LogError(errorLogId);
        Assert.AreEqual(0, errorLogId.Value);
        Assert.AreEqual(typeof(int), errorLogId.ParameterType);
        Assert.AreEqual(-1, rows);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;declare @p1 int
set @p1=0
exec [dbo].[uspLogError] @ErrorLogID=@p1 output
select @p1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Stored procedure, with multiple result types&lt;/h3&gt;
&lt;p&gt;The following stored procedure returns 2 different types of results: a sequence of ProductCategory row(s), and a sequence of ProductSubcategory row(s).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE PROCEDURE [dbo].[uspGetCategoryAndSubCategory]
    @CategoryID int
AS
BEGIN
    SELECT [Category].[ProductCategoryID], [Category].[Name]
        FROM [Production].[ProductCategory] AS [Category] 
        WHERE [Category].[ProductCategoryID] = @CategoryID;

    SELECT [Subcategory].[ProductSubcategoryID], [Subcategory].[Name], [Subcategory].[ProductCategoryID]
        FROM [Production].[ProductSubcategory] As [Subcategory]
        WHERE [Subcategory].[ProductCategoryID] = @CategoryID;
END
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The involved ProductCategory table and ProductSubcategory table can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public const string Production = nameof(Production);

    public DbSet&amp;lt;ProductCategory&amp;gt; ProductCategories { get; set; }

    public DbSet&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; }
}

[Table(nameof(ProductCategory), Schema = AdventureWorks.Production)]
public partial class ProductCategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductCategoryID { get; set; }

    [MaxLength(50)]
    public string Name { get; set; }
}

[Table(nameof(ProductSubcategory), Schema = AdventureWorks.Production)]
public partial class ProductSubcategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductSubcategoryID { get; set; }

    [MaxLength(50)]
    public string Name { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above ProductCategory and ProductSubcategory classes are tagged with [Table], so they will be added to entity model automatically by Entity Framework.&lt;/p&gt;
&lt;p&gt;Multiple return types can be specified by [ReturnType]. The return type defined on the method will be merged into the return types from [ReturnType]s, and be at the first position:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Defines stored procedure returning multiple result types: 
// - a ProductCategory sequence.
// - a ProductSubcategory sequence.
[Function(FunctionType.StoredProcedure, nameof(uspGetCategoryAndSubCategory), Schema = dbo)]
[ResultType(typeof(ProductCategory))]
[ResultType(typeof(ProductSubcategory))]
public ObjectResult&amp;lt;ProductCategory&amp;gt; uspGetCategoryAndSubCategory(int CategoryID)
{
    ObjectParameter categoryIdParameter = new ObjectParameter(nameof(CategoryID), CategoryID);
    return this.ObjectContext().ExecuteFunction&amp;lt;ProductCategory&amp;gt;(
        nameof(this.uspGetCategoryAndSubCategory), categoryIdParameter);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then it can be called to retrieve one ProductCategory sequence, and one ProductSubcategory sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void CallStoreProcedureWithMultipleResults()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        // The first type of result type: a sequence of ProductCategory objects.
        ObjectResult&amp;lt;ProductCategory&amp;gt; categories = database.uspGetCategoryAndSubCategory(1);
        Assert.IsNotNull(categories.Single());
        // The second type of result type: a sequence of ProductCategory objects.
        ObjectResult&amp;lt;ProductSubcategory&amp;gt; subcategories = categories.GetNextResult&amp;lt;ProductSubcategory&amp;gt;();
        Assert.IsTrue(subcategories.Any());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The SQL translation is normal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec [dbo].[uspGetCategoryAndSubCategory] @CategoryID=1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Table-valued function&lt;/h3&gt;
&lt;p&gt;The AdventureWorks sample database has a table-valued function, dbo.ufnGetContactInformation, its return type can be also represented as another complex type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ComplexType]
public class ContactInformation
{
    public int PersonID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string JobTitle { get; set; }

    public string BusinessEntityType { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the ufnGetContactInformation function can be mapped by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Defines table-valued function, which must return IQueryable&amp;lt;T&amp;gt;.
[Function(FunctionType.TableValuedFunction, nameof(ufnGetContactInformation), Schema = dbo)]
public IQueryable&amp;lt;ContactInformation&amp;gt; ufnGetContactInformation(
    [Parameter(DbType = &quot;int&quot;, Name = &quot;PersonID&quot;)]int? personId)
{
    ObjectParameter personIdParameter = personId.HasValue
        ? new ObjectParameter(&quot;PersonID&quot;, personId)
        : new ObjectParameter(&quot;PersonID&quot;, typeof(int));

    return this.ObjectContext().CreateQuery&amp;lt;ContactInformation&amp;gt;(
        $&quot;[{nameof(this.ufnGetContactInformation)}](@{nameof(personId)})&quot;, personIdParameter);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its return type should be IQueryable&amp;lt;T&amp;gt;, so that it is composable in LINQ to Entities. And it can be called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void CallTableValuedFunction()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        IQueryable&amp;lt;ContactInformation&amp;gt; employees = database.ufnGetContactInformation(1).Take(2);
        Assert.IsNotNull(employees.Single());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above ufnGetContactInformation call and Take call will be translated to one single SQL query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT TOP (2) 
    [top].[C1] AS [C1], 
    [top].[PersonID] AS [PersonID], 
    [top].[FirstName] AS [FirstName], 
    [top].[LastName] AS [LastName], 
    [top].[JobTitle] AS [JobTitle], 
    [top].[BusinessEntityType] AS [BusinessEntityType]
    FROM ( SELECT TOP (2) 
        [Extent1].[PersonID] AS [PersonID], 
        [Extent1].[FirstName] AS [FirstName], 
        [Extent1].[LastName] AS [LastName], 
        [Extent1].[JobTitle] AS [JobTitle], 
        [Extent1].[BusinessEntityType] AS [BusinessEntityType], 
        1 AS [C1]
        FROM [dbo].[ufnGetContactInformation](@PersonID) AS [Extent1]
    )  AS [top]&apos;,N&apos;@PersonID int&apos;,@PersonID=1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Scalar-valued function, non-composable&lt;/h3&gt;
&lt;p&gt;For scalar-valued function. the return value becomes a primitive non-collection type.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Defines scalar-valued function (non-composable), 
// which cannot be used in LINQ to Entities queries;
// and can be called directly.
[Function(FunctionType.NonComposableScalarValuedFunction, nameof(ufnGetProductStandardCost), Schema = dbo)]
[return: Parameter(DbType = &quot;money&quot;)]
public decimal? ufnGetProductStandardCost(
    [Parameter(DbType = &quot;int&quot;)]int ProductID,
    [Parameter(DbType = &quot;datetime&quot;)]DateTime OrderDate)
{
    ObjectParameter productIdParameter = new ObjectParameter(nameof(ProductID), ProductID);
    ObjectParameter orderDateParameter = new ObjectParameter(nameof(OrderDate), OrderDate);
    return this.ObjectContext().ExecuteFunction&amp;lt;decimal?&amp;gt;(
        nameof(this.ufnGetProductStandardCost), productIdParameter, orderDateParameter).SingleOrDefault();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, [Parameter] can tag its return type.&lt;/p&gt;
&lt;p&gt;It can be called directly just like other above methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void CallNonComposableScalarValuedFunction()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        decimal? cost = database.ufnGetProductStandardCost(999, DateTime.Now);
        Assert.IsNotNull(cost);
        Assert.IsTrue(cost &amp;gt; 1);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the translated SQL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [dbo].[ufnGetProductStandardCost](@ProductID, @OrderDate)&apos;,N&apos;@ProductID int,@OrderDate datetime2(7)&apos;,@ProductID=999,@OrderDate=&apos;2015-12-28 02:22:53.0353800&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, since it is specified to be non-composable, it cannot be translated by Entity Framework in LINQ to Entities queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void NonComposableScalarValuedFunctionInLinq()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        try
        {
            database
                .Products
                .Where(product =&amp;gt; product.ListPrice &amp;gt;= database.ufnGetProductStandardCost(999, DateTime.Now))
                .ToArray();
            Assert.Fail();
        }
        catch (NotSupportedException)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is by design of Entity Framework.&lt;/p&gt;
&lt;h3&gt;Scalar-valued function, composable&lt;/h3&gt;
&lt;p&gt;The composable scalar-valued function is very similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Defines scalar-valued function (composable),
// which can only be used in LINQ to Entities queries, where its body will never be executed;
// and cannot be called directly.
[Function(FunctionType.ComposableScalarValuedFunction, nameof(ufnGetProductListPrice), Schema = dbo)]
[return: Parameter(DbType = &quot;money&quot;)]
public decimal? ufnGetProductListPrice(
    [Parameter(DbType = &quot;int&quot;)] int ProductID,
    [Parameter(DbType = &quot;datetime&quot;)] DateTime OrderDate) =&amp;gt; 
        Function.CallNotSupported&amp;lt;decimal?&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, it works in LINQ to Entities queries, but cannot be called directly. As a result, its body will never be executed. So in the body, it can just throw an exception. This library provides a Function.,CallNotSupported help methods for convenience, which just throws a NotSupportedException.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void ComposableScalarValuedFunctionInLinq()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        IQueryable&amp;lt;Product&amp;gt; products = database
            .Products
            .Where(product =&amp;gt; product.ListPrice &amp;lt;= database.ufnGetProductListPrice(999, DateTime.Now));
        Assert.IsTrue(products.Any());
    }
}

[TestMethod]
public void CallComposableScalarValuedFunction()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        try
        {
            database.ufnGetProductListPrice(999, DateTime.Now);
            Assert.Fail();
        }
        catch (NotSupportedException)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above LINQ query, containing composable scalar-valued function, is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;lt;= ([dbo].[ufnGetProductListPrice](999, SysDateTime()))
    )) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent2]
        WHERE [Extent2].[ListPrice] &amp;lt;= ([dbo].[ufnGetProductListPrice](999, SysDateTime()))
    )) THEN cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregate function&lt;/h3&gt;
&lt;p&gt;To demonstrate the mapping of user defined aggregate, the following aggregate function can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToNulls = true,
    IsInvariantToDuplicates = false,
    IsInvariantToOrder = false,
    MaxByteSize = 8000)]
public class Concat : IBinarySerialize
{
    private const string Separator = &quot;, &quot;;

    private StringBuilder concat;

    public void Init()
    {
    }

    public void Accumulate(SqlString sqlString) =&amp;gt; this.concat = this.concat?
        .Append(Separator).Append(sqlString.IsNull ? null : sqlString.Value)
        ?? new StringBuilder(sqlString.IsNull ? null : sqlString.Value);

    public void Merge(Concat concat) =&amp;gt; this.concat.Append(concat.concat);

    public SqlString Terminate() =&amp;gt; new SqlString(this.concat?.ToString());

    public void Read(BinaryReader reader) =&amp;gt; this.concat = new StringBuilder(reader.ReadString());

    public void Write(BinaryWriter writer) =&amp;gt; writer.Write(this.concat?.ToString() ?? string.Empty);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Concat takes 1 parameter, just like COUNT(), SUM(), etc. The following ConcatWith aggregate function accepts 2 parameters, a value and a separator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToNulls = true,
    IsInvariantToDuplicates = false,
    IsInvariantToOrder = false,
    MaxByteSize = 8000)]
public class ConcatWith : IBinarySerialize
{
    private StringBuilder concatWith;

    public void Init()
    {
    }

    public void Accumulate(SqlString sqlString, SqlString separator) =&amp;gt; this.concatWith = this.concatWith?
        .Append(separator.IsNull ? null : separator.Value)
        .Append(sqlString.IsNull ? null : sqlString.Value)
        ?? new StringBuilder(sqlString.IsNull ? null : sqlString.Value);

    public void Merge(ConcatWith concatWith) =&amp;gt; this.concatWith.Append(concatWith.concatWith);

    public SqlString Terminate() =&amp;gt; new SqlString(this.concatWith?.ToString());

    public void Read(BinaryReader reader) =&amp;gt; this.concatWith = new StringBuilder(reader.ReadString());

    public void Write(BinaryWriter writer) =&amp;gt; writer.Write(this.concatWith?.ToString() ?? string.Empty);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Build these 2 classes into a .NET assembly, and add to database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Create assembly.
CREATE ASSEMBLY [Dixin.Sql] 
FROM N&apos;D:\OneDrive\Works\Drafts\CodeSnippets\Dixin.Sql\bin\Debug\Dixin.Sql.dll&apos;;
GO

-- Create aggregate from assembly.
CREATE AGGREGATE [Concat] (@value nvarchar(4000)) RETURNS nvarchar(max)
EXTERNAL NAME [Dixin.Sql].[Dixin.Sql.Concat];
GO

CREATE AGGREGATE [ConcatWith] (@value nvarchar(4000), @separator nvarchar(40)) RETURNS nvarchar(max)
EXTERNAL NAME [Dixin.Sql].[Dixin.Sql.ConcatWith];
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Concat and ConcatWith can be used in SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [Subcategory].[ProductCategoryID], COUNT([Subcategory].[Name]), [dbo].[Concat]([Subcategory].[Name])
FROM [Production].[ProductSubcategory] AS [Subcategory]
GROUP BY [Subcategory].[ProductCategoryID];

SELECT [dbo].[Concat](Name) FROM Production.ProductCategory;

SELECT [Subcategory].[ProductCategoryID], COUNT([Subcategory].[Name]), [dbo].[ConcatWith]([Subcategory].[Name], N&apos; | &apos;)
FROM [Production].[ProductSubcategory] AS [Subcategory]
GROUP BY [Subcategory].[ProductCategoryID];

SELECT [dbo].[ConcatWith](Name, N&apos; | &apos;) FROM Production.ProductCategory;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To map them in C#, the following methods can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class AdventureWorksFunctions
{
    // Defines aggregate function, which must have one singele IEnumerable&amp;lt;T&amp;gt; or IQueryable&amp;lt;T&amp;gt; parameter.
    // It can only be used in LINQ to Entities queries, where its body will never be executed;
    // and cannot be called directly.
    [Function(FunctionType.AggregateFunction, nameof(Concat), Schema = AdventureWorks.dbo)]
    public static string Concat(this IEnumerable&amp;lt;string&amp;gt; value) =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();

    // Aggregate function with more than more parameter is not supported by Entity Framework.
    // The following cannot to translated in LINQ queries.
    // [Function(FunctionType.AggregateFunction, nameof(ConcatWith), Schema = AdventureWorks.dbo)]
    // public static string ConcatWith(this IEnumerable&amp;lt;string&amp;gt; value, string separator) =&amp;gt; 
    //    Function.CallNotSupported&amp;lt;string&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, aggregate functions cannot be called directly, so their bodies just throw exception. Unfortunately, above ConcatWith cannot be translated, because currently Entity Framework does not support aggregate function with more than one parameters.&lt;/p&gt;
&lt;p&gt;They are defined as extension methods of IEnumerable&amp;lt;T&amp;gt;, so that they can easily be used in LINQ to :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void AggregateFunctionInLinq()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        var categories = database.ProductSubcategories
            .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID)
            .Select(category =&amp;gt; new
            {
                CategoryId = category.Key,
                SubcategoryNames = category.Select(subcategory =&amp;gt; subcategory.Name).Concat()
            })
            .ToArray();
        Assert.IsTrue(categories.Length &amp;gt; 0);
        categories.ForEach(category =&amp;gt;
            {
                Assert.IsTrue(category.CategoryId &amp;gt; 0);
                Assert.IsFalse(string.IsNullOrWhiteSpace(category.SubcategoryNames));
            });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above query will be translated to SQL with Concat call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [ProductCategoryID], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
        [Extent1].[ProductCategoryID] AS [K1], 
        [dbo].[Concat]([Extent1].[Name]) AS [A1]
        FROM [Production].[ProductSubcategory] AS [Extent1]
        GROUP BY [Extent1].[ProductCategoryID]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason is Entity Framework does not support aggregate function with more than one parameters.&lt;/p&gt;
&lt;h3&gt;Built-in function&lt;/h3&gt;
&lt;p&gt;SQL Server provides a lot of &lt;a href=&quot;https://msdn.microsoft.com/en-US/library/ms174318.aspx&quot;&gt;built-in functions&lt;/a&gt;. They can be easily represented with [Function] tag. Take &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms177601.aspx&quot;&gt;LEFT function&lt;/a&gt; as example:&lt;/p&gt;
&lt;p&gt;It is a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms181984.aspx&quot;&gt;string function&lt;/a&gt;, returns the left part of a string with the specified number of characters. So, in C#, just defines a function accepting a string parameter and a int parameter, and returns a string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class BuiltInFunctions
{
    [Function(FunctionType.BuiltInFunction, &quot;LEFT&quot;)]
    public static string Left(this string value, int count) =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, it can only be used in LINQ to Entities and cannot be called directly. So in its body, it just simply throw an exception. It is implemented as an extension method of string, for convenience.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void BuitInFunctionInLinq()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        var categories = database.ProductSubcategories
            .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID)
            .Select(category =&amp;gt; new
            {
                CategoryId = category.Key,
                SubcategoryNames = category.Select(subcategory =&amp;gt; subcategory.Name.Left(4)).Concat()
            })
            .ToArray();
        Assert.IsTrue(categories.Length &amp;gt; 0);
        categories.ForEach(category =&amp;gt;
        {
            Assert.IsTrue(category.CategoryId &amp;gt; 0);
            Assert.IsFalse(string.IsNullOrWhiteSpace(category.SubcategoryNames));
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above query is translated to SQL with LEFT call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [ProductCategoryID], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
        [Extent1].[K1] AS [K1], 
        [dbo].[Concat]([Extent1].[A1]) AS [A1]
        FROM ( SELECT 
            [Extent1].[ProductCategoryID] AS [K1], 
            LEFT([Extent1].[Name], 4) AS [A1]
            FROM [Production].[ProductSubcategory] AS [Extent1]
        )  AS [Extent1]
        GROUP BY [K1]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Niladic function&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms174979.aspx&quot;&gt;Niladic functions&lt;/a&gt; are functions called without parentheses, e.g., these SQL-92 niladic functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CURRENT_TIMESTAMP&lt;/li&gt;
&lt;li&gt;CURRENT_USER&lt;/li&gt;
&lt;li&gt;SESSION_USER&lt;/li&gt;
&lt;li&gt;USER&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class NiladicFunctions
{
    [Function(FunctionType.NiladicFunction, &quot;CURRENT_TIMESTAMP&quot;)]
    public static DateTime? CurrentTimestamp() =&amp;gt; Function.CallNotSupported&amp;lt;DateTime?&amp;gt;();

    [Function(FunctionType.NiladicFunction, &quot;CURRENT_USER&quot;)]
    public static string CurrentUser() =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();

    [Function(FunctionType.NiladicFunction, &quot;SESSION_USER&quot;)]
    public static string SessionUser() =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();

    [Function(FunctionType.NiladicFunction, &quot;SYSTEM_USER&quot;)]
    public static string SystemUser() =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();

    [Function(FunctionType.NiladicFunction, &quot;USER&quot;)]
    public static string User() =&amp;gt; Function.CallNotSupported&amp;lt;string&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When they are called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void NiladicFunctionInLinq()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        var firstCategory = database.ProductSubcategories
            .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID)
            .Select(category =&amp;gt; new
            {
                CategoryId = category.Key,
                SubcategoryNames = category.Select(subcategory =&amp;gt; subcategory.Name.Left(4)).Concat(),
                CurrentTimestamp = NiladicFunctions.CurrentTimestamp(),
                CurrentUser = NiladicFunctions.CurrentUser(),
                SessionUser = NiladicFunctions.SessionUser(),
                SystemUser = NiladicFunctions.SystemUser(),
                User = NiladicFunctions.User()
            })
            .First();
        Assert.IsNotNull(firstCategory);
        Assert.IsNotNull(firstCategory.CurrentTimestamp);
        Assert.IsTrue(DateTime.Now &amp;gt;= firstCategory.CurrentTimestamp);
        Assert.AreEqual(&quot;dbo&quot;, firstCategory.CurrentUser, true, CultureInfo.InvariantCulture);
        Assert.AreEqual(&quot;dbo&quot;, firstCategory.SessionUser, true, CultureInfo.InvariantCulture);
        Assert.AreEqual($@&quot;{Environment.UserDomainName}\{Environment.UserName}&quot;, firstCategory.SystemUser, true, CultureInfo.InvariantCulture);
        Assert.AreEqual(&quot;dbo&quot;, firstCategory.User, true, CultureInfo.InvariantCulture);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are translated to SQL calls without parentheses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[C2] AS [C1], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID], 
    [Limit1].[C1] AS [C2], 
    [Limit1].[C3] AS [C3], 
    [Limit1].[C4] AS [C4], 
    [Limit1].[C5] AS [C5], 
    [Limit1].[C6] AS [C6], 
    [Limit1].[C7] AS [C7]
    FROM ( SELECT TOP (1) 
        [GroupBy1].[A1] AS [C1], 
        [GroupBy1].[K1] AS [ProductCategoryID], 
        1 AS [C2], 
        CURRENT_TIMESTAMP AS [C3], 
        CURRENT_USER AS [C4], 
        SESSION_USER AS [C5], 
        SYSTEM_USER AS [C6], 
        USER AS [C7]
        FROM ( SELECT 
            [Extent1].[K1] AS [K1], 
            [dbo].[Concat]([Extent1].[A1]) AS [A1]
            FROM ( SELECT 
                [Extent1].[ProductCategoryID] AS [K1], 
                LEFT([Extent1].[Name], 4) AS [A1]
                FROM [Production].[ProductSubcategory] AS [Extent1]
            )  AS [Extent1]
            GROUP BY [K1]
        )  AS [GroupBy1]
    )  AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Model defined function&lt;/h3&gt;
&lt;p&gt;The following code defines a FormatName function for the Person model:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ModelDefinedFunctions
{
    [ModelDefinedFunction(nameof(FormatName), &quot;EntityFramework.Functions.Tests.Examples&quot;,
        @&quot;(CASE 
            WHEN [Person].[Title] IS NOT NULL
            THEN [Person].[Title] + N&apos; &apos; 
            ELSE N&apos;&apos; 
        END) + [Person].[FirstName] + N&apos; &apos; + [Person].[LastName]&quot;)]
    public static string FormatName(this Person person) =&amp;gt;
        $&quot;{(person.Title == null ? string.Empty : person.Title + &quot; &quot;)}{person.FirstName} {person.LastName}&quot;;

    [ModelDefinedFunction(nameof(ParseDecimal), &quot;EntityFramework.Functions.Tests.Examples&quot;, &quot;cast([Person].[BusinessEntityID] as Decimal(20,8))&quot;)]
    public static decimal ParseDecimal(this Person person) =&amp;gt; Convert.ToDecimal(person.BusinessEntityID);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When FormatName is called in LINQ to Entities query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void ModelDefinedFunctionInLinqTest()
{
    using (AdventureWorks database = new AdventureWorks())
    {
        var employees = from employee in database.Persons
                        where employee.Title != null
                        let formatted = employee.FormatName()
                        select new
                        {
                            formatted,
                            employee
                        };
        var employeeData = employees.Take(1).ToList().FirstOrDefault();
        Assert.IsNotNull(employeeData);
        Assert.IsNotNull(employeeData.formatted);
        Assert.AreEqual(employeeData.employee.FormatName(), employeeData.formatted);
    }

    using (AdventureWorks database = new AdventureWorks())
    {
        var employees = from employee in database.Persons
                        where employee.Title != null
                        select new
                        {
                            Decimal = employee.ParseDecimal(),
                            Int32 = employee.BusinessEntityID
                        };
        var employeeData = employees.Take(1).ToList().FirstOrDefault();
        Assert.IsNotNull(employeeData);
        Assert.AreEqual(employeeData.Decimal, Convert.ToInt32(employeeData.Int32));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The queries are translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[BusinessEntityID] AS [BusinessEntityID], 
    [Limit1].[C1] AS [C1], 
    [Limit1].[Title] AS [Title], 
    [Limit1].[FirstName] AS [FirstName], 
    [Limit1].[LastName] AS [LastName]
    FROM ( SELECT TOP (1) 
        [Extent1].[BusinessEntityID] AS [BusinessEntityID], 
        [Extent1].[Title] AS [Title], 
        [Extent1].[FirstName] AS [FirstName], 
        [Extent1].[LastName] AS [LastName], 
        CASE WHEN ([Extent1].[Title] IS NOT NULL) THEN [Extent1].[Title] + N&apos; &apos; ELSE N&apos;&apos; END + [Extent1].[FirstName] + N&apos; &apos; + [Extent1].[LastName] AS [C1]
        FROM [Person].[Person] AS [Extent1]
        WHERE [Extent1].[Title] IS NOT NULL
    )  AS [Limit1]

SELECT 
    [Limit1].[BusinessEntityID] AS [BusinessEntityID], 
    [Limit1].[C1] AS [C1]
    FROM ( SELECT TOP (1) 
        [Extent1].[BusinessEntityID] AS [BusinessEntityID], 
         CAST( [Extent1].[BusinessEntityID] AS decimal(20,8)) AS [C1]
        FROM [Person].[Person] AS [Extent1]
        WHERE [Extent1].[Title] IS NOT NULL
    )  AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Version history&lt;/h2&gt;
&lt;p&gt;This library adopts the &lt;a href=&quot;http://semver.org/&quot;&gt;http://semver.org&lt;/a&gt; standard for semantic versioning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.0.0: Initial release.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.0.1: Bug fix.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.1.0: &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions/issues/1&quot;&gt;Bug fix&lt;/a&gt;, and shortcut APIs for each function type:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[StoredProcedure]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[TableValuedFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ComposableScalarValuedFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[NonComposableScalarValuedFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[AggregateFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[BuiltInFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[NiladicFunction]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.2.0: Support model defined function with [ModelDefinedFunction].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.3.0: Support entity type and complex type defined in different assembly/namespace. Support table-valued function returning entity type or complex type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.3.1: Fix a &lt;a href=&quot;https://github.com/Dixin/EntityFramework.Functions/commit/00a2212828825d874a502525e2fed52e700954a5#commitcomment-17750617&quot;&gt;regression&lt;/a&gt; causing complex type not working properly with PostgreSQL.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.4.0: Sign assembly with strong named key. Fix minor issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1.5.0: Support .NET Standard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>C# 10 new feature CallerArgumentExpression, argument check and more</title><link>https://dixin.github.io/posts/csharp-10-new-feature-callerargumentexpression-argument-check-and-more/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-10-new-feature-callerargumentexpression-argument-check-and-more/</guid><description>The CallerArgumentExpression has been discussed for years, it was supposed to a part of C# 8.0 but got delayed. Finally this month it is delivered along with C# 10 and .NET 6.</description><pubDate>Sun, 14 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The CallerArgumentExpression has been discussed for years, it was supposed to a part of C# 8.0 but got delayed. Finally this month it is delivered along with C# 10 and .NET 6.&lt;/p&gt;
&lt;h2&gt;CallerArgumentExpressionAttribute and argument compilation&lt;/h2&gt;
&lt;p&gt;In C# 10, [CallerArgumentExpression(parameterName)] can be used to direct the compiler to capture the specified argument’s expression as text. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System.Runtime.CompilerServices;

void Function(int a, TimeSpan b, [CallerArgumentExpression(&quot;a&quot;)] string c = &quot;&quot;, [CallerArgumentExpression(&quot;b&quot;)] string d = &quot;&quot;)
{
    Console.WriteLine($&quot;Called with value {a} from expression &apos;{c}&apos;&quot;);
    Console.WriteLine($&quot;Called with value {b} from expression &apos;{d}&apos;&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling above function, The magic happens at compile time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Function(1, default);
// Compiled to: 
Function(1, default, &quot;1&quot;, &quot;default&quot;);

int x = 1;
TimeSpan y = TimeSpan.Zero;
Function(x, y);
// Compiled to:
Function(x, y, &quot;x&quot;, &quot;y&quot;);

Function(int.Parse(&quot;2&quot;) + 1 + Math.Max(2, 3), TimeSpan.Zero - TimeSpan.MaxValue);
// Compiled to:
Function(int.Parse(&quot;2&quot;) + 1 + Math.Max(2, 3), TimeSpan.Zero - TimeSpan.MaxValue, &quot;int.Parse(\&quot;2\&quot;) + 1 + Math.Max(2, 3)&quot;, &quot;TimeSpan.Zero - TimeSpan.MaxValue&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Function’s parameter c is decorated with [CallerArgumentExpression(&quot;a&quot;)]. So when calling Function, C# compiler will pickup whatever expression passed to a, and use that expression’s text for c. Similarly, whatever expression is used for b, that expression’s text is used for d.&lt;/p&gt;
&lt;h2&gt;Argument check&lt;/h2&gt;
&lt;p&gt;The most useful scenario of this feature is argument check. In the past, a lot of argument check utility methods are created like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Argument
{
    public static void NotNull&amp;lt;T&amp;gt;([NotNull] T? value, string name) where T : class
    {
        if (value is null)
        {
            throw new ArgumentNullException(name);
        }
    }

    public static void NotNullOrWhiteSpace([NotNull] string? value, string name)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.StringCannotBeEmpty, name));
        }
    }

    public static void NotNegative(int value, string name)
    {
        if (value &amp;lt; 0)
        {
            throw new ArgumentOutOfRangeException(name, value, string.Format(CultureInfo.CurrentCulture, Resources.ArgumentCannotBeNegative, name));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So they can be used as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial record Person
{
    public Person(string name, int age, Uri link)
    {
        Argument.NotNullOrWhiteSpace(name, nameof(name));
        Argument.NotNegative(age, nameof(age));
        Argument.NotNull(link, nameof(link));

        this.Name = name;
        this.Age = age;
        this.Link = link.ToString();
    }

    public string Name { get; }
    public int Age { get; }
    public string Link { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is, it is very annoying to pass argument name every time. There are some ways to get rid of manually passing argument name, but these approaches introduces other issues. For example, a lambda expression with closure can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial record Person
{
    public Person(Uri link)
    {
        Argument.NotNull(() =&amp;gt; link);

        this.Link = link.ToString();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this version of NotNull can take a function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Argument
{
    public static void NotNull&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; value)
    {
        if (value() is null)
        {
            throw new ArgumentNullException(GetName(value));
        }
    }

    private static string GetName&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; func)
    {
        // func: () =&amp;gt; arg is compiled to DisplayClass with a field and a method. That method is func.
        object displayClassInstance = func.Target!;
        FieldInfo closure = displayClassInstance.GetType()
            .GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
            .Single();
        return closure.Name;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See my post on &lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;what is closure and how C# compiles closure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lambda expression can be also compiled to expression tree. So NotNull can be implemented to take an expression too (See my post on &lt;a href=&quot;/posts/functional-csharp-function-as-data-and-expression-tree&quot;&gt;what is expression tree and how C# compiles expression tree&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Argument
{
    public static void NotNull&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt; value)
    {
        if (value.Compile().Invoke() is null)
        {
            throw new ArgumentNullException(GetName(value));
        }
    }

    private static string GetName&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt; expression)
    {
        // expression: () =&amp;gt; arg is compiled to DisplayClass with a field. Here expression body is to access DisplayClass instance&apos;s field.
        MemberExpression displayClassInstance = (MemberExpression)expression.Body;
        MemberInfo closure = displayClassInstance.Member;
        return closure.Name;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These approaches introduce the lambda syntax and performance overhead at runtime. And they are extremely fragile too. Now C# 10’s CallerArgumentExpression finally provides a cleaner solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Argument
{
    public static T NotNull&amp;lt;T&amp;gt;([NotNull] this T? value, [CallerArgumentExpression(&quot;value&quot;)] string name = &quot;&quot;)
        where T : class =&amp;gt;
        value is null ? throw new ArgumentNullException(name) : value;

    public static string NotNullOrWhiteSpace([NotNull] this string? value, [CallerArgumentExpression(&quot;value&quot;)] string name = &quot;&quot;) =&amp;gt;
        string.IsNullOrWhiteSpace(value)
            ? throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.StringCannotBeEmpty, name), name)
            : value;

    public static int NotNegative(this int value, [CallerArgumentExpression(&quot;value&quot;)] string name = &quot;&quot;) =&amp;gt;
        value &amp;lt; 0
            ? throw new ArgumentOutOfRangeException(name, value, string.Format(CultureInfo.CurrentCulture, Resources.ArgumentCannotBeNegative, name))
            : value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the argument check can be shorter and fluent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public record Person
{
    public Person(string name, int age, Uri link) =&amp;gt; 
        (this.Name, this.Age, this.Link) = (name.NotNullOrWhiteSpace(), age.NotNegative(), link.NotNull().ToString());
        // Compiled to:
        // this.Name = Argument.NotNullOrWhiteSpace(name, &quot;name&quot;);
        // this.Age = Argument.NotNegative(age, &quot;age&quot;);
        // this.Link = Argument.NotNull(link, &quot;link&quot;).ToString();

    public string Name { get; }
    public int Age { get; }
    public string Link { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The argument name is generated at compile time and there is no performance overhead at runtime at all.&lt;/p&gt;
&lt;h2&gt;Assertion and logging&lt;/h2&gt;
&lt;p&gt;The other useful scenarios could be assertion and logging:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Conditional(&quot;DEBUG&quot;)]
static void Assert(bool condition, [CallerArgumentExpression(&quot;condition&quot;)] string expression = &quot;&quot;)
{
    if (!condition)
    {
        Environment.FailFast($&quot;&apos;{expression}&apos; is false and should be true.&quot;);
    }
}

Assert(y &amp;gt; TimeSpan.Zero);
// Compiled to:
Assert(y &amp;gt; TimeSpan.Zero, &quot;y &amp;gt; TimeSpan.Zero&quot;);

[Conditional(&quot;DEBUG&quot;)]
static void Log&amp;lt;T&amp;gt;(T value, [CallerArgumentExpression(&quot;value&quot;)] string expression = &quot;&quot;)
{
    Trace.WriteLine($&quot;&apos;{expression}&apos; has value &apos;{value}&apos;&quot;);
}

Log(Math.Min(Environment.ProcessorCount, x));
// Compiled to:
Log(Math.Min(Environment.ProcessorCount, x), &quot;Math.Min(Environment.ProcessorCount, x)&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Use for older projects&lt;/h2&gt;
&lt;p&gt;If .NET 6.0 SDK is installed, C# 10 is available, where CallerArgumentExpression can be used targeting to .NET 5 and .NET 6. For older project targeting older .NET or .NET Standard, CallerArgumentExpressionAttribute is not available. Fortunately C# 10 and this feature can still be used with them, as long as .NET 6.0 SDK is installed. Just manually add the CallerArgumentExpressionAttribute class to your project and use it like the built-in attribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#if !NET5_0 &amp;amp;&amp;amp; !NET6_0
namespace System.Runtime.CompilerServices;

/// &amp;lt;summary&amp;gt;
/// Allows capturing of the expressions passed to a method.
/// &amp;lt;/summary&amp;gt;
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref=&quot;T:System.Runtime.CompilerServices.CallerArgumentExpressionAttribute&quot; /&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;parameterName&quot;&amp;gt;The name of the targeted parameter.&amp;lt;/param&amp;gt;
    public CallerArgumentExpressionAttribute(string parameterName) =&amp;gt; this.ParameterName = parameterName;

    /// &amp;lt;summary&amp;gt;
    /// Gets the target parameter name of the &amp;lt;c&amp;gt;CallerArgumentExpression&amp;lt;/c&amp;gt;.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;
    /// The name of the targeted parameter of the &amp;lt;c&amp;gt;CallerArgumentExpression&amp;lt;/c&amp;gt;.
    /// &amp;lt;/returns&amp;gt;
    public string ParameterName { get; }
}
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should be internal so that when this assembly is referenced by another assembly, there won’t conflict with the built-in version of [CallerArgumentExpression]. Then C# 10‘s compiler will pick it up and the above magic will happen.&lt;/p&gt;
</content:encoded></item><item><title>Windows 10 and 11 minimal setup for HDR video playback and streaming</title><link>https://dixin.github.io/posts/windows-10-and-11-minimal-setup-for-hdr-video-playback-and-streaming/</link><guid isPermaLink="true">https://dixin.github.io/posts/windows-10-and-11-minimal-setup-for-hdr-video-playback-and-streaming/</guid><description>On last Black Friday, I purchased a 50-inch 4K HDR10 smart TV with only $150. I use it as monitor for my computer. I didn’t find a walk through tutorial for the whole HDR (High Dynamic Range) setup, s</description><pubDate>Sun, 14 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On last Black Friday, I purchased a 50-inch 4K HDR10 smart TV with only $150. I use it as monitor for my computer. I didn’t find a walk through tutorial for the whole HDR (High Dynamic Range) setup, so here I am sharing the steps.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Graphic card must support HDR. For example:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nvidia GeForce GTX 900, 10 series, 16 series and RTX 20 series, 30 series&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AMD Polaris Series, Vega series, Big Navi series&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Monitor or TV must have the HDR feature, including DP 1.4 or HDMI 2.0 support. Other fancy features, like 10 bit color, FreeSync, G-Sync, etc., are not relevant to HDR.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Video cable must be DP 1.4 or HDMI 2.0 or higher.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows 11 or Windows 10 version 1803 or later.&lt;/li&gt;
&lt;li&gt;Video player must support HDR.&lt;/li&gt;
&lt;li&gt;Video file or stream must be HDR encoded.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Setup TV/monitor&lt;/h2&gt;
&lt;p&gt;Make sure the TV/monitor’s HDMI 2.0/DP 1.4 mode is enabled. “Auto” does not work on my TV. Switching to 2.0 makes it work.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_15.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Windows and graphic card configuration&lt;/h2&gt;
&lt;p&gt;Installing the latest Windows 10 build version 20H2, switch the default power plan from Balanced to High Performance.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Install the latest graphic card driver, switch Output dynamic range from Limited to Full.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And switch to Dynamic range from Limited to Full:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup video player and filter&lt;/h2&gt;
&lt;p&gt;For player, there are many options, like MPC-HC, MPC-BE, MPV, Pot Player, etc. I use MPC-HC (Media Player Classic Home Cinema), because I am used to it for more than a decade. And it is open source &lt;a href=&quot;https://github.com/clsid2/mpc-hc&quot;&gt;https://github.com/clsid2/mpc-hc&lt;/a&gt;. It can be easily installed via winget:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;winget install –id clsid2.mpc-hc&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After trying many things around, I found MadVR works the best and easist for playing normal and HDR videos. It can be installed from official website &lt;a href=&quot;http://madvr.com/&quot;&gt;http://madvr.com/&lt;/a&gt;, or from Chocolatey:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;choco install madvr&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Launch video player, in the options, go to Playback –&amp;gt; Output, for “DirectShow Video” select “madVR” from the dropdown list.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then Go to Internal Filters, click “Video decoder” button, the Properties panel pops up. For “Hardware Decoder to use”, select whatever works for your machine. For my computer, “DXVA2 (copy-back)” and “NVIDIA CUVID” both work.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_26.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then launch madVR settings. You can go to its installation folder (e.g. C:\ProgramData\chocolatey\lib\madvr\tools), launch madHcCtrl.exe. It is luanched and minimized to the system tray. Right click the system tray icon, click “Edit madVR settings” in the menu.&lt;/p&gt;
&lt;p&gt;FIrst, go to devices, find your monitor, and select the correct device type:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to devices –&amp;gt; Your monitor –&amp;gt; properties, select 0-255 for the level, and select the correct color depth.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Windows-10-HDR-and_12389/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you should be able to play HDR video files.&lt;/p&gt;
&lt;p&gt;This article documents the minimal setup for HDR on Windows 10 and Windows 11. There are tons of more madVR settings to tweak if you have time and interest. Please see the following tools and tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gehrleib/MPC-BE-with-madVR&quot;&gt;https://github.com/gehrleib/MPC-BE-with-madVR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://anime.my/tutorials/madvr/&quot;&gt;https://anime.my/tutorials/madvr/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Setup and use CUDA and TensorFlow in Windows Subsystem for Linux 2</title><link>https://dixin.github.io/posts/setup-and-use-cuda-and-tensorflow-in-windows-subsystem-for-linux-2/</link><guid isPermaLink="true">https://dixin.github.io/posts/setup-and-use-cuda-and-tensorflow-in-windows-subsystem-for-linux-2/</guid><description>Table of contents</description><pubDate>Thu, 17 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Table of contents&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Install Windows preview&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install WSL 2 preview&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Nvidia driver preview and CUDA toolkit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run CUDA sample application&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Docker and Nvidia container toolkit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run CUDA containers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Troubleshoot&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run WSL + CUDA + Docker + Jupyter + TensorFlow&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encoding and decoding video with GPU in WSL?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GPU support is &lt;a href=&quot;https://github.com/microsoft/WSL/issues/829&quot;&gt;the most requested feature&lt;/a&gt; in Windows Subsystem for Linux (WSL). It is available in WSL 2.0 through Windows Insiders program. And Nvidia &lt;a href=&quot;https://developer.nvidia.com/blog/announcing-cuda-on-windows-subsystem-for-linux-2/&quot;&gt;CUDA is supported&lt;/a&gt;. The following diagram shows the WDDM model supporting CUDA user mode driver running inside Linux guest:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://developer.nvidia.com/blog/wp-content/uploads/2020/06/wddm-model-supporting-cuda-user-mode-linux-guest-625x352.png&quot; alt=&quot;In the Linux guest, the CUDA user mode library talks to dxgkrnl driver&apos;s /dev/dxg device using IoCtls wrapped with libdxcore API. The dxg requests then get forwarded to the Windows host system using VMBus where for those the host dxgkrnl driver makes calls to the KMD (Kernel Mode Driver) DDI handlers.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So the popular Linux AI frameworks like TensorFlow, PyTorch, etc. can work with WSL with CUDA acceleration:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://developer.nvidia.com/blog/wp-content/uploads/2020/06/WSL-launch-stack-diagram-HR-r4-625x829.png&quot; alt=&quot;The diagram shows Microsoft Windows GPU machines running on the NVIDIA hardware. For the software layers, it shows the Windows kernel, NVIDIA Windows driver, GPU virtualization, WSL2 environment (Linux kernel), NVIDIA CUDA, and other Linux AI frameworks and apps.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This article walks through the installation of Windows, WSL, CUDA in WSL, and Docker in WSL.&lt;/p&gt;
&lt;h2&gt;Install Windows preview&lt;/h2&gt;
&lt;p&gt;First, you must enable “Optional diagnostic data”, otherwise Windows cannot join Windows Insiders.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then, join Windows Insiders program with Microsoft account (an account can be created if you don’t have one: &lt;a href=&quot;https://insider.windows.com/&quot;&gt;https://insider.windows.com/&lt;/a&gt;). The channel must be Dev:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then run Windows Update. It will download the pre=release installer. Windows will restart and reinstall.&lt;/p&gt;
&lt;h2&gt;Install WSL 2 preview&lt;/h2&gt;
&lt;p&gt;In Windows, make sure the following Windows features are enabled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WSL: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart&lt;/li&gt;
&lt;li&gt;Virtual machine platform: dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now restart Windows, then Windows will have WSL and the wsl command line tool. Run Windows Update again to get the latest WSL 2. When this is done, in the update history, it must show 4.19.121 or later:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then manually install this patch: &lt;a href=&quot;https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi&quot;&gt;https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi&lt;/a&gt;. And then run the following command as administrator to update the kernel to the latest version:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\WINDOWS\system32&amp;gt;wsl --update Checking for updates... Downloading updates... Installing updates... This change will take effect on the next full restart of WSL. To force a restart, please run &apos;wsl --shutdown&apos;. Kernel version: 5.4.72&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now go to Microsoft Store, install a Linux distribution. I installed the first one Ubuntu, it is the same as the third item Ubuntu 20.04 LTS&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When the installation is done, use the following command to set the default version to 2 and verify:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\WINDOWS\system32&amp;gt;wsl --set-default-version 2 For information on key differences with WSL 2 please visit &lt;a href=&quot;https://aka.ms/wsl2&quot;&gt;https://aka.ms/wsl2&lt;/a&gt; The operation completed successfully.&lt;/p&gt;
&lt;p&gt;C:\WINDOWS\system32&amp;gt;wsl --list --verbose NAME STATE VERSION * Ubuntu Stopped 2 docker-desktop Stopped 2 docker-desktop-data Stopped 2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;WSL version can also be set for a specific distribution:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\WINDOWS\system32&amp;gt;wsl --set-version ubuntu 2 Conversion in progress, this may take a few minutes... For information on key differences with WSL 2 please visit &lt;a href=&quot;https://aka.ms/wsl2&quot;&gt;https://aka.ms/wsl2&lt;/a&gt; The distribution is already the requested version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now launch the installed Ubuntu (default) from the Store, or using the command wsl:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the first time launch, it asks for initializing the user name and password.&lt;/p&gt;
&lt;h2&gt;Install Nvidia driver preview and CUDA toolkit&lt;/h2&gt;
&lt;p&gt;In Windows, download the preview driver from Nvidia: &lt;a href=&quot;https://developer.nvidia.com/cuda/wsl/download&quot;&gt;https://developer.nvidia.com/cuda/wsl/download&lt;/a&gt; and install.&lt;/p&gt;
&lt;p&gt;Then launch WSL, install CUDA:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;apt-key adv --fetch-keys &lt;a href=&quot;http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub&quot;&gt;http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub&lt;/a&gt; sh -c &apos;echo &quot;deb &lt;a href=&quot;http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64&quot;&gt;http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64&lt;/a&gt; /&quot; &amp;gt; /etc/apt/sources.list.d/cuda.list&apos; apt update apt install -y cuda-toolkit-11-1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Run CUDA sample application&lt;/h3&gt;
&lt;p&gt;The CUDA sample source code can be downloaded from GitHub. In WSL, run:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;git clone &lt;a href=&quot;https://github.com/NVIDIA/cuda-samples.git&quot;&gt;https://github.com/NVIDIA/cuda-samples.git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then build and run a sample application&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd cuda-samples/Samples/concurrentKernels make ./concurrentKernels&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If everything is successful, it should find the GPU and show the test output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[./concurrentKernels] - Starting... GPU Device 0: &quot;Turing&quot; with compute capability 7.5 &amp;gt; Detected Compute SM 7.5 hardware with 20 multi-processors Expected time for serial execution of 8 kernels = 0.080s Expected time for concurrent execution of 8 kernels = 0.010s Measured time for sample = 0.012s Test passed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Install Docker and Nvidia container toolkit&lt;/h2&gt;
&lt;p&gt;First, if Docker Desktop is installed in Windows, turn off the WSL integration for WSL in the distro, because It does not work with CUDA in WSL:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now go to WSL, install Docker from there:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;curl &lt;a href=&quot;https://get.docker.com&quot;&gt;https://get.docker.com&lt;/a&gt; | sh&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then install Nvidia container toolkit in WSL:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L &lt;a href=&quot;https://nvidia.github.io/nvidia-docker/gpgkey&quot;&gt;https://nvidia.github.io/nvidia-docker/gpgkey&lt;/a&gt; | sudo apt-key add - curl -s -L &lt;a href=&quot;https://nvidia.github.io/nvidia-docker/&quot;&gt;https://nvidia.github.io/nvidia-docker/&lt;/a&gt;$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list curl -s -L &lt;a href=&quot;https://nvidia.github.io/libnvidia-container/experimental/&quot;&gt;https://nvidia.github.io/libnvidia-container/experimental/&lt;/a&gt;$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list sudo apt update sudo apt install -y nvidia-docker2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When it is done, restart docker in WSL:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo service docker stop sudo service docker start&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Run CUDA containers&lt;/h3&gt;
&lt;p&gt;Now it is ready to run CUDA container:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It should give output like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPU Device 0: &quot;GeForce GTX 1650 SUPER&quot; with compute capability 7.5 &amp;gt; Compute 7.5 CUDA device: [GeForce GTX 1650 SUPER] 20480 bodies, total time for 10 iterations: 30.007 ms = 139.776 billion interactions per second = 2795.517 single-precision GFLOP/s at 20 flops per interaction&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Troubleshoot&lt;/h3&gt;
&lt;p&gt;Here Windows, WSL 2, Nvidia driver are all in preview. Sometimes when you run container, docker gives error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker: Error response from daemon: cgroups: cannot find cgroup mount destination: unknown. ERRO[0000] error waiting for container: context canceled&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then WSL has to be restarted. In Windows command prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;wsl –shutdown wsl&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If Docker gives the following error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error response from daemon: could not select device driver &quot;&quot; with capabilities: [[gpu]]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then &lt;a href=&quot;https://github.com/NVIDIA/nvidia-docker/issues/1243&quot;&gt;install nvidia-container-toolkit&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo apt install -y nvidia-container-toolkit&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If Docker gives error message:&lt;/p&gt;
&lt;p&gt;Error response from daemon: cgroups: cannot find cgroup mount destination: unknown.&lt;/p&gt;
&lt;p&gt;Then this is &lt;a href=&quot;https://github.com/microsoft/WSL/issues/4189&quot;&gt;the fix&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo mkdir /sys/fs/cgroup/systemd sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Run WSL + CUDA + Docker + Jupyter + TensorFlow&lt;/h2&gt;
&lt;p&gt;Finally, Jupyter notebook can be used in WSL to run popular AI framework code, like TensorFlow. Nvidia’s official tutorial runs TensorFlow with Jupyter notebook in Docker image tensorflow/tensorflow:latest-gpu-py3-jupyter. However, this docker image is no longer updated and gives errors. Now there is another up-to-date image tensorflow/tensorflow:latest-gpu-jupyter. In WSL, run :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker run -it --gpus all -p 8889:8888 tensorflow/tensorflow:latest-gpu-jupyter&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here container’s port 8888 is mapped to WSL’s port 8889, because on Windows I am already running an instance of Jupyter notebook, which already occupies port 8888.&lt;/p&gt;
&lt;p&gt;Dock shows the following messages:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;________ _______________ ___ __/__________________________________ ____/__ /________ __ __ / _ _ \_ __ \_ ___/ __ \_ ___/_ /_ __ /_ __ \_ | /| / / _ / / __/ / / /(__ )/ /_/ / / _ __/ _ / / /_/ /_ |/ |/ / /_/ \___//_/ /_//____/ \____//_/ /_/ /_/ \____/____/|__/&lt;/p&gt;
&lt;p&gt;WARNING: You are running this container as root, which can cause new files in mounted volumes to be created as the root user on your host machine.&lt;/p&gt;
&lt;p&gt;To avoid this, run the container by specifying your user&apos;s userid:&lt;/p&gt;
&lt;p&gt;$ docker run -u $(id -u):$(id -g) args...&lt;/p&gt;
&lt;p&gt;[I 17:15:59.736 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret jupyter_http_over_ws extension initialized. Listening on /http_over_websocket [I 17:15:59.947 NotebookApp] Serving notebooks from local directory: /tf [I 17:15:59.948 NotebookApp] The Jupyter Notebook is running at: [I 17:15:59.948 NotebookApp] &lt;a href=&quot;http://ccd3c60790ab:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&quot;&gt;http://ccd3c60790ab:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&lt;/a&gt; [I 17:15:59.948 NotebookApp] or &lt;a href=&quot;http://127.0.0.1:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&quot;&gt;http://127.0.0.1:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&lt;/a&gt; [I 17:15:59.948 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). [C 17:15:59.953 NotebookApp]&lt;/p&gt;
&lt;p&gt;To access the notebook, open this file in a browser: file:///root/.local/share/jupyter/runtime/nbserver-1-open.html Or copy and paste one of these URLs: &lt;a href=&quot;http://ccd3c60790ab:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&quot;&gt;http://ccd3c60790ab:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&lt;/a&gt; or &lt;a href=&quot;http://127.0.0.1:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&quot;&gt;http://127.0.0.1:8888/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now take the last URI, replace “127.0.0.1:8888” with “localhost:8889”, go to Windows and launch browser, paste the URI: &lt;a href=&quot;http://localhost:8889/?token=8d4c4fda17acc9a58044e14db8f735f64aa49df1ba7a343e&quot;&gt;http://localhost:8889/?token=8b1969bc9a278498fd5debe119feb6d86130850166425bef&lt;/a&gt;, The browser should load the Jupyter notebook with built-in TensorFlow tutorial:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, running the cells in the notebook, it shows some errors. If it shows an error of git not found (“FileNotFoundError: No such file or directory: &apos;git&apos;”), then run these commands in a cell to install git:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;!apt update !apt install -y git&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the python code throws an error “InternalError: Blas GEMM launch failed” or “InternalError: Blas GEMV launch failed”, &lt;a href=&quot;https://stackoverflow.com/questions/43990046/tensorflow-blas-gemm-launch-failed&quot;&gt;the fix&lt;/a&gt; is to run these code:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;#import tensorflow as tf physical_devices = tf.config.list_physical_devices(&apos;GPU&apos;) tf.config.experimental.set_memory_growth(physical_devices[0], True)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The it should work:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/bc58ed1e1573_14C6C/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Encoding and decoding video with GPU in WSL?&lt;/h2&gt;
&lt;p&gt;Not supported yet. To test GPU encoding and decoding, &lt;a href=&quot;https://launchpad.net/~savoury1/+archive/ubuntu/ffmpeg4&quot;&gt;the latest version of FFmpeg&lt;/a&gt; can be installed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo add-apt-repository ppa:savoury1/graphics sudo add-apt-repository ppa:savoury1/multimedia sudo add-apt-repository ppa:savoury1/ffmpeg4 sudo apt-get update sudo apt-get upgrade &amp;amp;&amp;amp; sudo apt-get dist-upgrade sudo apt-get install ffmpeg&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then install the Nvidia encoding/decoding libraries:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo apt install libnvidia-decode-455 sudo apt install libnvidia-encode-455&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now try to use FFmpeg to decode a video and encode it with hevc_nvenc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ffmpeg -hwaccel auto -i input.mkv -map 0:v:0 -map 0:a -map_metadata 0 -loglevel verbose -c:v hevc_nvenc -profile:v main10 -pix_fmt yuv420p10le -preset slow -tune film -b_adapt 2 -b_ref_mode middle -bf 3 -rc vbr_hq -deblock 0:0 -rc-lookahead 25 -rc_lookahead 25 -g 250 -keyint_min 23 -refs 4 -sc_threshold 40 -temporal_aq 1 -spatial_aq 1 -nonref_p 1 -c:a aac -ar 48000 -b:a 256k -ac 6 -b:v 2048k output.nvenc.mp4 –y&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It does not work and gives the following error for decoding the input video:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[h264 @ 0x55c4517dd540] decoder-&amp;gt;cvdl-&amp;gt;cuvidGetDecoderCaps(&amp;amp;caps) failed -&amp;gt; CUDA_ERROR_INVALID_DEVICE: invalid device ordinal [h264 @ 0x55c4517dd540] Failed setup for format cuda: hwaccel initialisation returned error.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it gives the following error for encoding the output video:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[hevc_nvenc @ 0x55c451065b00] OpenEncodeSessionEx failed: unsupported device (2): (no details) [hevc_nvenc @ 0x55c451065b00] Nvenc unloaded Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I searched around and found &lt;a href=&quot;https://forums.developer.nvidia.com/t/building-ffmpeg-with-nvenc-inside-docker-container-in-wsl-2-linux-distro/155102/3&quot;&gt;a video&lt;/a&gt; of WSLConf’s CUDA session, where &lt;a href=&quot;https://www.facebook.com/6723083591/videos/676914529849697/&quot;&gt;Nvidia conforms GPU encoding/decoding is not yet supported in WSL&lt;/a&gt;, and will come in the future:&lt;/p&gt;
</content:encoded></item><item><title>Update code font from Consolas to Cascadia Code with ligature</title><link>https://dixin.github.io/posts/update-code-font-from-consolas-to-cascadia-code-with-ligature/</link><guid isPermaLink="true">https://dixin.github.io/posts/update-code-font-from-consolas-to-cascadia-code-with-ligature/</guid><description>A decade ago, I . They are both monospaced. The difference is:</description><pubDate>Sun, 31 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A decade ago, I &lt;a href=&quot;/posts/blog-code-font-change-from-courier-new-to-consolas&quot;&gt;blogged that I switched my code font from Courier New to Consolas&lt;/a&gt;. They are both monospaced. The difference is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Courier New is an old font introduced in Windows 3.1.&lt;/li&gt;
&lt;li&gt;Consolas is introduced with Windows Vista/Office 2007/Visual Studio 2010. It &lt;a href=&quot;https://devblogs.microsoft.com/visualstudio/visual-studio-2010-text-clarity-cleartype-options/&quot;&gt;always uses ClearType&lt;/a&gt;, which is designed for LCD screens and other flat panels which arrange their pixels in vertical stripes of red, green and blue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After using Consolas for 10+ years, now I am switching code font to Cascadia Code.&lt;/p&gt;
&lt;h2&gt;Cascadia and Windows Terminal&lt;/h2&gt;
&lt;p&gt;A week ago, Widows Terminal 1.0 is released by Microsoft, along with a dedicated Cascadia fonts. Cascadia is &lt;a href=&quot;https://github.com/microsoft/cascadia-code&quot;&gt;open source&lt;/a&gt; and is &lt;a href=&quot;https://twitter.com/cinnamon_msft/status/1130864977185632256&quot;&gt;named&lt;/a&gt; after Widows Terminal’s code name. I personally prefer the name “Seattle”, where I live.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Microsoft actually released 2 Cascadia fonts along with Windows Terminal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cascadia mono: the normal monospaced font&lt;/li&gt;
&lt;li&gt;Cascadia code: the fancy version of Cascadia mono, with programming ligatures&lt;/li&gt;
&lt;li&gt;Cascadia mono PL: Cascadia mono plus powerline symbols&lt;/li&gt;
&lt;li&gt;Cascadia code PL: Cascadia code plus powerline symbols&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are designed by &lt;a href=&quot;https://twitter.com/aaronbell&quot;&gt;Aaron Bell&lt;/a&gt; from &lt;a href=&quot;https://www.sajatypeworks.com/&quot;&gt;Saja Typeworks&lt;/a&gt;. Microsoft &lt;a href=&quot;https://devblogs.microsoft.com/commandline/cascadia-code/&quot;&gt;recommends Cascadia Code&lt;/a&gt; for terminal apps and code editors.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The font design looks good for me, except number 7 and letter f looks inconsistent with others:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Text ligature&lt;/h2&gt;
&lt;p&gt;Ligature means two or more graphemes are joined as a single glyph. The most example is that e and t can be joined as &amp;amp;. The following are examples of joined letters:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Ligatures.svg/300px-Ligatures.svg.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here are some ligatures examples in Unicode (Multiple letters/single ligature/Unicode/HTML):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A E/Æ/U+00C6/Æ&lt;/li&gt;
&lt;li&gt;a e/æ/U+00E6/æ&lt;/li&gt;
&lt;li&gt;O E/Œ/U+0152/Œ&lt;/li&gt;
&lt;li&gt;o e/œ/U+0153/œ&lt;/li&gt;
&lt;li&gt;f f/ﬀ/U+FB00/ﬀ&lt;/li&gt;
&lt;li&gt;f‌ i/ﬁ/U+FB01/ﬁ&lt;/li&gt;
&lt;li&gt;i j/ĳ/U+0133/ĳ&lt;/li&gt;
&lt;li&gt;s t/ﬆ/U+FB06/ﬆ&lt;/li&gt;
&lt;li&gt;f f i/ﬃ/U+FB03/ﬃ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CSS also support ligature with properties font-feature-settings and font-variant-ligatures.&lt;/p&gt;
&lt;p&gt;I used to practice calligraphy in Chinese and English, but personally I am not in favor of ligatures.&lt;/p&gt;
&lt;h3&gt;Code ligature&lt;/h3&gt;
&lt;p&gt;Programing ligature means to join code symbols as a single glyph. For example, in terminal or code editor,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“greater than or equal to” operator &amp;gt;= can be joined as ≥&lt;/li&gt;
&lt;li&gt;“not equal” operator != cam ne joined as ≠&lt;/li&gt;
&lt;li&gt;“double arrow”operator =&amp;gt; can be joined as ⇒&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Recently code ligature become popular because of the &lt;a href=&quot;https://github.com/tonsky/FiraCode&quot;&gt;Fira Code&lt;/a&gt; font based on &lt;a href=&quot;https://github.com/mozilla/Fira&quot;&gt;Fira Mono from Mozilla&lt;/a&gt;, &lt;a href=&quot;https://github.com/larsenwork/monoid&quot;&gt;Monoid font&lt;/a&gt;, &lt;a href=&quot;https://github.com/i-tu/Hasklig&quot;&gt;Hasklig font&lt;/a&gt;, etc. Here is a &lt;a href=&quot;https://betterwebtype.com/articles/2020/02/13/5-monospaced-fonts-with-cool-coding-ligatures/&quot;&gt;detailed comparison&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ligate in programming language is said to improve readability. Personally I do not have a strong preference. There are also &lt;a href=&quot;https://news.ycombinator.com/item?id=19805053&quot;&gt;some people who do not like ligature at all&lt;/a&gt;. In Cascadia Code, the following are some examples of how programming operator characters are joined as ligatures in this font:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;++ -- ** &amp;amp;&amp;amp; !! || %% ;; ?? +++ --- *** www # ## ### #### /= ^= =~ ~- -~ ~~ ~= ~@ ?. #{ #( #_ #_( #[ ]# #? #: #= #! &amp;lt;= &amp;gt;= &amp;lt;&amp;gt; &amp;lt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&amp;gt; == != =/= === !== =!= =:= &amp;lt;== ==&amp;gt; &amp;lt;=&amp;gt; =&amp;gt; &amp;lt;&amp;lt;= =&amp;gt;&amp;gt; &amp;gt;&amp;gt;= =&amp;lt;&amp;lt; &amp;lt;=&amp;lt; &amp;gt;=&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; -&amp;lt; &amp;gt;- &amp;lt;&amp;lt;- -&amp;gt;&amp;gt; &amp;gt;&amp;gt;- -&amp;lt;&amp;lt; &amp;lt;-- --&amp;gt; &amp;lt;- &amp;lt;-&amp;gt; -&amp;gt; &amp;lt;$ &amp;lt;$&amp;gt; $&amp;gt; &amp;lt;+ &amp;lt;+&amp;gt; +&amp;gt; &amp;lt;* &amp;lt;*&amp;gt; *&amp;gt; &amp;lt;~ &amp;lt;~&amp;gt; ~&amp;gt; &amp;lt;/ /&amp;gt; &amp;lt;/&amp;gt; &amp;lt;!-- --&amp;gt; &amp;lt;||| &amp;lt;|| &amp;lt;| &amp;lt;|&amp;gt; |&amp;gt; ||&amp;gt; |||&amp;gt; .. ... :: ::: .- .= := ::= ..&amp;lt; &amp;lt;: :&amp;gt; :&amp;lt; &amp;gt;: __ -| _|_ |- |= ||= [| |] {| |} 0xFF 1x2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Powerline&lt;/h2&gt;
&lt;p&gt;Powerline was a status line plugin for vim. &lt;a href=&quot;https://github.com/microsoft/cascadia-code/issues/10&quot;&gt;Powerline symbols&lt;/a&gt; (U+E0A0 to U+E0A2 and U+E0B0 to U+E0B3) are &lt;a href=&quot;https://en.wikipedia.org/wiki/Private_Use_Areas&quot;&gt;extra box-drawing characters&lt;/a&gt; that could be useful for displaying status.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;U+E0A0 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142523-f9e84e80-bf9e-11e9-838f-e3ae9ebdfe2e.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0A1 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142529-02408980-bf9f-11e9-8dd5-58365099be9d.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0A2 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142537-09679780-bf9f-11e9-820d-c30aea428d14.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0B0 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142612-50558d00-bf9f-11e9-90de-7fe0530c0089.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0B1 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142620-58153180-bf9f-11e9-8d1b-5849849a049d.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0B2 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142626-5f3c3f80-bf9f-11e9-95ba-9900ae8e7aae.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;li&gt;U+E0B3 &lt;img src=&quot;https://user-images.githubusercontent.com/14316954/63142634-67947a80-bf9f-11e9-9452-7022cc85633e.png&quot; alt=&quot;image&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Install and configure&lt;/h3&gt;
&lt;p&gt;Cascadia Code is installed along with Windows Terminal. You can also download and install Cascadia Code PL from official release page: &lt;a href=&quot;https://github.com/microsoft/cascadia-code/releases&quot;&gt;https://github.com/microsoft/cascadia-code/releases&lt;/a&gt;. With chocolatey, it can be installed by: choco install cascadiacodepl. You can also manually install it for Linux etc..&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/Screenshot%20from%202020-05-31%2003-35-25_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/Screenshot%20from%202020-05-31%2003-35-25_thumb.png&quot; alt=&quot;Screenshot from 2020-05-31 03-35-25&quot; title=&quot;Screenshot from 2020-05-31 03-35-25&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Windows Terminal, the default font is Cascadia Mono.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Open settings. In the JSON configuration, under profiles/defaults, add &quot;fontFace&quot;: &quot;Cascadia Code PL&quot;, and save. The terminal instantly becomes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_26.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_12.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To make usage of powerline symbols, you can &lt;a href=&quot;https://github.com/JanDeDobbeleer/oh-my-posh&quot;&gt;install oh-my-posh&lt;/a&gt; for PowerShell, and &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh&quot;&gt;install oh-my-zsh&lt;/a&gt; for WSL then &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/wiki/Themes&quot;&gt;switch the theme to “agnoster”&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Visual Studio, to use Cascadia Code, In Tools/Options, search for font, change it to Cascadia:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_28.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_13.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Visual Studio Code, open File/Preferences/Settings, search for font, and add it to the head:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Tips-for-using-Windows-Terminal_FB67/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then search for ligature, turn it on (&quot;editor.fontLigatures&quot;: true). On Windows, the ligatures will be shown in VS Code. On Ubuntu, you need to restart VS Code.&lt;/p&gt;
</content:encoded></item><item><title>Installing SQL Server 2017/2019 LocalDB and resolve the engine versioning problem</title><link>https://dixin.github.io/posts/installing-sql-server-2017-2019-localdb-and-resolve-the-engine-versioning-problem/</link><guid isPermaLink="true">https://dixin.github.io/posts/installing-sql-server-2017-2019-localdb-and-resolve-the-engine-versioning-problem/</guid><description>SQL Server LocalDB is a minimal SQL Server database engine, it can be installed and used with zero configuration.</description><pubDate>Wed, 29 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SQL Server LocalDB is a minimal SQL Server database engine, it can be installed and used with zero configuration.&lt;/p&gt;
&lt;h2&gt;Get the installer and install&lt;/h2&gt;
&lt;p&gt;SQL Server LocalDB setup file is included in SQL Server Express. SQL Server 2019 can be downloaded from &lt;a href=&quot;https://go.microsoft.com/fwlink/?LinkID=866658&quot;&gt;https://go.microsoft.com/fwlink/?LinkID=866658&lt;/a&gt;, and SQL Server 2017 can be downloaded from: &lt;a href=&quot;https://go.microsoft.com/fwlink/?LinkID=853017&quot;&gt;https://go.microsoft.com/fwlink/?LinkID=853017&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After unzip the downloaded package, please run root\x64\Setup\x64\SQLLOCALDB.MSI to install.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When it is done, code can connect to it with a connection string, or SQL Server Management Studio can be used to manage the databases by connecting to (LocalDB)\MSSQLLocalDB:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_16.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Resolve the engine connectivity/versioning issue&lt;/h2&gt;
&lt;p&gt;After SQL Server LocalDB 2017/2019 is installed, connecting with SSNS may fail with an error:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In command line, trying to manage it with the sqllocaldb command may also fail with an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;D:\ λ sqllocaldb info MSSQLLocalDB&lt;/p&gt;
&lt;p&gt;D:\ λ sqllocaldb info MSSQLLocalDB Printing of LocalDB instance &quot;MSSQLLocalDB&quot; information failed because of the following error: Unexpected error occurred inside a LocalDB instance API method call. See the Windows Application event log for error details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is caused by engine versioning issue, which can be viewed in Windows Event Viewer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LocalDB parent instance version is invalid: MSSQL13E.LOCALDB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Apparently “MSSQL13E” is incorrect. SQL Server 2016 is v13, SQL Server 2017 should be v14, and SQL Server 2019 should be v15. There are 2 ways to fix this:&lt;/p&gt;
&lt;p&gt;The default instance can be deleted and recreated:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sqllocaldb stop mssqllocaldb sqllocaldb delete mssqllocaldb sqllocaldb create MSSQLLocalDB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or the version info can be manually updated in Registry: Computer\HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\UserInstances\{2DD3D445-34C1-4251-B67D-7DFEED432A87}&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just change ParentInstance to MSSQL14E.LOCALDB or MSSQL15E.LOCALDB.&lt;/p&gt;
&lt;p&gt;Then SQL Server LocalDB can be managed by command line or SSMS:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;D:\ λ sqllocaldb info MSSQLLocalDB Name: MSSQLLocalDB Version: 15.0.2000.5 Shared name: Owner: PC\dixin Auto-create: Yes State: Stopped Last start time: 4/28/2020 5:31:14 PM Instance pipe name:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/89ee21b2c263_49AE/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (8) Optimistic Concurrency</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency/</guid><description>Conflicts can occur if the same data is read and changed concurrently. Generally, there are 2  approaches:</description><pubDate>Tue, 15 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Conflicts can occur if the same data is read and changed concurrently. Generally, there are 2 &lt;a href=&quot;https://en.wikipedia.org/wiki/Concurrency_control&quot;&gt;concurrency control&lt;/a&gt; approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pessimistic concurrency: one database client can lock the data being accessed, in order to prevent other database clients to change that same data concurrently.&lt;/li&gt;
&lt;li&gt;Optimistic concurrency: Data is not locked in the database for client to CRUD. Any database client is allowed to read and change any data concurrently. As a result, concurrency conflicts can happen. This is how EF/Core work with database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate the behavior of EF/Core for concurrency, the following DbReaderWriter type is defined as database CRUD client:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter : IDisposable
{
    private readonly DbContext context;

    internal DbReaderWriter(DbContext context) =&amp;gt; this.context = context;

    internal TEntity Read&amp;lt;TEntity&amp;gt;(params object[] keys) where TEntity : class =&amp;gt; 
        this.context.Set&amp;lt;TEntity&amp;gt;().Find(keys);

    internal int Write(Action change)
    {
        change();
        return this.context.SaveChanges();
    }

    internal DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class =&amp;gt; this.context.Set&amp;lt;TEntity&amp;gt;();

    public void Dispose() =&amp;gt; this.context.Dispose();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple DbReaderWriter instances can be be used to read and write data concurrently. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Concurrency
{
    internal static void NoCheck(
        DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
    {
        int id = 1;
        ProductCategory categoryCopy1 = readerWriter1.Read&amp;lt;ProductCategory&amp;gt;(id);
        ProductCategory categoryCopy2 = readerWriter2.Read&amp;lt;ProductCategory&amp;gt;(id);

        readerWriter1.Write(() =&amp;gt; categoryCopy1.Name = nameof(readerWriter1));
        // exec sp_executesql N&apos;SET NOCOUNT ON;
        // UPDATE [Production].[ProductCategory] SET [Name] = @p0
        // WHERE [ProductCategoryID] = @p1;
        // SELECT @@ROWCOUNT;
        // &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter1&apos;
        readerWriter2.Write(() =&amp;gt; categoryCopy2.Name = nameof(readerWriter2)); // Last client wins.
        // exec sp_executesql N&apos;SET NOCOUNT ON;
        // UPDATE [Production].[ProductCategory] SET [Name] = @p0
        // WHERE [ProductCategoryID] = @p1;
        // SELECT @@ROWCOUNT;
        // &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter2&apos;

        ProductCategory category3 = readerWriter3.Read&amp;lt;ProductCategory&amp;gt;(id);
        category3.Name.WriteLine(); // readerWriter2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, multiple DbReaderWriter instances read and write data concurrently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads category “Bikes”&lt;/li&gt;
&lt;li&gt;readerWriter2 reads category “Bikes”. These 2 entities are independent because they are are from different DbContext instances.&lt;/li&gt;
&lt;li&gt;readerWriter1 updates category’s name from “Bikes” to “readerWriter1”. As previously discussed, by default EF/Core locate the category with its primary key.&lt;/li&gt;
&lt;li&gt;In database, this category’s name is no longer “Bikes”&lt;/li&gt;
&lt;li&gt;readerWriter2 updates category’s name from “Bikes” to “readerWriter2”. It locates the category with its primary key as well. The primary key is unchanged, so the same category can be located and the name can be changed.&lt;/li&gt;
&lt;li&gt;So later when readerWriter3 reads the entity with the same primary key, the category entity’s Name is “readerWriter2”.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Detect Concurrency conflicts&lt;/h2&gt;
&lt;p&gt;Concurrency conflicts can be detected by checking entities’ property values besides primary keys. To required EF/Core to check a certain property, just add a System.ComponentModel.DataAnnotations.ConcurrencyCheckAttribute to it. Remember when defining ProductPhoto entity, its ModifiedDate has a [ConcurrencyCheck] attribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductPhoto
{
    [ConcurrencyCheck]
    public DateTime ModifiedDate { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This property is also called the concurrency token. When EF/Core translate changes of a photo, ModifiedDate property is checked along with the primary key to locate the photo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcurrencyCheck(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)
{
    int id = 1;
    ProductPhoto photoCopy1 = readerWriter1.Read&amp;lt;ProductPhoto&amp;gt;(id);
    ProductPhoto photoCopy2 = readerWriter2.Read&amp;lt;ProductPhoto&amp;gt;(id);

    readerWriter1.Write(() =&amp;gt;
    {
        photoCopy1.LargePhotoFileName = nameof(readerWriter1);
        photoCopy1.ModifiedDate = DateTime.Now;
    });
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
    // WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter1&apos;,@p1=&apos;2017-01-25 22:04:25.9292433&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
    readerWriter2.Write(() =&amp;gt;
    {
        photoCopy2.LargePhotoFileName = nameof(readerWriter2);
        photoCopy2.ModifiedDate = DateTime.Now;
    });
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
    // WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter2&apos;,@p1=&apos;2017-01-25 22:04:59.1792263&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the translated SQL statement, the WHERE clause contains primary key and the original concurrency token. The following is how EF/Core check the concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter2 reads the same photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter1 locates the photo with primary key and original modified date, and update its large photo file name and modified date.&lt;/li&gt;
&lt;li&gt;In database the photo’s modified date is no longer the original value “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter2 tries to locate the photo with primary key and original modified date. However the provided modified date is outdated. EF/Core detect that 0 row is updated by the translated SQL, and throws DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See &lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkId=527962&quot;&gt;http://go.microsoft.com/fwlink/?LinkId=527962&lt;/a&gt; for information on understanding and handling optimistic concurrency exceptions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another option for concurrency check is System.ComponentModel.DataAnnotations.TimestampAttribute. It can only be used for a byte[] property, which is mapped from a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms182776.aspx&quot;&gt;rowversion&lt;/a&gt; (timestamp) column. For SQL database, these 2 terms, rowversion and timestamp, are the same thing. timestamp is just a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms177566.aspx&quot;&gt;synonym&lt;/a&gt; of rowversion data type. A row’s non-nullable rowversion column is a 8 bytes (binary(8)) counter maintained by database, its value increases for each change of the row.&lt;/p&gt;
&lt;p&gt;Microsoft’s AdventureWorks sample database does not have such a rowversion column, so create one for the Production.Product table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER TABLE [Production].[Product] ADD [RowVersion] rowversion NOT NULL
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then define the mapping property for Product entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Timestamp]
    public byte[] RowVersion { get; set; }

    [NotMapped]
    public string RowVersionString =&amp;gt;
        $&quot;0x{BitConverter.ToUInt64(this.RowVersion.Reverse().ToArray(), 0).ToString(&quot;X16&quot;)}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now RowVersion property is the concurrency token. Regarding database automatically increases the RowVersion value, Rowversion also has the [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute. The other RowVersionString property returns a readable representation of the byte array returned by RowVersion. It is not a part of the object-relational mapping, so it has a [NotMapped] attribute. The following example updates and and deletes the same product concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RowVersion(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)
{
    int id = 995;
    Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
    productCopy1.RowVersionString.WriteLine(); // 0x0000000000000803

    Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
    productCopy2.RowVersionString.WriteLine(); // 0x0000000000000803

    readerWriter1.Write(() =&amp;gt; productCopy1.Name = nameof(readerWriter1));
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[Product] SET [Name] = @p0
    // WHERE [ProductID] = @p1 AND [RowVersion] = @p2;
    // SELECT [RowVersion]
    // FROM [Production].[Product]
    // WHERE @@ROWCOUNT = 1 AND [ProductID] = @p1;
    // &apos;,N&apos;@p1 int,@p0 nvarchar(50),@p2 varbinary(8)&apos;,@p1=995,@p0=N&apos;readerWriter1&apos;,@p2=0x0000000000000803
    productCopy1.RowVersionString.WriteLine(); // 0x00000000000324B1
    readerWriter2.Write(() =&amp;gt; readerWriter2.Set&amp;lt;Product&amp;gt;().Remove(productCopy2));
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // DELETE FROM [Production].[Product]
    // WHERE [ProductID] = @p0 AND [RowVersion] = @p1;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p0 int,@p1 varbinary(8)&apos;,@p0=995,@p1=0x0000000000000803
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When updating and deleting photo entities, its auto generated RowVersion property value is checked too. So this is how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads product with primary key 995 and row version 0x0000000000000803&lt;/li&gt;
&lt;li&gt;readerWriter2 reads product with the same primary key 995 and row version 0x0000000000000803&lt;/li&gt;
&lt;li&gt;readerWriter1 locates the photo with primary key and original row version, and update its name. Database automatically increases the photo’s row version. Since the row version is specified as [DatabaseGenerated(DatabaseGeneratedOption.Computed)], EF/Core also locate the photo with the primary key to query the increased row version, and update the entity at client side.&lt;/li&gt;
&lt;li&gt;In database the product’s row version is no longer 0x0000000000000803.&lt;/li&gt;
&lt;li&gt;Then readerWriter2 tries to locate the product with primary key and original row version, and delete it. No product can be found with outdated row version, EF/Core detect that 0 row is deleted, and throws DbUpdateConcurrencyException.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Resolve concurrency conflicts&lt;/h2&gt;
&lt;p&gt;DbUpdateConcurrencyException is thrown when SaveChanges detects concurrency conflict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore
{
    public class DbUpdateException : Exception
    {
        public virtual IReadOnlyList&amp;lt;EntityEntry&amp;gt; Entries { get; }

        // Other members.
    }

    public class DbUpdateConcurrencyException : DbUpdateException
    {
        // Members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inherited from DbUpdateException, DbUpdateConcurrencyException has an Entries property. Entries returns a sequence of EntityEntry instances, representing the conflicting entities’ tracking information. The basic idea of resolving concurrency conflicts, is to handle DbUpdateConcurrencyException and retry SaveChanges:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int Write(Action change, Action&amp;lt;DbUpdateConcurrencyException&amp;gt; handleException, int retryCount = 3)
    {
        change();
        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return this.context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception)
            {
                handleException(exception);
            }
        }
        return this.context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above Write overload, if SaveChanges throws DbUpdateConcurrencyException, the handleException function is called. This function is expected to handle the exception and resolve the conflicts properly. Then SaveChanges is called again. If the last retry of SaveChanges still throws DbUpdateConcurrencyException, the exception is thrown to the caller.&lt;/p&gt;
&lt;h3&gt;Retain database values (database wins)&lt;/h3&gt;
&lt;p&gt;Similar to previous examples, the following example has multiple DbReaderWriter instances to update a product concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UpdateProduct(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3,
    Action&amp;lt;EntityEntry&amp;gt; resolveConflicts)
{
    int id = 950;
    Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
    Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);

    readerWriter1.Write(() =&amp;gt;
    {
        productCopy1.Name = nameof(readerWriter1);
        productCopy1.ListPrice = 100.0000M;
    });
    readerWriter2.Write(
        change: () =&amp;gt;
        {
            productCopy2.Name = nameof(readerWriter2);
            productCopy2.ProductSubcategoryID = 1;
        },
        handleException: exception =&amp;gt;
        {
            EntityEntry tracking = exception.Entries.Single();
            Product original = (Product)tracking.OriginalValues.ToObject();
            Product current = (Product)tracking.CurrentValues.ToObject();
            Product database = productCopy1; // Values saved in database.
            $&quot;Original:  ({original.Name},   {original.ListPrice}, {original.ProductSubcategoryID}, {original.RowVersionString})&quot;
                        .WriteLine();
            $&quot;Database:  ({database.Name}, {database.ListPrice}, {database.ProductSubcategoryID}, {database.RowVersionString})&quot;
                .WriteLine();
            $&quot;Update to: ({current.Name}, {current.ListPrice}, {current.ProductSubcategoryID})&quot;
                .WriteLine();

            resolveConflicts(tracking);
        });

    Product resolved = readerWriter3.Read&amp;lt;Product&amp;gt;(id);
    $&quot;Resolved:  ({resolved.Name}, {resolved.ListPrice}, {resolved.ProductSubcategoryID}, {resolved.RowVersionString})&quot;
        .WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how it works with concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads product with primary key 950, and RowVersion 0x00000000000007D1&lt;/li&gt;
&lt;li&gt;readerWriter2 reads product with the same primary key 950, and RowVersion 0x00000000000007D1&lt;/li&gt;
&lt;li&gt;readerWriter1 locates product with primary key and original RowVersion 0x00000000000007D1, and updates product’s name and list price. Database automatically increases the product’s row version&lt;/li&gt;
&lt;li&gt;In database the product’s row version is no longer 0x00000000000007D1.&lt;/li&gt;
&lt;li&gt;readerWriter2 tries to locate product with primary key and original RowVersion, and update product’s name and subcategory.&lt;/li&gt;
&lt;li&gt;readerWriter2 fails to update product, because it cannot locate the product with original RowVersion 0x00000000000007D1. Again, no product can be found with outdated row version, DbUpdateConcurrencyException is thrown.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a result, the handleException function specified for readWriter2 is called, it retrieves the conflicting product’s tracking information from DbUpdateConcurrencyException.Entries, and logs these information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;product’s original property values read by readerWriter2 before the changes&lt;/li&gt;
&lt;li&gt;product’s property values in database at this moment, which are already updated readerWriter1&lt;/li&gt;
&lt;li&gt;product’s current property values after changes, which readerWriter2 fails to save to database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then handleException calls resolveConflicts function to actually resolve the conflict. Then readerWriter2 retries to save the product changes again. This time, SaveChanges should succeed, because there is no conflicts anymore (In this example, there are only 2 database clients reading/writing data concurrently. In reality, the concurrency can be higher, an appropriate retry count or retry strategy should be specified.). Eventually, readerWriter3 reads the product from database, verify its property values.&lt;/p&gt;
&lt;p&gt;There are several options to implement the resolveConflicts function to resolves the conflicts. One simple option, called “database wins”, is to simply give up the client update, and let database retain whatever values it has for that entity. This seems to be easy to just catch DbUpdateConcurrencyException and do nothing, then database naturally wins, and retains its values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int WriteDatabaseWins(Action change)
    {
        change();
        try
        {
            return this.context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            return 0; // this.context is in a corrupted state.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this way leaves the DbContext, the conflicting entity, and the entity’s tracking information in a corrupted state. For the caller, since the change saving is done, the entity’s property values should be in sync with database values, but the values are actually out of sync and still conflicting. Also, the entity has a tracking state Modified after change saving is done. So the safe approach is to reload and refresh the entity’s values and tracking information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DatabaseWins(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True

        tracking.Reload(); // Execute query.

        tracking.State.WriteLine(); // Unchanged
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // False
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UpdateProduct is called with a resolveConflicts function, which resolves the conflict by calling Reload method on the EntityEntry instance representing the conflicting product’s tracking information:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EntityEntry.Reload executes a SELECT statement to read the product’s property values from database, then refresh the product entity and all tracking information. The product’s property values, the tracked original property values before changes, the tracked current property values after changes, are all refreshed to the queried database values. The entity tracking state is also refreshed to Unchanged.&lt;/li&gt;
&lt;li&gt;At this moment, product has the same tracked original values and current values, as if it is just initially read from database, without changes.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, no changed entity is detected. SaveChanges succeeds without executing any SQL, and returns 0. As expected, readerWriter2 does not update any value to database, and all values in database are retained.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrtier1.&lt;/p&gt;
&lt;h3&gt;Overwrite database values (client wins)&lt;/h3&gt;
&lt;p&gt;Another simple option, called “client wins”, is to disregard values in database, and overwrite them with whatever data submitted from client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ClientWins(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        PropertyValues databaseValues = tracking.GetDatabaseValues();
        // Refresh original values, which go to WHERE clause of UPDATE statement.
        tracking.OriginalValues.SetValues(databaseValues);

        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036336)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter2, 256.4900, 1, 0x0000000000036337)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same conflict is resolved differently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version. This call does not impact the product values or tracking information.&lt;/li&gt;
&lt;li&gt;Manually set the tracked original property values to the queried database values. The entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product properties are tracked as modified.&lt;/li&gt;
&lt;li&gt;At this moment, the product has tracked original values updated, and keeps all tracked current values, as if it is read from database after readerWriter1 updates the name and list price, and then have all properties values changed.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. So EF/Core translate the product change to a UPDATE statement. In the SET clause, since there are 3 properties tracked as modified, 3 columns are set. In the WHERE clause, to locate the product, the tracked original row version has been set to the updated value from database. This time product can be located, and all 3 properties are updated. SaveChanges succeeds and returns 1. As expected, readerWriter2 updates all value to database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrter2.&lt;/p&gt;
&lt;h3&gt;Merge with database values&lt;/h3&gt;
&lt;p&gt;A more complex but useful option, is to merge the client values and database values. For each property:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If original value is different from database value, which means database value is already updated by other concurrent client, then give up updating this property, and retain the database value&lt;/li&gt;
&lt;li&gt;If original value is the same as database value, which means no concurrency conflict for this property, then process normally to submit the change&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeClientAndDatabase(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute query.
        PropertyValues originalValues = tracking.OriginalValues.Clone();
        // Refresh original values, which go to WHERE clause.
        tracking.OriginalValues.SetValues(databaseValues);
        // If database has an different value for a property, then retain the database value.
#if EF
        databaseValues.PropertyNames // Navigation properties are not included.
            .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
            .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
        databaseValues.Properties // Navigation properties are not included.
            .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
            .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036338)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter1, 100.0000, 1, 0x0000000000036339)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Again, EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version.&lt;/li&gt;
&lt;li&gt;Backup tracked original values, then refresh conflict.OriginalValues to the database values, so that these values can go to the translated WHERE clause. Again, the entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product values are tracked as modified and should go to SET clause.&lt;/li&gt;
&lt;li&gt;For each property, if the backed original value is different from the database value, it means this property is changed by other client and there is concurrency conflict. In this case, revert this property’s tracking status to unmodified. The name and list price are reverted.&lt;/li&gt;
&lt;li&gt;At this moment, the product has tracked original values updated, and only keeps tracked current value of subcategory, as if it is read from database after readerWriter1 updates the name and list price, and then only have subcategory changed, which has no conflict.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. Here only subcategory is updated to database. SaveChanges succeeds and returns 1. As expected, readerWriter2 only updates value without conflict, the other conflicted values are retained.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product, product has name and list price values updated by readerWrtier1, and has subcategory updated by readerWriter2.&lt;/p&gt;
&lt;h2&gt;Save changes with concurrency conflict handling&lt;/h2&gt;
&lt;p&gt;Similar to above DbReaderWriter.Write method, a general SaveChanges extension method for DbContext can be defined to handle concurrency conflicts and apply simple retry logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                resolveConflicts(exception.Entries);
            }
        }
        return context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To apply custom retry logic, Microsoft provides EnterpriseLibrary.TransientFaultHandling NuGet package (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn440728.aspx&quot;&gt;Exception Handling Application Block&lt;/a&gt;) for .NET Framework. It has been ported to .NET Core for this tutorial, as EnterpriseLibrary.TransientFaultHandling.Core NuGet package. can be used. With this library, a SaveChanges overload with customizable retry logic can be easily defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TransientDetection&amp;lt;TException&amp;gt; : ITransientErrorDetectionStrategy
    where TException : Exception
{
    public bool IsTransient(Exception ex) =&amp;gt; ex is TException;
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, RetryStrategy retryStrategy)
    {
        RetryPolicy retryPolicy = new RetryPolicy(
            errorDetectionStrategy: new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(),
            retryStrategy: retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt;
            resolveConflicts(((DbUpdateConcurrencyException)e.LastException).Entries);
        return retryPolicy.ExecuteAction(context.SaveChanges);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ITransientErrorDetectionStrategy is the contract to detect each exception, and determine whether the exception is transient and the operation should be retried. Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryStrategy is the contract of retry logic. Then Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy executes the operation with the specified exception detection, exception handling, and retry logic.&lt;/p&gt;
&lt;p&gt;As discussed above, to resolve a concurrency conflict, the entity and its tracking information need to be refreshed. So the more specific SaveChanges overloads can be implemented by applying refresh for each conflict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum RefreshConflict
{
    StoreWins,

    ClientWins,

    MergeClientAndStore
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        return context.SaveChanges(
            conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryCount);
    }

    public static int SaveChanges(
        this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =&amp;gt;
            context.SaveChanges(
                conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryStrategy);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A RefreshConflict enumeration has to be defined with 3 members to represent the 3 options discussed above: database wins, client wind, merge client and database.. And here the Refresh method is an extension method for EntityEntry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static EntityEntry Refresh(this EntityEntry tracking, RefreshConflict refreshMode)
{
    switch (refreshMode)
    {
        case RefreshConflict.StoreWins:
        {
            // When entity is already deleted in database, Reload sets tracking state to Detached.
            // When entity is already updated in database, Reload sets tracking state to Unchanged.
            tracking.Reload(); // Execute SELECT.
            // Hereafter, SaveChanges ignores this entity.
            break;
        }
        case RefreshConflict.ClientWins:
        {
            PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
            if (databaseValues == null)
            {
                // When entity is already deleted in database, there is nothing for client to win against.
                // Manually set tracking state to Detached.
                tracking.State = EntityState.Detached;
                // Hereafter, SaveChanges ignores this entity.
            }
            else
            {
                // When entity is already updated in database, refresh original values, which go to in WHERE clause.
                tracking.OriginalValues.SetValues(databaseValues);
                // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
            }
            break;
        }
        case RefreshConflict.MergeClientAndStore:
        {
            PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
            if (databaseValues == null)
            {
                // When entity is already deleted in database, there is nothing for client to merge with.
                // Manually set tracking state to Detached.
                tracking.State = EntityState.Detached;
                // Hereafter, SaveChanges ignores this entity.
            }
            else
            {
                // When entity is already updated, refresh original values, which go to WHERE clause.
                PropertyValues originalValues = tracking.OriginalValues.Clone();
                tracking.OriginalValues.SetValues(databaseValues);
                // If database has an different value for a property, then retain the database value.
#if EF
                databaseValues.PropertyNames // Navigation properties are not included.
                    .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
                databaseValues.Properties // Navigation properties are not included.
                    .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
                    .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
                // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
            }
            break;
        }
    }
    return tracking;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF already provides a System.Data.Entity.Core.Objects.RefreshMode enumeration, but it only has 2 members: StoreWins and ClientWins.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This Refresh extension method covers the update conflicts discussed above, as well as deletion conflicts. Now the these SaveChanges extension methods can be used to manage concurrency conflicts easily. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveChanges(AdventureWorks adventureWorks1, AdventureWorks adventureWorks2)
{
    int id = 950;
    Product productCopy1 = adventureWorks1.Products.Find(id);
    Product productCopy2 = adventureWorks2.Products.Find(id);

    productCopy1.Name = nameof(adventureWorks1);
    productCopy1.ListPrice = 100;
    adventureWorks1.SaveChanges();

    productCopy2.Name = nameof(adventureWorks2);
    productCopy2.ProductSubcategoryID = 1;
    adventureWorks2.SaveChanges(RefreshConflict.MergeClientAndStore);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (7) Data Changes and Transactions</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions/</guid><description>Besides LINQ to Entities queries, EF Core also provides rich APIs for data changes, with imperative paradigm.</description><pubDate>Mon, 14 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Besides LINQ to Entities queries, EF Core also provides rich APIs for data changes, with imperative paradigm.&lt;/p&gt;
&lt;h2&gt;Repository pattern and unit of work pattern&lt;/h2&gt;
&lt;p&gt;In EF Core, DbSet&amp;lt;T&amp;gt; implements repository pattern. Repositories can centralize data access for applications, and connect between the data source and the business logic. A DbSet&amp;lt;T&amp;gt; instance can be mapped to a database table, which is a repository for data CRUD (create, read, update and delete):&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class DbSet&amp;lt;TEntity&amp;gt; : IQueryable&amp;lt;TEntity&amp;gt; // Other interfaces.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TEntity : class
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual TEntity Find(params object[] keyValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual EntityEntry&amp;lt;TEntity&amp;gt; Add(TEntity entity);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void AddRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual EntityEntry&amp;lt;TEntity&amp;gt; Remove(TEntity entity);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void RemoveRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt;, so that DbSet&amp;lt;T&amp;gt; can represent the data source to read from. DbSet&amp;lt;T&amp;gt;.Find is also provided to read entity by the primary keys. After reading, the retrieved data can be changed. Add and AddRange methods track the specified entities as to be created in the repository. Remove and RemoveRange methods track the specified entities as to be deleted in the repository.&lt;/p&gt;
&lt;p&gt;As fore mentioned, a unit of work is a collection of data operations that should together or fail together as a unit. DbContext implements unit of work pattern:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class DbContext : IDisposable, IInfrastructure&amp;lt;IServiceProvider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ChangeTracker ChangeTracker { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual int SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As the mapping of database, DbContext’s Set method returns the specified entity’s repositories. For example, calling AdventureWorks.Products is equivalent to calling AdventureWorks.Set&amp;lt;Product&amp;gt;. The entities tracking is done at the DbContext level, by its ChangeTracker. When DbContext.Submit is called, the tracked changes are submitted to database. When a unit of work is done, DbContext should be disposed.&lt;/p&gt;
&lt;h2&gt;Track entities and changes&lt;/h2&gt;
&lt;p&gt;DbContext.ChangeTracker property returns Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker, which can track entities for the source DbContext:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class ChangeTracker : IInfrastructure&amp;lt;IStateManager&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IEnumerable&amp;lt;EntityEntry&amp;gt; Entries();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IEnumerable&amp;lt;EntityEntry&amp;lt;TEntity&amp;gt;&amp;gt; Entries&amp;lt;TEntity&amp;gt;() where TEntity : class;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void DetectChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual bool HasChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Each entity’s loading and tracking information is represented by Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry or Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry&amp;lt;TEntity&amp;gt;. The following is the non generic EntityEntry:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class EntityEntry : IInfrastructure&amp;lt;InternalEntityEntry&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual EntityState State { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual object Entity { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual PropertyEntry Property(string propertyName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual PropertyValues CurrentValues { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual PropertyValues OriginalValues { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual PropertyValues GetDatabaseValues();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void Reload();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides the loading information APIs discussed in previous part, EntityEntry also provides rich APIs for entity’s tracking information and state management:&lt;/p&gt;
&lt;p&gt;· State returns the entity’s tracking state: Detached, Unchanged, Added, Deleted, or Modified.&lt;/p&gt;
&lt;p&gt;· Entity property returns the tracked entity&lt;/p&gt;
&lt;p&gt;· Property returns the specified property’s tracking information.&lt;/p&gt;
&lt;p&gt;· CurrentValues returns the tracked entity’s current property values.&lt;/p&gt;
&lt;p&gt;· OriginalValues returns the tracked entity’s original property values&lt;/p&gt;
&lt;p&gt;· GetDatabaseValues instantly execute a SQL query to read entity’s property values from database, without updating current entity’s property values and tracking information.&lt;/p&gt;
&lt;p&gt;· Reload also executes a SQL query to read the database values, and also update current entity’s property values, and all tracking information&lt;/p&gt;
&lt;p&gt;The generic EntityEntry&amp;lt;TEntity&amp;gt; is just stronger typing:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class EntityEntry&amp;lt;TEntity&amp;gt; : EntityEntry where TEntity : class
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual TEntity Entity { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned in data loading part, DbContext.Entry also accepts an entity and return its EntityEntry&amp;lt;TEntity&amp;gt;/EntityEntry.&lt;/p&gt;
&lt;h3&gt;Track entities&lt;/h3&gt;
&lt;p&gt;By default, all entities read from repositories are tracked by the source DbContext. For example:&lt;/p&gt;
&lt;p&gt;internal static void EntitiesFromSameDbContext(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productById = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(product =&amp;gt; product.ProductID == 999);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productByName = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(productById, productByName).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The single result from the first LINQ to Entities query is tracked by DbContext. Later, the second query has a single result too. EF Core identifies both results map to the same data row of the same table, so they are reference to the same entity instance.&lt;/p&gt;
&lt;p&gt;If data from repositories are not entities mapping to table rows, they cannot be tracked:&lt;/p&gt;
&lt;p&gt;internal static void ObjectsFromSameDbContext(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var productById = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(product =&amp;gt; product.ProductID == 999);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var productByName = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(productById, productByName).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here data is queries from repositories, and anonymous type instances are constructed on the fly. EF Core cannot decide if 2 arbitrary instances semantically represent the same piece of data in remote database. This time 2 query results are independent from each other.&lt;/p&gt;
&lt;p&gt;Since the tracking is at DbContext scope. Entities of different DbContext instances belong to different units of work, and do not interfere each other:&lt;/p&gt;
&lt;p&gt;internal static void EntitiesFromMultipleDbContexts()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productById;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productByName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productById = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productByName = adventureWorks.Products.Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(productById, productByName).WriteLine(); // False.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Track entity changes and property changes&lt;/h3&gt;
&lt;p&gt;The following example demonstrate CRUD operations in the product repository, then examine all the tracking information:&lt;/p&gt;
&lt;p&gt;internal static void EntityChanges(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product create = new Product() { Name = nameof(create), ListPrice = 1 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Products.Add(create); // Create locally.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product read = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999); // Read from remote to local.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; update = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; product.Name.Contains(&quot;HL&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;update.ForEach(product =&amp;gt; product.ListPrice += 100); // Update locally.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; delete = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; product.Name.Contains(&quot;ML&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Products.RemoveRange(delete); // Delete locally.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.HasChanges().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product changed = tracking.Entity;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (tracking.State)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case EntityState.Added:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case EntityState.Deleted:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case EntityState.Unchanged:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{tracking.State}: {(changed.ProductID, changed.Name, changed.ListPrice)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case EntityState.Modified:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product original = (Product)tracking.OriginalValues.ToObject();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{tracking.State}: {(original.ProductID, original.Name, original.ListPrice)} =&amp;gt; {(changed.ProductID, changed.Name, changed.ListPrice)}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Added: (-2147482647, toCreate, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Unchanged: (999, Road-750 Black, 52, 539.9900)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Modified: (951, HL Crankset, 404.9900) =&amp;gt; (951, HL Crankset, 504.9900)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Modified: (996, HL Bottom Bracket, 121.4900) =&amp;gt; (996, HL Bottom Bracket, 221.4900)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Deleted: (950, ML Crankset, 256.4900)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Deleted: (995, ML Bottom Bracket, 101.2400)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If an entity is not read from a DbContext instance’s repositories, then it has nothing to do with that unit of work, and apparently is not tracked by that DbContext instance. DbSet&amp;lt;T&amp;gt; provides an Attach method to place an entity to the repository, and the DbContext tracks the entity as the Unchanged state:&lt;/p&gt;
&lt;p&gt;internal static void Attach(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product product = new Product() { ProductID = 950, Name = &quot;ML Crankset&quot;, ListPrice = 539.99M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Products.Attach(product);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;product.Name = &quot;After attaching&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State.WriteLine(); // Modified
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().WriteLines(tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{tracking.State}: {tracking.OriginalValues[nameof(Product.Name)]} =&amp;gt; {tracking.CurrentValues[nameof(Product.Name)]}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Modified: ML Crankset =&amp;gt; After attaching
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Track relationship changes&lt;/h3&gt;
&lt;p&gt;The relationship of entities is also tracked. Remember Product’s foreign key ProductSubcategoryID is nullable. The following example reads a subcategory and its products, then delete the relationship. As a result, each navigation property is cleared to empty collection or null. And each related subcategory’s foreign key property value is synced to null, which is tracked:&lt;/p&gt;
&lt;p&gt;internal static void RelationshipChanges(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Include(entity =&amp;gt; entity.Products).Single(entity =&amp;gt; entity.ProductSubcategoryID == 8);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products.Count.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.All(product =&amp;gt; product.ProductSubcategory == subcategory).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products.Clear();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to: subcategory.Products.ForEach(product =&amp;gt; product.ProductSubcategory = null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products.Count.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.All(product =&amp;gt; product.ProductSubcategory == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product original = (Product)tracking.OriginalValues.ToObject();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product changed = tracking.Entity;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{tracking.State}: {(original.ProductID, original.Name, original.ProductSubcategoryID)} =&amp;gt; {(changed.ProductID, changed.Name, changed.ProductSubcategoryID)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Modified: (950, ML Crankset, 8) =&amp;gt; (950, ML Crankset, )
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Modified: (951, HL Crankset, 8) =&amp;gt; (951, HL Crankset, )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Enable and disable tracking&lt;/h3&gt;
&lt;p&gt;DbContext’s default behavior is to track all changes automatically. This can be turned off if not needed. To disable tracking for specific entities queried from repository, call the EntityFrameworkQueryableExtensions.AsNoTracking extension method for IQueryable&amp;lt;T&amp;gt; query:&lt;/p&gt;
&lt;p&gt;internal static void AsNoTracking(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product untracked = adventureWorks.Products.AsNoTracking().First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Tracking can also be enabled or disabled at the DbContext scope, by setting the ChangeTracker.AutoDetectChangesEnabled property to true or false. The default value of ChangeTracker.AutoDetectChangesEnabled is true, so usually it is not needed to manually detect changes by calling ChangeTracker.DetectChanges method. The changes are automatically detected when DbContext.SubmitChanges is called. The changes are also automatically detected when tracking information is calculated, for example, when calling ChangeTracker.Entries, DbContext.Entry, etc.&lt;/p&gt;
&lt;p&gt;If needed, changes and be manually tracked by calling ChangeTracker.DetectChanges method:&lt;/p&gt;
&lt;p&gt;internal static void DetectChanges(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.AutoDetectChangesEnabled = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product product = adventureWorks.Products.First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;product.ListPrice += 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.HasChanges().WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.DetectChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.HasChanges().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Change data&lt;/h2&gt;
&lt;p&gt;To change the data in the database, just create a DbContext instance, change the data in its repositories, and call DbContext.SaveChanges method to submit the tracked changes to the remote database as a unit of work.&lt;/p&gt;
&lt;h3&gt;Create&lt;/h3&gt;
&lt;p&gt;To create new entities into the repository, call DbSet&amp;lt;T&amp;gt;.Add or DbSet&amp;lt;T&amp;gt;.AddRange. The following example creates a new category, and a new related subcategory, and add to repositories:&lt;/p&gt;
&lt;p&gt;internal static ProductCategory Create()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = new ProductCategory() { Name = &quot;Create&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = new ProductSubcategory() { Name = &quot;Create&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.ProductSubcategories = new HashSet&amp;lt;ProductSubcategory&amp;gt;() { subcategory };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to: subcategory.ProductCategory = category;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.ProductCategoryID.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductCategoryID.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductSubcategoryID.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Add(category); // Track creation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to: adventureWorks.ProductSubcategories.Add(subcategory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(tracking =&amp;gt; tracking.State == EntityState.Added).WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(category.ProductSubcategories.Single(), subcategory).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// INSERT INTO [Production].[ProductCategory] ([Name])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// VALUES (@p0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE @@ROWCOUNT = 1 AND [ProductCategoryID] = scope_identity();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 nvarchar(50)&apos;,@p0=N&apos;Create&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// INSERT INTO [Production].[ProductCategory] ([Name])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// VALUES (@p0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE @@ROWCOUNT = 1 AND [ProductCategoryID] = scope_identity();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 nvarchar(50)&apos;,@p0=N&apos;Create&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.ProductCategoryID.WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductCategoryID.WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductSubcategoryID.WriteLine(); // 38
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return category;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here DbSet&amp;lt;T&amp;gt;.Add is called only once with 1 subcategory entity. Internally, Add triggers change detection, and tracks this subcategory as Added state. Since this subcategory is related with another category entity with navigation property, the related category is also tracked, as the Added state too. So in total there are 2 entity changes tracked. When DbContext.SaveChanges is called, EF Core translates these 2 changes to 2 SQL INSERT statements:&lt;/p&gt;
&lt;p&gt;The category’s key is identity key, with value generated by database, so is subcategory. So in the translated INSERT statements, the new category’s ProductCategoryID and the new subcategory’s ProductSubcategory are ignored. After the each new row is created, a SELECT statement calls SCOPE_IDENTITY metadata function to read the last generated identity value, which is the primary key of the inserted row. As a result, since there are 2 row changes in total, SaveChanges returns 2, And the 2 changes are submitted in a transaction, so that all changes can succeed or fail as a unit.&lt;/p&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt;.AddRange can be called with multiple entities. AddRange only triggers change detection once for all the entities, so it can have better performance than multiple Add calls,&lt;/p&gt;
&lt;h3&gt;Update&lt;/h3&gt;
&lt;p&gt;To update entities in the repositories, just change their properties, including navigation properties. The following example updates a subcategory entity’s name, and related category entity, which is translated to UPDATE statement:&lt;/p&gt;
&lt;p&gt;internal static void Update(int categoryId, int subcategoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = adventureWorks.ProductCategories.Find(categoryId);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.Find(subcategoryId);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // (48, Create, 25)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Name = &quot;Update&quot;; // Entity property update.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductCategory = category; // Relashionship (foreign key) update.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // (48, Update, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductSubcategory] SET [Name] = @p0, [ProductCategoryID] = @p1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductSubcategoryID] = @p2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 int&apos;,@p2=25,@p0=N&apos;Update&apos;,@p1=25
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above example first call Find to read the entities with a SELECT query, then execute the UPDATE statement. Here the row to update is located by primary key, so, if the primary key is known, then it can be used directly:&lt;/p&gt;
&lt;p&gt;internal static void UpdateWithoutRead(int categoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = new ProductCategory()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategoryID = categoryId,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Name = Guid.NewGuid().ToString() // To be updated.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Attach(category); // Track entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EntityEntry tracking = adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State = EntityState.Modified;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductCategory] SET [Name] = @p0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductCategoryID] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=25,@p0=N&apos;513ce396-4a5e-4a86-9d82-46f284aa4f94&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here a category entity is constructed on the fly, with specified primary key and updated Name. To track and save the changes, ii is attached to the repository. As fore mentioned, the attached entity is tracked as Unchanged state, so just manually set its state to Modified. This time, only one UPDATE statement is translated and executed, without SELECT.&lt;/p&gt;
&lt;p&gt;When there is no change to save, SaveChanges does not translate or execute any SQL and returns 0:&lt;/p&gt;
&lt;p&gt;internal static void SaveNoChanges(int categoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = adventureWorks.ProductCategories.Find(categoryId);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string originalName = category.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.Name = Guid.NewGuid().ToString(); // Entity property update.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.Name = originalName; // Entity property update.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EntityEntry tracking = adventureWorks.ChangeTracker.Entries().Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.HasChanges().WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Delete&lt;/h3&gt;
&lt;p&gt;To delete entities from the repositories, call DbSet&amp;lt;T&amp;gt;.Remove or DbSet&amp;lt;T&amp;gt;.RemoveRange. The following example read an entity then delete it:&lt;/p&gt;
&lt;p&gt;internal static void Delete(int subcategoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.Find(subcategoryId);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductSubcategories.Remove(subcategory); // Track deletion.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State.WriteLine(); // Deleted
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DELETE FROM [Production].[ProductSubcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductSubcategoryID] = @p0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 int&apos;,@p0=48
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here, the row to delete is also located with primary key. So again, when primary key is known, reading entity can be skipped:&lt;/p&gt;
&lt;p&gt;internal static void DeleteWithoutRead(int categoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = new ProductCategory() { ProductCategoryID = categoryId };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Attach(category);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Remove(category); // Track deletion.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State.WriteLine(); // Deleted
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DELETE FROM [Production].[ProductCategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductCategoryID] = @p0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 int&apos;,@p0=25
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a principal entity is loaded with its dependent entities, deleting the principal entity becomes cascade deletion:&lt;/p&gt;
&lt;p&gt;internal static void DeleteCascade(int categoryId)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = adventureWorks.ProductCategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Include(entity =&amp;gt; entity.ProductSubcategories)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(entity =&amp;gt; entity.ProductCategoryID == categoryId);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = category.ProductSubcategories.Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Remove(category); // Track deletion.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Optional: adventureWorks.ProductSubcategories.Remove(subcategory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ChangeTracker.Entries().Count(tracking =&amp;gt; tracking.State == EntityState.Deleted)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DELETE FROM [Production].[ProductSubcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductSubcategoryID] = @p0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 int&apos;,@p0=49
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DELETE FROM [Production].[ProductCategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductCategoryID] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p1 int&apos;,@p1=26
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the cascade deletion are translated and executed in the right order. The subcategory is deleted first, then category is deleted.&lt;/p&gt;
&lt;h2&gt;Transaction&lt;/h2&gt;
&lt;p&gt;As discussed above, by default DbContext.SaveChanges execute all data creation, update and deletion in a transaction, so that all the work can succeed or fail as a unit. If the unit of work succeeds, the transaction is committed, if any operation fails, the transaction is rolled back. EF Core also supports custom transactions.&lt;/p&gt;
&lt;h3&gt;Transaction with connection resiliency and execution strategy&lt;/h3&gt;
&lt;p&gt;If the retry strategy is enabled for connection resiliency for DbContext by default, then this default retry strategy does not work custom transaction. Custom transaction works within a single retry operation, but not cross multiple retries. In EF Core, database façade’s CreateExecutionStrategy method can be called to explicitly specify a single retry operation:&lt;/p&gt;
&lt;p&gt;internal static void ExecutionStrategy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Single retry operation, which can have custom transactions.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;EF Core transaction&lt;/h3&gt;
&lt;p&gt;EF Core provides Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction to represent a transaction. It can be created by DbContext.Database.BeginTransaction, where the transaction’s isolation level can be optionally specified. The following example executes a entity change and custom SQL with one EF Core transaction:&lt;/p&gt;
&lt;p&gt;internal static void DbContextTransaction(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IDbContextTransaction transaction = adventureWorks.Database
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.BeginTransaction(IsolationLevel.ReadUncommitted))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Add(category);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExecuteSqlCommand($@&quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {nameof(ProductCategory)}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.CurrentIsolationLevel().WriteLine(); // ReadUncommitted transaction.Commit();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;transaction.Rollback();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core transaction wraps ADO.NET transaction. When the EF Core transaction begins, The specified isolation level is written to a packet (represented by System.Data.SqlClient.SNIPacket type), and sent to SQL database via TDS protocol. There is no SQL statement like SET TRANSACTION ISOLATION LEVEL executed, so the actual isolation level cannot be logged by EF Core, or traced by SQL Profiler. In above example, CurrentIsolationLevel is called to verify the current transaction’s isolation level. It is an extension method of DbContext. It queries the dynamic management view sys.dm_exec_sessions with current session id, which can be retrieved with @@SPID function:&lt;/p&gt;
&lt;p&gt;internal static IsolationLevel CurrentIsolationLevel(this DbConnection connection,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbTransaction transaction = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbCommand command = connection.CreateCommand())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.CommandText =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@&quot;SELECT transaction_isolation_level FROM sys.dm_exec_sessions WHERE session_id = @@SPID&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.Transaction = transaction;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch ((short)command.ExecuteScalar())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 0: return IsolationLevel.Unspecified;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 1: return IsolationLevel.ReadUncommitted;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 2: return IsolationLevel.ReadCommitted;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 3: return IsolationLevel.RepeatableRead;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 4: return IsolationLevel.Serializable;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 5: return IsolationLevel.Snapshot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;default: throw new InvalidOperationException();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IsolationLevel CurrentIsolationLevel(this DbContext dbContext) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dbContext.Database.GetDbConnection().CurrentIsolationLevel(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dbContext.Database.CurrentTransaction?.GetDbTransaction());&lt;/p&gt;
&lt;p&gt;When DbContext.SaveChanges is called to create entity. it detects a transaction is explicitly created with the current DbContext, so it uses that transaction and does not automatically begins a new transaction like all the previous examples. Then DbContext.Database.ExecuteSqlCommnd is called to delete entity. It also detects and uses transaction of the current DbContext. Eventually, to commit the transaction, call IDbContextTransaction.Commit, to rollback the transaction, call IDbContextTransaction.Rollback.&lt;/p&gt;
&lt;h3&gt;ADO.NET transaction&lt;/h3&gt;
&lt;p&gt;EF Core can also use the ADO.NET transaction, represented by System.Data.Common.DbTransaction. The following example execute the same entity change and custom SQL command with one ADO.NET transaction. To use an existing ADO.NET transaction, call DbContext.Database.UseTransaction:&lt;/p&gt;
&lt;p&gt;internal static void DbTransaction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.RepeatableRead))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks(connection))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database.UseTransaction(transaction);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.CurrentIsolationLevel().WriteLine(); // RepeatableRead
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.ProductCategories.Add(category);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.SaveChanges().WriteLine(); // 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbCommand command = connection.CreateCommand())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @Name&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DbParameter parameter = command.CreateParameter();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.ParameterName = &quot;@Name&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.Value = nameof(ProductCategory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.Parameters.Add(parameter);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.Transaction = transaction;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.ExecuteNonQuery().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.CurrentIsolationLevel(transaction).WriteLine(); // RepeatableRead
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;transaction.Commit();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;transaction.Rollback();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Transaction scope&lt;/h3&gt;
&lt;p&gt;As fore mentioned, EF Core transaction only works with its source DbContext, and the ADO.NET transaction only work with its source DbConnection. EF Core can also use System.Transactions.TransactionScope to have a transaction that work across the lifecycle of multiple DbContext or DbConnection instances:&lt;/p&gt;
&lt;p&gt;internal static void TransactionScope(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (TransactionScope scope = new TransactionScope(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TransactionScopeOption.Required,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable }))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbCommand command = connection.CreateCommand())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.CommandText = &quot;INSERT INTO [Production].[ProductCategory] ([Name]) VALUES(@Name); &quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DbParameter parameter = command.CreateParameter();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.ParameterName = &quot;@Name&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.Value = nameof(ProductCategory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.Parameters.Add(parameter);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.ExecuteNonQuery().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.CurrentIsolationLevel().WriteLine(); // Serializable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks1 = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = adventureWorks1.ProductCategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(entity =&amp;gt; entity.Name == nameof(ProductCategory));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks1.ProductCategories.Remove(category);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks1.SaveChanges().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks1.CurrentIsolationLevel().WriteLine(); // Serializable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;scope.Complete();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Resolving optimistic concurrency&lt;/h2&gt;
&lt;p&gt;Conflicts can occur if the same data is read and changed concurrently. Generally, there are 2 concurrency control approaches:&lt;/p&gt;
&lt;p&gt;· Pessimistic concurrency: one database client can lock the data being accessed, in order to prevent other database clients to change that same data concurrently.&lt;/p&gt;
&lt;p&gt;· Optimistic concurrency: Data is not locked in the database for client to CRUD. Any database client is allowed to read and change any data concurrently. As a result, concurrency conflicts can happen. This is how EF Core work with database.&lt;/p&gt;
&lt;p&gt;To demonstrate the behavior of EF Core for concurrency, the following DbReaderWriter type is defined as database CRUD client:&lt;/p&gt;
&lt;p&gt;internal partial class DbReaderWriter : IDisposable&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly DbContext context;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal DbReaderWriter(DbContext context) =&amp;gt; this.context = context;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal TEntity Read&amp;lt;TEntity&amp;gt;(params object[] keys) where TEntity : class =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.context.Set&amp;lt;TEntity&amp;gt;().Find(keys);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Write(Action change)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;change();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class =&amp;gt; this.context.Set&amp;lt;TEntity&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Dispose() =&amp;gt; this.context.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Multiple DbReaderWriter instances can be be used to read and write data concurrently. For example:&lt;/p&gt;
&lt;p&gt;internal static void NoCheck(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory categoryCopy1 = readerWriter1.Read&amp;lt;ProductCategory&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory categoryCopy2 = readerWriter2.Read&amp;lt;ProductCategory&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter1.Write(() =&amp;gt; categoryCopy1.Name = nameof(readerWriter1));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductCategory] SET [Name] = @p0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductCategoryID] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter2.Write(() =&amp;gt; categoryCopy2.Name = nameof(readerWriter2)); // Last client wins.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductCategory] SET [Name] = @p0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductCategoryID] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter2&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category3 = readerWriter3.Read&amp;lt;ProductCategory&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category3.Name.WriteLine(); // readerWriter2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In this example, multiple DbReaderWriter instances read and write data concurrently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads category “Bikes”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads category “Bikes”. These 2 entities are independent because they are are from different DbContext instances.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 updates category’s name from “Bikes” to “readerWriter1”. As previously discussed, by default EF Core locate the category with its primary key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In database, this category’s name is no longer “Bikes”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 updates category’s name from “Bikes” to “readerWriter2”. It locates the category with its primary key as well. The primary key is unchanged, so the same category can be located and the name can be changed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;So later when readerWriter3 reads the entity with the same primary key, the category entity’s Name is “readerWriter2”.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Detect Concurrency conflicts&lt;/h3&gt;
&lt;p&gt;Concurrency conflicts can be detected by checking entities’ property values besides primary keys. To required EF Core to check a certain property, just add a System.ComponentModel.DataAnnotations.ConcurrencyCheckAttribute to it. Remember when defining ProductPhoto entity, its ModifiedDate has a [ConcurrencyCheck] attribute:&lt;/p&gt;
&lt;p&gt;public partial class ProductPhoto&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ConcurrencyCheck]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime ModifiedDate { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This property is also called the concurrency token. When EF Core translate changes of a photo, ModifiedDate property is checked along with the primary key to locate the photo:&lt;/p&gt;
&lt;p&gt;internal static void ConcurrencyCheck(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductPhoto photoCopy1 = readerWriter1.Read&amp;lt;ProductPhoto&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductPhoto photoCopy2 = readerWriter2.Read&amp;lt;ProductPhoto&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter1.Write(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;photoCopy1.LargePhotoFileName = nameof(readerWriter1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;photoCopy1.ModifiedDate = DateTime.Now;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter1&apos;,@p1=&apos;2017-01-25 22:04:25.9292433&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter2.Write(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;photoCopy2.LargePhotoFileName = nameof(readerWriter2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;photoCopy2.ModifiedDate = DateTime.Now;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter2&apos;,@p1=&apos;2017-01-25 22:04:59.1792263&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the translated SQL statement, the WHERE clause contains primary key and the original concurrency token. The following is how EF Core check the concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads the same photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates the photo with primary key and original modified date, and update its large photo file name and modified date.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In database the photo’s modified date is no longer the original value “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 tries to locate the photo with primary key and original modified date. However the provided modified date is outdated. EF Core detect that 0 row is updated by the translated SQL, and throws DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another option for concurrency check is System.ComponentModel.DataAnnotations.TimestampAttribute. It can only be used for a byte[] property, which is mapped from a rowversion (timestamp) column. For SQL database, these 2 terms, rowversion and timestamp, are the same thing. timestamp is just a synonym of rowversion data type. A row’s non-nullable rowversion column is a 8 bytes (binary(8)) counter maintained by database, its value increases for each change of the row.&lt;/p&gt;
&lt;p&gt;Microsoft’s AdventureWorks sample database does not have such a rowversion column, so create one for the Production.Product table:&lt;/p&gt;
&lt;p&gt;ALTER TABLE [Production].[Product] ADD [RowVersion] rowversion NOT NULL&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;Then define the mapping property for Product entity:&lt;/p&gt;
&lt;p&gt;public partial class Product&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Timestamp]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public byte[] RowVersion { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[NotMapped]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string RowVersionString =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;0x{BitConverter.ToUInt64(this.RowVersion.Reverse().ToArray(), 0).ToString(&quot;X16&quot;)}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now RowVersion property is the concurrency token. Regarding database automatically increases the RowVersion value, Rowversion also has the [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute. The other RowVersionString property returns a readable representation of the byte array returned by RowVersion. It is not a part of the object-relational mapping, so it has a [NotMapped] attribute. The following example updates and and deletes the same product concurrently:&lt;/p&gt;
&lt;p&gt;internal static void RowVersion(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int id = 995;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.RowVersionString.WriteLine(); // 0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy2.RowVersionString.WriteLine(); // 0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter1.Write(() =&amp;gt; productCopy1.Name = nameof(readerWriter1));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UPDATE [Production].[Product] SET [Name] = @p0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductID] = @p1 AND [RowVersion] = @p2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [RowVersion]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE @@ROWCOUNT = 1 AND [ProductID] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p1 int,@p0 nvarchar(50),@p2 varbinary(8)&apos;,@p1=995,@p0=N&apos;readerWriter1&apos;,@p2=0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.RowVersionString.WriteLine(); // 0x00000000000324B1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter2.Write(() =&amp;gt; readerWriter2.Set&amp;lt;Product&amp;gt;().Remove(productCopy2));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SET NOCOUNT ON;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DELETE FROM [Production].[Product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [ProductID] = @p0 AND [RowVersion] = @p1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT @@ROWCOUNT;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;,N&apos;@p0 int,@p1 varbinary(8)&apos;,@p0=995,@p1=0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When updating and deleting photo entities, its auto generated RowVersion property value is checked too. So this is how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads product with primary key 995 and row version 0x0000000000000803&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads product with the same primary key 995 and row version 0x0000000000000803&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates the photo with primary key and original row version, and update its name. Database automatically increases the photo’s row version. Since the row version is specified as [DatabaseGenerated(DatabaseGeneratedOption.Computed)], EF Core also locate the photo with the primary key to query the increased row version, and update the entity at client side.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In database the product’s row version is no longer 0x0000000000000803.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then readerWriter2 tries to locate the product with primary key and original row version, and delete it. No product can be found with outdated row version, EF Core detect that 0 row is deleted, and throws DbUpdateConcurrencyException.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Resolve concurrency conflicts&lt;/h3&gt;
&lt;p&gt;DbUpdateConcurrencyException is thrown when SaveChanges detects concurrency conflict:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class DbUpdateException : Exception
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IReadOnlyList&amp;lt;EntityEntry&amp;gt; Entries { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class DbUpdateConcurrencyException : DbUpdateException
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Inherited from DbUpdateException, DbUpdateConcurrencyException has an Entries property. Entries returns a sequence of EntityEntry instances, representing the conflicting entities’ tracking information. The basic idea of resolving concurrency conflicts, is to handle DbUpdateConcurrencyException and retry SaveChanges:&lt;/p&gt;
&lt;p&gt;internal partial class DbReaderWriter&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Write(Action change, Action&amp;lt;DbUpdateConcurrencyException&amp;gt; handleException, int retryCount = 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;change();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int retry = 1; retry &amp;lt; retryCount; retry++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (DbUpdateConcurrencyException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;handleException(exception);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the above Write overload, if SaveChanges throws DbUpdateConcurrencyException, the handleException function is called. This function is expected to handle the exception and resolve the conflicts properly. Then SaveChanges is called again. If the last retry of SaveChanges still throws DbUpdateConcurrencyException, the exception is thrown to the caller.&lt;/p&gt;
&lt;h3&gt;Retain database values (database wins)&lt;/h3&gt;
&lt;p&gt;Similar to previous examples, the following example has multiple DbReaderWriter instances to update a product concurrently:&lt;/p&gt;
&lt;p&gt;internal static void UpdateProduct(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;EntityEntry&amp;gt;resolveConflicts)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int id = 950;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter1.Write(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.Name = nameof(readerWriter1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.ListPrice = 100.0000M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerWriter2.Write(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;change: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy2.Name = nameof(readerWriter2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy2.ProductSubcategoryID = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;handleException: exception =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EntityEntry tracking = exception.Entries.Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product original = (Product)tracking.OriginalValues.ToObject();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product current = (Product)tracking.CurrentValues.ToObject();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product database = productCopy1; // Values saved in database.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Original: ({original.Name}, {original.ListPrice}, {original.ProductSubcategoryID}, {original.RowVersionString})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Database: ({database.Name}, {database.ListPrice}, {database.ProductSubcategoryID}, {database.RowVersionString})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Update to: ({current.Name}, {current.ListPrice}, {current.ProductSubcategoryID})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resolveConflicts(tracking);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product resolved = readerWriter3.Read&amp;lt;Product&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Resolved: ({resolved.Name}, {resolved.ListPrice}, {resolved.ProductSubcategoryID}, {resolved.RowVersionString})&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is how it works with concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads product with primary key 950, and RowVersion 0x00000000000007D1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads product with the same primary key 950, and RowVersion 0x00000000000007D1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates product with primary key and original RowVersion 0x00000000000007D1, and updates product’s name and list price. Database automatically increases the product’s row version&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In database the product’s row version is no longer 0x00000000000007D1.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 tries to locate product with primary key and original RowVersion, and update product’s name and subcategory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 fails to update product, because it cannot locate the product with original RowVersion 0x00000000000007D1. Again, no product can be found with outdated row version, DbUpdateConcurrencyException is thrown.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a result, the handleException function specified for readWriter2 is called, it retrieves the conflicting product’s tracking information from DbUpdateConcurrencyException.Entries, and logs these information:&lt;/p&gt;
&lt;p&gt;· product’s original property values read by readerWriter2 before the changes&lt;/p&gt;
&lt;p&gt;· product’s property values in database at this moment, which are already updated readerWriter1&lt;/p&gt;
&lt;p&gt;· product’s current property values after changes, which readerWriter2 fails to save to database.&lt;/p&gt;
&lt;p&gt;Then handleException calls resolveConflicts function to actually resolve the conflict. Then readerWriter2 retries to save the product changes again. This time, SaveChanges should succeed, because there is no conflicts anymore (In this example, there are only 2 database clients reading/writing data concurrently. In reality, the concurrency can be higher, an appropriate retry count or retry strategy should be specified.). Eventually, readerWriter3 reads the product from database, verify its property values.&lt;/p&gt;
&lt;p&gt;There are several options to implement the resolveConflicts function to resolves the conflicts. One simple option, called “database wins”, is to simply give up the client update, and let database retain whatever values it has for that entity. This seems to be easy to just catch DbUpdateConcurrencyException and do nothing, then database naturally wins, and retains its values:&lt;/p&gt;
&lt;p&gt;internal partial class DbReaderWriter&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int WriteDatabaseWins(Action change)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;change();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (DbUpdateConcurrencyException)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return 0; // this.context is in a corrupted state.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;However, this way leaves the DbContext, the conflicting entity, and the entity’s tracking information in a corrupted state. For the caller, since the change saving is done, the entity’s property values should be in sync with database values, but the values are actually out of sync and still conflicting. Also, the entity has a tracking state Modified after change saving is done. So the safe approach is to reload and refresh the entity’s values and tracking information:&lt;/p&gt;
&lt;p&gt;internal static void DatabaseWins(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Modified
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Reload(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Original: (ML Crankset, 256.4900, 8, 0x00000000000007D1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Database: (readerWriter1, 100.0000, 8, 0x0000000000036335)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Update to: (readerWriter2, 256.4900, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Resolved: (readerWriter1, 100.0000, 8, 0x0000000000036335)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;UpdateProduct is called with a resolveConflicts function, which resolves the conflict by calling Reload method on the EntityEntry instance representing the conflicting product’s tracking information:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;EntityEntry.Reload executes a SELECT statement to read the product’s property values from database, then refresh the product entity and all tracking information. The product’s property values, the tracked original property values before changes, the tracked current property values after changes, are all refreshed to the queried database values. The entity tracking state is also refreshed to Unchanged.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, product has the same tracked original values and current values, as if it is just initially read from database, without changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, no changed entity is detected. SaveChanges succeeds without executing any SQL, and returns 0. As expected, readerWriter2 does not update any value to database, and all values in database are retained.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrtier1.&lt;/p&gt;
&lt;h3&gt;Overwrite database values (client wins)&lt;/h3&gt;
&lt;p&gt;Another simple option, called “client wins”, is to disregard values in database, and overwrite them with whatever data submitted from client.&lt;/p&gt;
&lt;p&gt;internal static void ClientWins(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues databaseValues = tracking.GetDatabaseValues();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Refresh original values, which go to WHERE clause of UPDATE statement.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.OriginalValues.SetValues(databaseValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Modified
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Original: (ML Crankset, 256.4900, 8, 0x00000000000007D1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Database: (readerWriter1, 100.0000, 8, 0x0000000000036336)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Update to: (readerWriter2, 256.4900, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Resolved: (readerWriter2, 256.4900, 1, 0x0000000000036337)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The same conflict is resolved differently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version. This call does not impact the product values or tracking information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manually set the tracked original property values to the queried database values. The entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product properties are tracked as modified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, the product has tracked original values updated, and keeps all tracked current values, as if it is read from database after readerWriter1 updates the name and list price, and then have all properties values changed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. So EF Core translate the product change to a UPDATE statement. In the SET clause, since there are 3 properties tracked as modified, 3 columns are set. In the WHERE clause, to locate the product, the tracked original row version has been set to the updated value from database. This time product can be located, and all 3 properties are updated. SaveChanges succeeds and returns 1. As expected, readerWriter2 updates all value to database.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrter2.&lt;/p&gt;
&lt;h3&gt;Merge with database values&lt;/h3&gt;
&lt;p&gt;A more complex but useful option, is to merge the client values and database values. For each property:&lt;/p&gt;
&lt;p&gt;· If original value is different from database value, which means database value is already updated by other concurrent client, then give up updating this property, and retain the database value&lt;/p&gt;
&lt;p&gt;· If original value is the same as database value, which means no concurrency conflict for this property, then process normally to submit the change&lt;/p&gt;
&lt;p&gt;internal static void MergeClientAndDatabase(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues originalValues = tracking.OriginalValues.Clone();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Refresh original values, which go to WHERE clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.OriginalValues.SetValues(databaseValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// If database has an different value for a property, then retain the database value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseValues.Properties // Navigation properties are not included.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State.WriteLine(); // Modified
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Original: (ML Crankset, 256.4900, 8, 0x00000000000007D1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Database: (readerWriter1, 100.0000, 8, 0x0000000000036338)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Update to: (readerWriter2, 256.4900, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Resolved: (readerWriter1, 100.0000, 1, 0x0000000000036339)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With this approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Again, EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Backup tracked original values, then refresh conflict.OriginalValues to the database values, so that these values can go to the translated WHERE clause. Again, the entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product values are tracked as modified and should go to SET clause.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For each property, if the backed original value is different from the database value, it means this property is changed by other client and there is concurrency conflict. In this case, revert this property’s tracking status to unmodified. The name and list price are reverted.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, the product has tracked original values updated, and only keeps tracked current value of subcategory, as if it is read from database after readerWriter1 updates the name and list price, and then only have subcategory changed, which has no conflict.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. Here only subcategory is updated to database. SaveChanges succeeds and returns 1. As expected, readerWriter2 only updates value without conflict, the other conflicted values are retained.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product, product has name and list price values updated by readerWrtier1, and has subcategory updated by readerWriter2.&lt;/p&gt;
&lt;h3&gt;Save changes with concurrency conflict handling&lt;/h3&gt;
&lt;p&gt;Similar to above DbReaderWriter.Write method, a general SaveChanges extension method for DbContext can be defined to handle concurrency conflicts and apply simple retry logic:&lt;/p&gt;
&lt;p&gt;public static int SaveChanges(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, int retryCount = 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (retryCount &amp;lt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(retryCount));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int retry = 1; retry &amp;lt; retryCount; retry++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resolveConflicts(exception.Entries);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return context.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To apply custom retry logic, Microsoft provides EnterpriseLibrary.TransientFaultHandling NuGet package (Exception Handling Application Block) for .NET Framework. It has been ported to .NET Core for this tutorial, as EnterpriseLibrary.TransientFaultHandling.Core NuGet package. can be used. With this library, a SaveChanges overload with customizable retry logic can be easily defined:&lt;/p&gt;
&lt;p&gt;public class TransientDetection&amp;lt;TException&amp;gt; : ITransientErrorDetectionStrategy&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;where TException : Exception
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool IsTransient(Exception ex) =&amp;gt; ex is TException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int SaveChanges(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, RetryStrategy retryStrategy)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;RetryPolicy retryPolicy = new RetryPolicy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;errorDetectionStrategy: new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;retryStrategy: retryStrategy);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;retryPolicy.Retrying += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resolveConflicts(((DbUpdateConcurrencyException)e.LastException).Entries);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return retryPolicy.ExecuteAction(context.SaveChanges);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ITransientErrorDetectionStrategy is the contract to detect each exception, and determine whether the exception is transient and the operation should be retried. Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryStrategy is the contract of retry logic. Then Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy executes the operation with the specified exception detection, exception handling, and retry logic.&lt;/p&gt;
&lt;p&gt;As discussed above, to resolve a concurrency conflict, the entity and its tracking information need to be refreshed. So the more specific SaveChanges overloads can be implemented by applying refresh for each conflict:&lt;/p&gt;
&lt;p&gt;public enum RefreshConflict&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;StoreWins,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ClientWins,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MergeClientAndStore
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (retryCount&amp;lt; = 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(retryCount));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return context.SaveChanges(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int SaveChanges(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context.SaveChanges(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryStrategy);&lt;/p&gt;
&lt;p&gt;A RefreshConflict enumeration has to be defined with 3 members to represent the 3 options discussed above: database wins, client wind, merge client and database.. And here the Refresh method is an extension method for EntityEntry:&lt;/p&gt;
&lt;p&gt;public static EntityEntry Refresh(this EntityEntry tracking, RefreshConflict refreshMode)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (refreshMode)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case RefreshConflict.StoreWins:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already deleted in database, Reload sets tracking state to Detached.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already updated in database, Reload sets tracking state to Unchanged.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.Reload(); // Execute SELECT.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Hereafter, SaveChanges ignores this entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case RefreshConflict.ClientWins:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (databaseValues == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already deleted in database, there is nothing for client to win against.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Manually set tracking state to Detached.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State = EntityState.Detached;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Hereafter, SaveChanges ignores this entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already updated in database, refresh original values, which go to in WHERE clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.OriginalValues.SetValues(databaseValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case RefreshConflict.MergeClientAndStore:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (databaseValues == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already deleted in database, there is nothing for client to merge with.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Manually set tracking state to Detached.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.State = EntityState.Detached;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Hereafter, SaveChanges ignores this entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When entity is already updated, refresh original values, which go to WHERE clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;PropertyValues originalValues = tracking.OriginalValues.Clone();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tracking.OriginalValues.SetValues(databaseValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// If database has an different value for a property, then retain the database value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseValues.Properties // Navigation properties are not included.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return tracking;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This Refresh extension method covers the update conflicts discussed above, as well as deletion conflicts. Now the these SaveChanges extension methods can be used to manage concurrency conflicts easily. For example:&lt;/p&gt;
&lt;p&gt;internal static void SaveChanges(AdventureWorks adventureWorks1, AdventureWorks adventureWorks2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int id = 950;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy1 = adventureWorks1.Products.Find(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product productCopy2 = adventureWorks2.Products.Find(id);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.Name = nameof(adventureWorks1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy1.ListPrice = 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks1.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy2.Name = nameof(adventureWorks2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productCopy2.ProductSubcategoryID = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks2.SaveChanges(RefreshConflict.MergeClientAndStore);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (6) Query Data Loading</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading/</guid><description>After translated to SQL, in LINQ to Entities, sequence queries returning IQueryable&lt;T&gt; implements deferred execution too.</description><pubDate>Fri, 11 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;After translated to SQL, in LINQ to Entities, sequence queries returning IQueryable&amp;lt;T&amp;gt; implements deferred execution too.&lt;/p&gt;
&lt;h3&gt;Deferred execution&lt;/h3&gt;
&lt;p&gt;As previous part discussed, when defining a LINQ to Entities query represented by IQueryable&amp;lt;T&amp;gt;, an expression tree is built, there is no query execution. The execution is deferred until trying to pull the results from the query.&lt;/p&gt;
&lt;h3&gt;Iterator pattern&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;, so values can be pulled from IQueryable&amp;lt;T&amp;gt; with the standard iterator pattern. When trying to pull the first value, EF Core translates LINQ to Entities query to SQL, and execute SQL in the database. The implementation can be demonstrated with the Iterator&amp;lt;T&amp;gt; type from the LINQ to Objects chapter:&lt;/p&gt;
&lt;p&gt;public static IEnumerator&amp;lt;TEntity&amp;gt; GetEntityIterator&amp;lt;TEntity&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TEntity&amp;gt; query, DbContext dbContext) where TEntity : class
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;| |_Compile LINQ expression tree to database expression tree.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(SelectExpression DatabaseExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt; Parameters) compilation = dbContext.Compile(query.Expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TEntity&amp;gt; entityIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Iterator&amp;lt;TEntity&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;| |_Generate SQL from database expression tree.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRelationalCommand sql = dbContext.Generate(compilation.DatabaseExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TEntity&amp;gt; sqlQuery = dbContext.Set&amp;lt;TEntity&amp;gt;().FromRawSql(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sql: sql.CommandText,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters: compilation.Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(parameter =&amp;gt; new SqlParameter(parameter.Key, parameter.Value)).ToArray());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;entityIterator = sqlQuery.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;| |_Execute generated SQL.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; entityIterator.MoveNext(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;| |_Materialize data row to {typeof(TEntity).Name} entity.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return entityIterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; entityIterator.Dispose(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;end: () =&amp;gt; &quot; |_End.&quot;.WriteLine()).Start();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example executes Where and Take query to load 3 products with more than 10 characters in name. It demonstrates how to pull the results from IQueryable&amp;lt;T&amp;gt; with the iterator pattern:&lt;/p&gt;
&lt;p&gt;internal static void DeferredExecution(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; categories = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; product.Name.Length &amp;gt; 100)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Iterator - Create from LINQ to Entities query.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;Product&amp;gt; iterator = categories.GetEntityIterator(adventureWorks)) // Compile query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (new Func&amp;lt;bool&amp;gt;(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool moveNext = iterator.MoveNext();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;|_Iterator - [{index++}] {nameof(IEnumerator&amp;lt;Product&amp;gt;.MoveNext)}: {moveNext}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return moveNext; // Generate SQL when first time called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Product product = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;| |_Iterator - [{index}] {nameof(IEnumerator&amp;lt;Product&amp;gt;.Current)}: {product.Name}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Iterator - Create from LINQ to Entities query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Compile LINQ expression tree to database expression tree.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// |_Iterator - [0] MoveNext: True.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Generate SQL from database expression tree.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Execute generated SQL.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Materialize data row to Product entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Iterator - [0] Current: ML Crankset.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// |_Iterator - [1] MoveNext: True.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Materialize data row to Product entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Iterator - [1] Current: HL Crankset.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// |_Iterator - [2] MoveNext: True.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Materialize data row to Product entity.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// | |_Iterator - [2] Current: Touring-2000 Blue, 60.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// |_Iterator - [3] MoveNext: False.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// |_End.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here for demonstration purpose, the GetEntityIterator extension method of IQueryable&amp;lt;T&amp;gt; is called instead of GetEnumerator. In EF Core, when the iterator is created from IQueryable&amp;lt;T&amp;gt;, the LINQ query expression tree is compiled to database query expression tree. Later, when the iterator’s MoveNext method is called for the first time, the SQL query is generated and executed. In each iteration, an entity is materialized from the SQL execution result.&lt;/p&gt;
&lt;h3&gt;Lazy evaluation vs. eager evaluation&lt;/h3&gt;
&lt;p&gt;Deferred execution can be either lazy evaluation or eager evaluation. Internally, EF Core call ADP.NET APIs to execute query, including DbDataReader, etc. DbDataReader is abstract class. EF Core SQL database provider actually uses SqlDataReader in ADO.NET, which is derived from DbDataReader, to load the database query results. By default, when SqlDataReader starts to read data, it streams a number of rows to local buffer through TDS (tabular data stream) protocol. So by default, LINQ to Entities’ deferred execution is neither eager (load all rows when pulling the first result), nor totally lazy (load 1 result when pulling each result).&lt;/p&gt;
&lt;p&gt;When retry logic is specified for connection resiliency, EF Core become eager evaluation. When trying to pull the first query result, EF Core call DbDataReader to load all results from database.&lt;/p&gt;
&lt;h3&gt;Explicit loading&lt;/h3&gt;
&lt;p&gt;After an entity is queried, its related entities can be loaded through the navigation property. DbContext.Entry method accepts an entity of type TEntity, and returns Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry&amp;lt;TEntity&amp;gt;, which represents that entity’s tracking and loading information. EntityEntry&amp;lt;TEntity&amp;gt; provides a Reference method to return Microsoft.EntityFrameworkCore.ChangeTracking.ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt; instance, which represents the tracking and loading information of a single related entity from reference navigation property. EntityEntry&amp;lt;TEntity&amp;gt; also provides a Collection method to return Microsoft.EntityFrameworkCore.ChangeTracking.ReferenceEntry.CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;, which represents the tracking and loading information of multiple related entities from collection navigation property. These related entities in the navigation properties can be manually loaded by calling ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Load and CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;.Load:&lt;/p&gt;
&lt;p&gt;internal static void ExplicitLoading(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT TOP(1) [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Entry(subcategory) // Return EntityEntry&amp;lt;ProductSubcategory&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Reference(entity =&amp;gt; entity.ProductCategory) // Return ReferenceEntry&amp;lt;ProductSubcategory, ProductCategory&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Load(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductCategoryID], [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.ProductCategory.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Entry(subcategory) // Return EntityEntry&amp;lt;ProductSubcategory&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Collection(entity =&amp;gt; entity.Products) // Return CollectionEntry&amp;lt;ProductSubcategory, Product&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Load(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductID], [e].[ListPrice], [e].[Name], [e].[ProductSubcategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductSubcategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Products.WriteLines(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the Load method is called, the related entities are queried, and become available through the navigation properties. Besides loading the full entities, explicit lazy loading also support custom query. The following example uses the reference navigation property and collection navigation property as LINQ to Entities data sources, by calling ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Query and CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;.Query:&lt;/p&gt;
&lt;p&gt;internal static void ExplicitLoadingWithQuery(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT TOP(1) [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string categoryName = adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Entry(subcategory).Reference(entity =&amp;gt; entity.ProductCategory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Query() // Return IQueryable&amp;lt;ProductCategory&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(category =&amp;gt; category.Name).Single(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT TOP(2) [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;categoryName.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;products = adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Entry(subcategory).Collection(entity =&amp;gt; entity.Products)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Query() // Return IQueryable&amp;lt;Product&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; product.Name); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductSubcategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Eager loading&lt;/h3&gt;
&lt;p&gt;In explicit loading, after an entity is queried, its related entities are loaded separately. In eager loading, when an entity is queried, its related entities are loaded during the same query. To enable eager loading, call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions’ Include method, which is an extension method for IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal static void EagerLoadingWithInclude(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategoriesWithCategory = adventureWorks.ProductSubcategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Include(subcategory =&amp;gt; subcategory.ProductCategory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategoriesWithCategory.WriteLines(subcategory =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{subcategory.ProductCategory.Name}: {subcategory.Name}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID], [p].[ProductCategoryID], [p].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// INNER JOIN [Production].[ProductCategory] AS [p] ON [subcategory].[ProductCategoryID] = [p].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategoriesWithProducts = adventureWorks.ProductSubcategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Include(subcategory =&amp;gt; subcategory.Products);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategoriesWithProducts.WriteLines(subcategory =&amp;gt; $@&quot;{subcategory.Name}: {string.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;, &quot;, subcategory.Products.Select(product =&amp;gt; product.Name))}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ORDER BY [subcategory].[ProductSubcategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [p].[ProductID], [p].[ListPrice], [p].[Name], [p].[ProductSubcategoryID], [p].[RowVersion]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE EXISTS (
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [p].[ProductSubcategoryID] = [subcategory].[ProductSubcategoryID])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ORDER BY [p].[ProductSubcategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Eager loading related entity through reference navigation property is translated to INNER JOIN. Eager loading through collection navigation property is translated to 2 SQL queries for 2 types of entities. More queries can be chained after calling Include.&lt;/p&gt;
&lt;p&gt;In EF Core, ThenInclude can be called for eager loading of multiple levels of related entities:&lt;/p&gt;
&lt;p&gt;internal static void EagerLoadingMultipleLevels(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;products = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Include(product =&amp;gt; product.ProductProductPhotos)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ThenInclude(productProductPhoto =&amp;gt; productProductPhoto.ProductPhoto);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products.WriteLines(product =&amp;gt; $@&quot;{product.Name}: {string.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;, &quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;product.ProductProductPhotos.Select(productProductPhoto =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;productProductPhoto.ProductPhoto.LargePhotoFileName))}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ORDER BY [product].[ProductID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [p].[ProductID], [p].[ProductPhotoID], [p0].[ProductPhotoID], [p0].[LargePhotoFileName], [p0].[ModifiedDate]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductProductPhoto] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// INNER JOIN [Production].[ProductPhoto] AS [p0] ON [p].[ProductPhotoID] = [p0].[ProductPhotoID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE EXISTS (
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [p].[ProductID] = [product].[ProductID])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ORDER BY [p].[ProductID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Lazy loading&lt;/h3&gt;
&lt;p&gt;EF Core also supports lazy loading.&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public AdventureWorks(DbConnection connection = null, bool lazyLoading = true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: base(GetDbContextOptions(connection, lazyLoading))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static DbContextOptions GetDbContextOptions(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DbConnection connection = null, bool lazyLoading = true) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new DbContextOptionsBuilder&amp;lt;AdventureWorks&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.UseLazyLoadingProxies(lazyLoading)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.UseSqlServer(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection: connection ??
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new SqlConnection(ConnectionStrings.AdventureWorks),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sqlServerOptionsAction: options =&amp;gt; options.EnableRetryOnFailure(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;errorNumbersToAdd: null))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Options;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When an entity’s navigation property is accessed, the related entities are queried and loaded automatically:&lt;/p&gt;
&lt;p&gt;internal static void LazyLoading(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT TOP(1) [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = subcategory.ProductCategory; // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductCategoryID], [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ICollection&amp;lt;Product&amp;gt; products = subcategory.Products; // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductID], [e].[ListPrice], [e].[Name], [e].[ProductSubcategoryID], [e].[RowVersion]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductSubcategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products.WriteLines(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;The N + 1 problem&lt;/h3&gt;
&lt;p&gt;Sometimes lazy loading can cause the “N + 1 queries” problem. The following example queries the subcategories, and pulls each subcategory’s information:&lt;/p&gt;
&lt;p&gt;internal static void MultipleLazyLoading(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory[] subcategories = adventureWorks.ProductSubcategories.ToArray(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductSubcategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategories.WriteLines(subcategory =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{subcategory.Name} ({subcategory.ProductCategory.Name})&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductCategoryID], [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// exec sp_executesql N&apos;SELECT [e].[ProductCategoryID], [e].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [e]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When loading the subcategories, 1 database query is executed. When each subcategory’s related category is pulled through the navigation property, it is loaded instantly, if not loaded yet. So in total there are N queries for related categories + 1 query for subcategories executed. For better performance in this kind of scenario, eager loading or inner join should be used to load all entities and related entities with 1 single query.&lt;/p&gt;
&lt;h3&gt;Disable lazy loading&lt;/h3&gt;
&lt;p&gt;There are some scenarios where lazy loading needs to be disabled, like entity serialization. There are several ways to disable lazy loading for different scopes&lt;/p&gt;
&lt;p&gt;· To globally disable lazy loading for specific navigation properties, just do not mark it as virtual, so that the derived proxy entity cannot override it with the lazy load implementation.&lt;/p&gt;
&lt;p&gt;· To disable lazy loading for specific DbContext or specific query, call DbContext.Configuration to get a DbConfiguration instance, and set its LazyLoadingEnabled property to false.&lt;/p&gt;
&lt;p&gt;internal static void DisableLazyLoading()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks(lazyLoading: false))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;subcategory.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductCategory category = subcategory.ProductCategory; // No query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(category == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ICollection&amp;lt;Product&amp;gt; products = subcategory.Products; // No query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(products == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (5) Query Translation Implementation</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation/</guid><description>Regarding different database systems can have different query languages or different query APIs, EF Core implement a provider model to work with different kinds of databases. In EF Core, the base libr</description><pubDate>Thu, 10 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Regarding different database systems can have different query languages or different query APIs, EF Core implement a provider model to work with different kinds of databases. In EF Core, the base libraries are the Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Relational NuGet packages. Microsoft.EntityFrameworkCore provides the database provider contracts as Microsoft.EntityFrameworkCore.Storage.IDatabaseProviderServices interface. And the SQL database support is implemented by the Microsoft.EntityFrameworkCore,SqlServer NuGet package, which provides Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerDatabaseProviderServices type to implement IDatabaseProviderServices. There are other libraries for different databases, like Microsoft.EntityFrameworkCore.SQLite NuGet package for SQLite, etc.&lt;/p&gt;
&lt;p&gt;With this provider model, EF Core breaks the translation into 2 parts. First, IQueryable&amp;lt;T&amp;gt; queries work with expression trees, and EF Core base libraries translate these .NET expression tree to generic, intermediate database expression tree; Then the specific EF Core database provider is responsible to generate query language for the specific database.&lt;/p&gt;
&lt;h3&gt;Code to LINQ expression tree&lt;/h3&gt;
&lt;p&gt;Before translation, .NET expression tree must be built to represent the query logic. As fore mentioned, expression tree enables function as data. In C#, an expression tree shares the same lambda expression syntax as anonymous functions, but is compiled to abstract syntactic tree representing function’s source code. In LINQ, IQueryable&amp;lt;T&amp;gt; utilizes expression tree to represent the abstract syntactic structure of a remote query.&lt;/p&gt;
&lt;h3&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; has been demonstrated:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); from IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Type ElementType { get; } from IQueryable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Expression Expression { get; } from IQueryable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryProvider Provider { get; } from IQueryable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is a wrapper of iterator factory, an element type, an expression tree representing the current query’s logic, and a query provider of IQueryProvider type:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryProvider
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable CreateQuery(Expression expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object Execute(Expression expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult Execute&amp;lt;TResult&amp;gt;(Expression expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;IQueryProvider has CreateQuery and Execute methods, all accepting a expression tree parameter. CreateQuery returns an IQueryable&amp;lt;T&amp;gt; query, and Execute returns a query result. These methods are called by the standard queries internally.&lt;/p&gt;
&lt;h3&gt;Standard remote queries&lt;/h3&gt;
&lt;p&gt;Queryable provides 2 kinds of queries, sequence queries returning IQueryable&amp;lt;T&amp;gt; query, and value queries returning a query result. Take Where, Select, and First as examples, the following are their implementations:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;TSource&amp;gt;&amp;gt; currentMethod = Where;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression whereCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: currentMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: source.Expression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.Quote(predicate));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(whereCallExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt;source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;, IQueryable&amp;lt;TResult&amp;gt;&amp;gt; currentMethod =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Select;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression selectCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: currentMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: source.Expression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.Quote(selector));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(selectCallExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, TSource&amp;gt;currentMethod = First;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression firstCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: currentMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: source.Expression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.Quote(predicate));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt;source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, TSource&amp;gt;currentMethod = First;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression firstCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: currentMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: source.Expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;They just build a MethodCallExpression expression, representing the current query is called. Then they obtain query provider from source’s Provider property. The sequence queries call query provider’s CreateQuery method to return IQueryable&amp;lt;T&amp;gt; query, and the value queries call query provider’s Execute method to return a query result. All standard queries are implemented in this pattern except AsQueryable.&lt;/p&gt;
&lt;h3&gt;Build LINQ to Entities abstract syntax tree&lt;/h3&gt;
&lt;p&gt;With above Where and Select queries, a simple LINQ to Entities query can be implemented to return an IQueryable&amp;lt;T&amp;gt; of values:&lt;/p&gt;
&lt;p&gt;internal static void WhereAndSelect(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; products = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(product =&amp;gt; product.Name.Length&amp;gt; 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(product =&amp;gt; product.Name.Length &amp;gt; 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(product =&amp;gt; product.Name); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in selectQueryable) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above example filters the products with Name longer than 10 characters, and queries the products’ Names. By desugaring the lambda expressions, and unwrapping the standard queries, the above LINQ to Entities query is equivalent to:&lt;/p&gt;
&lt;p&gt;internal static void WhereAndSelectLinqExpressions(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;sourceQueryable = adventureWorks.Products; // DbSet&amp;lt;Product&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConstantExpression sourceConstantExpression = (ConstantExpression)sourceQueryable.Expression;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider sourceQueryProvider = sourceQueryable.Provider; // EntityQueryProvider.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = product =&amp;gt; product.Name.Length &amp;gt; 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParameterExpression productParameterExpression = Expression.Parameter(typeof(Product), &quot;product&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;predicateExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;body: Expression.GreaterThan(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;left: Expression.Property(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expression: Expression.Property(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expression: productParameterExpression, propertyName: nameof(Product.Name)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;propertyName: nameof(string.Length)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;right: Expression.Constant(10)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters: productParameterExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(predicateExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;Product&amp;gt;&amp;gt;whereMethod = Queryable.Where;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression whereCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: whereMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: sourceConstantExpression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.Quote(predicateExpression));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;whereQueryable = sourceQueryProvider
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.CreateQuery&amp;lt;Product&amp;gt;(whereCallExpression); // EntityQueryable&amp;lt;Product&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider whereQueryProvider = whereQueryable.Provider; // EntityQueryProvider.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression = product =&amp;gt; product.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;body: Expression.Property(productParameterExpression, nameof(Product.Name)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters: productParameterExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(selectorExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;, IQueryable&amp;lt;string&amp;gt;&amp;gt;selectMethod = Queryable.Select;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression selectCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: selectMethod.Method,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: whereCallExpression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.Quote(selectorExpression));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;selectQueryable = whereQueryProvider
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.CreateQuery&amp;lt;string&amp;gt;(selectCallExpression); // EntityQueryable&amp;lt;Product&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;string&amp;gt;iterator = selectQueryable.GetEnumerator()) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iterator.Current.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here are the steps how the fluent query builds its query expression tree:&lt;/p&gt;
&lt;p&gt;· Build data source:&lt;/p&gt;
&lt;p&gt;o The initial source IQueryable&amp;lt;T&amp;gt; is a DbSet&amp;lt;T&amp;gt; instance given by EF Core. It wraps an expression and a query provider:&lt;/p&gt;
&lt;p&gt;§ The expression is a ConstantExpression expression representing the data source.&lt;/p&gt;
&lt;p&gt;§ The query provider is an EntityQueryProvider instance automatically created by EF Core.&lt;/p&gt;
&lt;p&gt;· Build Where query:&lt;/p&gt;
&lt;p&gt;o A predicate expression is built for Where,&lt;/p&gt;
&lt;p&gt;o Where accepts the IQueryable&amp;lt;T&amp;gt; source. But actually Where only needs the source’s expression and query provider. A MethodCallExpression expression is built to represent a call of Where itself with 2 arguments, the source and the predicate expression. Then source query provider’s CreateQuery method is called with the MethodCallExpression expression just built, and return an IQueryable&amp;lt;T&amp;gt; query, which wraps:&lt;/p&gt;
&lt;p&gt;§ The MethodCallExpression expression representing current Where call&lt;/p&gt;
&lt;p&gt;§ The same query privider from its source.&lt;/p&gt;
&lt;p&gt;· Build Select query:&lt;/p&gt;
&lt;p&gt;o A selector expression is built for Select&lt;/p&gt;
&lt;p&gt;o Select accepts the IQueryable&amp;lt;T&amp;gt; returned by Where as source. Again, Select only needs the expression and query provider from source. A MethodCallExpression expression is built to represent a call to Select itself with 2 arguments, the source and the selector expression. Then source query provider’s CreateQuery method is called with the MethodCallExpression expression just built, and return an IQueryable&amp;lt;T&amp;gt; query, which wraps:&lt;/p&gt;
&lt;p&gt;§ The MethodCallExpression expression representing current Select call&lt;/p&gt;
&lt;p&gt;§ The same query privider from its source.&lt;/p&gt;
&lt;p&gt;So, the final IQueryable&amp;lt;T&amp;gt; query’s Expression property is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;p&gt;MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Object = null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Arguments
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;Product&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Method = Queryable.Where&amp;lt;Product&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Object = null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Arguments
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ConstantExpression (NodeType = Constant, Type = IQueryable&amp;lt;Product&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Value = new EntityQueryable&amp;lt;Product&amp;gt;(adventureWorks.GetService&amp;lt;IAsyncQueryProvider&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Operand
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, bool&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Body
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_BinaryExpression (NodeType = GreaterThan, Type = bool)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_MemberExpression (NodeType = MemberAccess, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Member = &quot;Length&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_MemberExpression (NodeType = MemberAccess, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Member = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ConstantExpression (NodeType = Constant, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Value = 10
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Operand
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Body
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_MemberExpression (NodeType = MemberAccess, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Member = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Name = &quot;product&quot;&lt;/p&gt;
&lt;p&gt;This also demonstrates that lambda expression, extension methods, and LINQ query expression are powerful language features of C#. The above a rich abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;p&gt;internal static void WhereAndSelectQuery(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;products = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; products =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// from product in adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// where product.Name.Length &amp;gt; 10
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// select product.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other kind of query returning a single value works in the similar way. Take above First as example:&lt;/p&gt;
&lt;p&gt;internal static void SelectAndFirst(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string first = adventureWorks.Products.Select(product =&amp;gt; product.Name).First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string first = selectQueryable.First().WriteLine(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the initial source and and Select query are the same as the previous example. So this time, just unwrap the First query. The above First query is equivalent to:&lt;/p&gt;
&lt;p&gt;internal static void SelectAndFirstLinqExpressions(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;sourceQueryable = adventureWorks.Products;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression selectCallExpression = (MethodCallExpression)selectQueryable.Expression;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider selectQueryProvider = selectQueryable.Provider; // DbQueryProvider.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string first = selectQueryable.First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IQueryable&amp;lt;string&amp;gt;, string&amp;gt; firstMethod = Queryable.First;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression firstCallExpression = Expression.Call(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;method: firstMethod.Method, arg0: selectCallExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string first = selectQueryProvider.Execute&amp;lt;string&amp;gt;(firstCallExpression).WriteLine(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In First query, the MethodCallExpression expression is built to represent current First call. The difference is, then query provider’s Execute method is called instead of CreateQuery, so that a query result is returned instead of a query.&lt;/p&gt;
&lt;p&gt;Similarly, the last expression tree built inside First, is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;p&gt;MethodCallExpression (NodeType = Call, Type = string)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Method = Queryable.First&amp;lt;string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Object = null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Arguments
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Object = null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Arguments
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ConstantExpression (NodeType = Constant, Type = IQueryable&amp;lt;Product&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Value = new EntityQueryable&amp;lt;Product&amp;gt;(adventureWorks.GetService&amp;lt;IAsyncQueryProvider&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Operand
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Body
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_MemberExpression (NodeType = MemberAccess, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Member = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ParameterExpression (NodeType = Parameter, Type = Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Name = &quot;product&quot;&lt;/p&gt;
&lt;p&gt;And again, the entire abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;p&gt;internal static void SelectAndFirstQuery(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string first = adventureWorks.Products.Select(product =&amp;gt; product.Name).First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string first = (from product in adventureWorks.Products select product.Name).First();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;.NET expression tree to database expression tree&lt;/h3&gt;
&lt;p&gt;When LINQ to Entities queries are executed by either pulling values from IQueryable&amp;lt;T&amp;gt;, or calling IQueryProvider.Execute, EF Core compiles .NET expression tree to database expression tree.&lt;/p&gt;
&lt;h3&gt;Database query abstract syntax tree&lt;/h3&gt;
&lt;p&gt;The logic of LINQ to Entities can be represented by .NET expression tree, and EF Core also use expression tree to represent the database query logic. For example, EF Core base libraries provides the Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpression type to represent a database SELECT query:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.Query.Expressions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class SelectExpression : TableExpressionBase
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IReadOnlyList&amp;lt;Expression&amp;gt; Projection { get; } // SELECT.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual bool IsDistinct { get; set; } // DISTINCT.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Expression Limit { get; set; } // TOP.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IReadOnlyList&amp;lt;TableExpressionBase&amp;gt; Tables { get; } // FROM.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Expression Predicate { get; set; } // WHERE.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IReadOnlyList&amp;lt;Ordering&amp;gt; OrderBy { get; } // ORDER BY.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Expression Offset { get; set; } // OFFSET.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override Type Type { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following are are all the database expressions provided by EF Core and the Remotion.Linq library used by EF Core, which are all derived from the Expression type:&lt;/p&gt;
&lt;p&gt;· AggregateExpression&lt;/p&gt;
&lt;p&gt;o MaxExpression&lt;/p&gt;
&lt;p&gt;o MinExpression&lt;/p&gt;
&lt;p&gt;o SumExpression&lt;/p&gt;
&lt;p&gt;· AliasExpression&lt;/p&gt;
&lt;p&gt;· ColumnExpression&lt;/p&gt;
&lt;p&gt;· CountExpression&lt;/p&gt;
&lt;p&gt;· DatePartExpression&lt;/p&gt;
&lt;p&gt;· DiscriminatorPredicateExpression&lt;/p&gt;
&lt;p&gt;· ExistsExpression&lt;/p&gt;
&lt;p&gt;· ExplicitCastExpression&lt;/p&gt;
&lt;p&gt;· InExpression&lt;/p&gt;
&lt;p&gt;· IsNullExpression&lt;/p&gt;
&lt;p&gt;· LikeExpression&lt;/p&gt;
&lt;p&gt;· NotNullableExpression&lt;/p&gt;
&lt;p&gt;· NullConditionalExpression&lt;/p&gt;
&lt;p&gt;· PartialEvaluationExceptionExpression&lt;/p&gt;
&lt;p&gt;· PropertyParameterExpression&lt;/p&gt;
&lt;p&gt;· QuerySourceReferenceExpression&lt;/p&gt;
&lt;p&gt;· RowNumberExpression&lt;/p&gt;
&lt;p&gt;· SqlFunctionExpression&lt;/p&gt;
&lt;p&gt;· StringCompareExpression&lt;/p&gt;
&lt;p&gt;· SubQueryExpression&lt;/p&gt;
&lt;p&gt;· TableExpressionBase&lt;/p&gt;
&lt;p&gt;o CrossJoinExpression&lt;/p&gt;
&lt;p&gt;o FromSqlExpression&lt;/p&gt;
&lt;p&gt;o JoinExpressionBase&lt;/p&gt;
&lt;p&gt;§ InnerJoinExpression&lt;/p&gt;
&lt;p&gt;§ LeftOuterJoinExpression&lt;/p&gt;
&lt;p&gt;o LateralJoinExpression&lt;/p&gt;
&lt;p&gt;o SelectExpression&lt;/p&gt;
&lt;p&gt;o TableExpression&lt;/p&gt;
&lt;p&gt;· VBStringComparisonExpression&lt;/p&gt;
&lt;h3&gt;Compile LINQ expressions to database expressions&lt;/h3&gt;
&lt;p&gt;EF Core calls the third party library Remotion.Linq to compile LINQ expression tree to a query model, then EF Core compiles the query model to database expression tree, which is a SelectExpression instance. The following Compile function demonstrates how the compilation can be done. It accepts a LINQ expression tree, and returns a tuple of SelectExpression, and its parameters if any:&lt;/p&gt;
&lt;p&gt;public static (SelectExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt;) Compile(this DbContext dbContext, Expression linqExpression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;QueryContext queryContext = dbContext
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryContextFactory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;QueryCompilationContext compilationContext = dbContext
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryCompilationContextFactory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create(async: false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;QueryCompiler queryCompiler = (QueryCompiler)dbContext.GetService&amp;lt;IQueryCompiler&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;linqExpression = queryCompiler.ExtractParameters(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;linqExpression,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;queryContext,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dbContext.GetService&amp;lt;IDiagnosticsLogger&amp;lt;DbLoggerCategory.Query&amp;gt;&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;linqExpression = dbContext
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryTranslationPreprocessorFactory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create(compilationContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Process(linqExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ShapedQueryExpression queryExpression = (ShapedQueryExpression)dbContext
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryableMethodTranslatingExpressionVisitorFactory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create(dbContext.Model)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visit(linqExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;queryExpression = (ShapedQueryExpression)dbContext
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryTranslationPostprocessorFactory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create(compilationContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Process(queryExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ((SelectExpression)queryExpression.QueryExpression, queryContext.ParameterValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So above Where and Select query’s expression tree can be compiled as:&lt;/p&gt;
&lt;p&gt;internal static void CompileWhereAndSelectExpressions(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression linqExpression =adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; product.Name).Expression;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(SelectExpression DatabaseExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt; Parameters) compilation =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks.Compile(linqExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;compilation.DatabaseExpression.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;compilation.Parameters.WriteLines(parameter =&amp;gt; $&quot;{parameter.Key}: {parameter.Value}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The compiled SelectExpression is the same as the following SelectExpression built on the fly:&lt;/p&gt;
&lt;p&gt;internal static SelectExpression WhereAndSelectDatabaseExpressions(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryableMethodTranslatingExpressionVisitorFactory expressionVisitorFactory = adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryableMethodTranslatingExpressionVisitorFactory&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ISqlExpressionFactory expressionFactory = adventureWorks.GetService&amp;lt;ISqlExpressionFactory&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEntityType entityType = adventureWorks.Model.FindEntityType(typeof(Product));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression databaseExpression = expressionFactory.Select(entityType);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EntityProjectionExpression projectionExpression = (EntityProjectionExpression)databaseExpression.GetMappedProjection(new ProjectionMember());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ColumnExpression columnExpression = projectionExpression.BindProperty(entityType.FindProperty(nameof(Product.Name)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseExpression.ApplyPredicate(expressionFactory.MakeBinary(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExpressionType.GreaterThan,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expressionFactory.Convert(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expressionFactory.Function(&quot;LEN&quot;, new SqlExpression[] { columnExpression }, typeof(long)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;typeof(int)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new SqlConstantExpression(Expression.Constant(10), null),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;null));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseExpression.AddToProjection(columnExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return databaseExpression.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;p&gt;SelectExpression (NodeType = Extension, Type = string)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Porjection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ColumnExpression (NodeType = Extension, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Property = Product.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Table
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_TableExpression (NodeType = Extension, Type = object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Schema = &quot;Production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Alias = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Tables
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_TableExpression (NodeType = Extension, Type = object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Schema = &quot;Production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Alias = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Predicate
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_BinaryExpression (NodeType = GreaterThan, Type = bool)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ExplicitCastExpression (NodeType = Extension, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Operand
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_SqlFunctionExpression (NodeType = Extension, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_FunctionName = &quot;LEN&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Arguments
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ColumnExpression (NodeType = Extension, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Property = Product.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Table
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_TableExpression (NodeType = Extension, Type = object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Schema = &quot;Production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Alias = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ConstantExpression (NodeType = Constant, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Value = 1&lt;/p&gt;
&lt;p&gt;Similarly, the other Select and First query’s expression tree is compiled to abstract syntax tree the same as the following:&lt;/p&gt;
&lt;p&gt;internal static SelectExpression SelectAndFirstDatabaseExpressions(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryableMethodTranslatingExpressionVisitorFactory expressionVisitorFactory = adventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetService&amp;lt;IQueryableMethodTranslatingExpressionVisitorFactory&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ISqlExpressionFactory expressionFactory = adventureWorks.GetService&amp;lt;ISqlExpressionFactory&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEntityType entityType = adventureWorks.Model.FindEntityType(typeof(Product));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression databaseExpression = expressionFactory.Select(entityType);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EntityProjectionExpression projectionExpression = (EntityProjectionExpression)databaseExpression.GetMappedProjection(new ProjectionMember());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ColumnExpression columnExpression = projectionExpression.BindProperty(entityType.FindProperty(nameof(Product.Name)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseExpression.AddToProjection(columnExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseExpression.ApplyLimit(expressionFactory.ApplyDefaultTypeMapping(new SqlConstantExpression(Expression.Constant(1), null)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return databaseExpression.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And this abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;p&gt;SelectExpression (NodeType = Extension, Type = string)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Limit
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ConstantExpression (NodeType = Constant, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Value = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Porjection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ColumnExpression (NodeType = Extension, Type = string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Property = Product.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Table
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_TableExpression (NodeType = Extension, Type = object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Schema = &quot;Production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;Product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Alias = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Tables
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_TableExpression (NodeType = Extension, Type = object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Schema = &quot;Production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Name = &quot;Product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Alias = &quot;product&quot;&lt;/p&gt;
&lt;h3&gt;Compile LINQ queries&lt;/h3&gt;
&lt;p&gt;EF Core first calls Remotion.Linq library to compile LINQ query function call nodes to QueryModel. Under Remotion.Linq.Parsing.Structure.IntermediateModel namespace, Remotion.Linq provides IExpressionNode interface, and many types implementing that interface, where each type can process a certain kind of query function call, for example:&lt;/p&gt;
&lt;p&gt;· MethodCallExpression node representing Queryable.Where call is processed by WhereExpressionNode, and converted to Remotion.Linq.Clauses.WhereClause, which is a part of QueryModel&lt;/p&gt;
&lt;p&gt;· MethodCallExpression node representing Queryable.Select call is processed by SelectExpressionNode, and converted to Remotion.Linq.Clauses.SelectClause, which is a part of QueryModel&lt;/p&gt;
&lt;p&gt;· MethodCallExpression node representing Queryable.First or Queryable.FirstOrDefault call is processed by FirstExpressionNode, and converted to Remotion.Linq.Clauses.ResultOperators.FirstResultOperator, which is a part of QueryModel&lt;/p&gt;
&lt;p&gt;etc. Then EF Core continues to compile QueryModel to SelectExpression. For example:&lt;/p&gt;
&lt;p&gt;· WhereClause is converted to predicate child nodes of the SelectExpression&lt;/p&gt;
&lt;p&gt;· SelectClause is converted to projection child nodes of the SelectExpression&lt;/p&gt;
&lt;p&gt;· FirstResultOperator is converted to limit child node of the SelectExpression&lt;/p&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;h3&gt;Compile .NET API calls&lt;/h3&gt;
&lt;p&gt;The above Where query’s predicate has a logic to call string.Length and compare the result to a constant. EF Core provides translator types under Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal namespace to translate these .NET API calls. Here MemberExpression node representing string.Length call is processed by SqlServerStringLengthTranslator, and converted to a SqlFunctionExpression node representing SQL database function LEN call:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class SqlServerStringLengthTranslator : IMemberTranslator
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Expression Translate(MemberExpression memberExpression) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;memberExpression.Expression != null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp;memberExpression.Expression.Type == typeof(string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp; memberExpression.Member.Name == nameof(string.Length)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? new SqlFunctionExpression(&quot;LEN&quot;, memberExpression.Type, new Expression[] { memberExpression.Expression })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There are many other translators to cover other basic .NET APIs of System.String, System.Enum, System.DateTime, System.Guid, System.Math, for example:&lt;/p&gt;
&lt;p&gt;· MethodCallExpression node representing string.Contains call (e.g. product.Name.Contains(“M”)) is processed by SqlServerContainsOptimizedTranslator, and converted to a BinaryExpression node representing SQL database int comparison, where the left child node is a SqlFunctionExpression node representing SQL database function CHARINDEX call, and the right child node is a ConstantExpression node representing 0 (e.g. CHARINDEX(N&apos;M&apos;, product.Name) &amp;gt; 0)&lt;/p&gt;
&lt;p&gt;· MethodCallExpression node representing Math.Ceiling call is processed by SqlServerMathCeilingTranslator, and converted to SqlFunctionExpression node representing SQL database function CEILING call&lt;/p&gt;
&lt;p&gt;· MemberExpression node representing DateTime.Now or DateTime.UtcNow property access, is processed by SqlServerDateTimeNowTranslator, and converted to SqlFunctionExpression node representing SQL database function GETDATE or GETUTCDATE call&lt;/p&gt;
&lt;p&gt;· The extension methods for EF.Functions are also translated to SQL database function calls or operators. For example, EF.Functions.Like is processed by LikeTranslator, and converted to LikeExpression node representing LIKE operator.&lt;/p&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;There are also a few other APIs covered with other EF Core components. For example, In Remotion.Linq, MethodCallExpression node representing Enumerable.Contains or List&amp;lt;T&amp;gt;.Contains call is converted to to Remotion.Linq.Clauses.ResultOperators.ContainsResultOperator. Then in EF Core, ContainsResultOperator is processed by Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor. and converted to InExpression node representing SQL database IN operation.&lt;/p&gt;
&lt;h3&gt;Remote API call vs. local API call&lt;/h3&gt;
&lt;p&gt;Apparently EF Core can only compile the supported .NET API calls, like the above string.Length call. It cannot compile arbitrary API calls. The following example wraps the string.Length call and result comparison with constant into a custom predicate:&lt;/p&gt;
&lt;p&gt;private static bool FilterName(string name) =&amp;gt; name.Length &amp;gt; 10;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectWithCustomPredicate(AdventureWorks adventureWorks)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;source = adventureWorks.Products;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;products = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(product =&amp;gt; FilterName(product.Name))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; product.Name); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [product].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;At compile time, the predicate expression tree has a MethodCallExpression node representing FilterName call, which apparently cannot be compiled to SQL by EF Core. In this case, EF Core execute FilterName locally.&lt;/p&gt;
&lt;h3&gt;Compile database functions and operators&lt;/h3&gt;
&lt;p&gt;Some database APIs cannot be translated from .NET Standard APIs. For example, there is no mapping .NET API for SQL database LIKE operator, DATEDIFF function, etc. EF Core defines mapping functions to address these scenarios. These functions can be used through Microsoft.EntityFrameworkCore.EF type’s Functions property:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class EF
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static DbFunctions Functions { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Extension methods are defined for the DbFunctions output type to represent database functions and operators. As fore mentioned, EF Core implements a provider model, so these mapping functions are provides in 2 levels. The EF Core base library provides mapping functions which should be supported by all database providers, like the LIKE operator:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class DbFunctionsExtensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Like(this DbFunctions _, string matchExpression, string pattern);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These are also called canonical functions. The mapping funcions for specific database is provided by the database provider library. For example, Microsoft.EntityFrameworkCore.SqlServer.dll library provides DateDiffDay extension method to represent SQL database’s DATEDIFF function for day, and provides Contains extension method to represent SQL database’s CONTAINS function, etc.&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class SqlServerDbFunctionsExtensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Contains(this DbFunctions _, string propertyReference, string searchCondition);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int DateDiffDay(this DbFunctions _, DateTime startDate, DateTime endDate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example filters the product’s names with a pattern. In the following LINQ to Entities query expression tree, the MethodCallExpression node representing Like call is compiled to a LikeExpression node representing the LIKE operator:&lt;/p&gt;
&lt;p&gt;internal static void DatabaseOperator(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt;products = adventureWorks.Products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(product =&amp;gt; product.Name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(name =&amp;gt; EF.Functions.Like(name, &quot;%Touring%50%&quot;)); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [product].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [product].[Name] LIKE N&apos;%Touring%50%&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following LINQ to Entities query calculates the number of days between current time and photo’s last modified time. In the following LINQ to Entities query expression tree, the MethodCallExpression node representing DateDiffDay call can be compiled to a SqlFunctionExpression node representing DATEDIFF call:&lt;/p&gt;
&lt;p&gt;internal static void DatabaseFunction(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var photos = adventureWorks.ProductPhotos.Select(photo =&amp;gt; new
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LargePhotoFileName = photo.LargePhotoFileName,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UnmodifiedDays = EF.Functions.DateDiffDay(photo.ModifiedDate, DateTime.UtcNow)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;photos.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [photo].[LargePhotoFileName], DATEDIFF(DAY, [photo].[ModifiedDate], GETUTCDATE()) AS [UnmodifiedDays]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductPhoto] AS [photo]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Database expression tree to database query&lt;/h3&gt;
&lt;p&gt;With database expression tree, EF can traverse and compile it to SQL query.&lt;/p&gt;
&lt;h3&gt;SQL generator and SQL command&lt;/h3&gt;
&lt;p&gt;The SQL database provider of EF Core provides a SQL generator to traverse the compiled database query abstract syntactic tree, and generate SQL database specific remote SQL query. EF Core defines SQL generator as Microsoft.EntityFrameworkCore.Query.Sql.IQuerySqlGenerator interface:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.Query.Sql&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQuerySqlGenerator
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRelationalCommand GenerateSql(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IReadOnlyDictionary&amp;lt;string, object&amp;gt;parameterValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is implemented by Microsoft.EntityFrameworkCore.Query.Sql.Internal.SqlServerQuerySqlGenerator. SQL generator wraps a database expression tree inside, and provides a GenerateSql method, which returns Microsoft.EntityFrameworkCore.Storage.IRelationalCommand to represents generated SQL:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore.Storage&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IRelationalCommand
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string CommandText { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IReadOnlyList&amp;lt;IRelationalParameter&amp;gt; Parameters { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;RelationalDataReader ExecuteReader(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRelationalConnection connection,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IReadOnlyDictionary&amp;lt;string, object&amp;gt;parameterValues);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is implemented by Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand in Microsoft.EntityFrameworkCore.Relational package.&lt;/p&gt;
&lt;h3&gt;Generate SQL from database expression tree&lt;/h3&gt;
&lt;p&gt;The following extension method of DbContext can be defined to accepot a database command tree, and generate SQL:&lt;/p&gt;
&lt;p&gt;public static IRelationalCommand Generate(this DbContext dbContext, SelectExpression databaseExpression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQuerySqlGeneratorFactory sqlGeneratorFactory = dbContext.GetService&amp;lt;IQuerySqlGeneratorFactory&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;QuerySqlGenerator sqlGenerator = sqlGeneratorFactory.Create();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sqlGenerator.GetCommand(databaseExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above WhereAndSelectDatabaseExpressions and SelectAndFirstDatabaseExpressions functions build database expression trees from scratch. Take them as an example to generate SQL:&lt;/p&gt;
&lt;p&gt;internal static void WhereAndSelectSql(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression databaseExpression = WhereAndSelectDatabaseExpressions(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;adventureWorks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRelationalCommand sql = adventureWorks.Generate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;databaseExpression: databaseExpression, parameters: null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sql.CommandText.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [product].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE CAST(LEN([product].[Name]) AS int)&amp;gt; 10
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstSql(AdventureWorks adventureWorks)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression databaseExpression = SelectAndFirstDatabaseExpressions(adventureWorks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRelationalCommand sql = adventureWorks.Generate(databaseExpression: databaseExpression, parameters: null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sql.CommandText.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT TOP(1) [product].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[Product] AS [product]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SQL generator traverses the command tree nodes, a specific Visit overloads is called for each supported node type. It generates SELECT clause from DbProjectionExpression node, FROM clause from DbScanExpression node, WHERE clause from DbFilterExpression node, LIKE operator from DbLikeExpression, etc.&lt;/p&gt;
&lt;p&gt;So finally LINQ to Entities queries are translated to remote SQL database queries. The next part discusses the query execution and data loading.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (4) Query Methods (Operators)</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-4-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-4-query-methods/</guid><description>This part discusses how to query SQL database with the defined mapping entities. In EF Core, LINQ to Entities supports most of the standard queries provided by Queryable:</description><pubDate>Mon, 07 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;This part discusses how to query SQL database with the defined mapping entities. In EF Core, LINQ to Entities supports most of the standard queries provided by Queryable:&lt;/p&gt;
&lt;p&gt;1. Sequence queries: return a new IQueryable&amp;lt;T&amp;gt; source&lt;/p&gt;
&lt;p&gt;o Filtering (restriction): Where, OfType*&lt;/p&gt;
&lt;p&gt;o Mapping (projection): Select&lt;/p&gt;
&lt;p&gt;o Generation: DefaultIfEmpty*&lt;/p&gt;
&lt;p&gt;o Grouping: GroupBy*&lt;/p&gt;
&lt;p&gt;o Join: Join, GroupJoin, SelectMany, Select&lt;/p&gt;
&lt;p&gt;o Concatenation: Concat*&lt;/p&gt;
&lt;p&gt;o Set: Distinct, GroupBy*, Union*, Intersect*, Except*&lt;/p&gt;
&lt;p&gt;o Convolution: ~Zip~&lt;/p&gt;
&lt;p&gt;o Partitioning: Take, Skip, ~TakeWhile~, ~SkipWhile~&lt;/p&gt;
&lt;p&gt;o Ordering: OrderBy*, ThenBy, OrderByDescending*, ThenByDescending, ~Reverse~&lt;/p&gt;
&lt;p&gt;o Conversion: Cast, AsQueryable&lt;/p&gt;
&lt;p&gt;2. Value queries: return a single value&lt;/p&gt;
&lt;p&gt;o Element: First, FirstOrDefault, Last*, LastOrDefault*, ~ElementAt~, ~ElementAtOrDefault~, Single, SingleOrDefault&lt;/p&gt;
&lt;p&gt;o Aggregation: ~Aggregate~, Count, LongCount, Min, Max, Sum, Average*&lt;/p&gt;
&lt;p&gt;o Quantifier: All, Any, Contains&lt;/p&gt;
&lt;p&gt;o Equality: ~SequenceEqual~&lt;/p&gt;
&lt;p&gt;In above list:&lt;/p&gt;
&lt;p&gt;· The crossed queries are not supported by LINQ to Entities (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb738550.aspx&quot;&gt;the list provided by MDSN&lt;/a&gt; is not up to date), because they cannot be translated to proper SQL database operations. For example, SQL database has no built-in Zip operation support. Calling these crossed queries throws NotSupportedException at runtime&lt;/p&gt;
&lt;p&gt;· The underlined queries have some overloads supported by LINQ to Entities, and other overloads not supported:&lt;/p&gt;
&lt;p&gt;o For GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except, Contains, the overloads accepting IEqualityComparer&amp;lt;T&amp;gt; parameter are not supported, because apparently IEqualityComparer&amp;lt;T&amp;gt; has no equivalent SQL translation&lt;/p&gt;
&lt;p&gt;o For OrderBy, ThenBy, OrderByDescending, ThenByDescending, the overloads with IComparer&amp;lt;T&amp;gt; parameter are not supported&lt;/p&gt;
&lt;p&gt;o For Where, Select, SelectMany, the indexed overloads are not supported&lt;/p&gt;
&lt;p&gt;· In EF Core, the queries marked with * can execute the query locally in some cases, without being translated to SQL.&lt;/p&gt;
&lt;p&gt;For LINQ to Entities, apparently these queries enable fluent chaining, implement the same LINQ query expression pattern as LINQ to Objects and Parallel LINQ. So in this part, most of the LINQ to Entities queries are demonstrated with queries.&lt;/p&gt;
&lt;h4&gt;Sequence queries&lt;/h4&gt;
&lt;p&gt;Similar to the other kinds of LINQ, LINQ to Entities implements deferred execution for these queries returning IQueryable&amp;lt;T&amp;gt;. The SQL query is translated and executed only when trying to pull the result value from IQueryable&amp;lt;T&amp;gt; for the first time.&lt;/p&gt;
&lt;h6&gt;Filtering (restriction)&lt;/h6&gt;
&lt;p&gt;EF Core translates Where function call to WHERE clause in SQL, and translates the predicate expression tree (again, not predicate function) to the condition in WHERE clause. The following example queries categories with ProductCategoryID greater than 0:&lt;/p&gt;
&lt;p&gt;internal static void Where(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0); // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines(category =&amp;gt; category.Name); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] &amp;gt; 0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When WriteLines executes, it pulls the results from the query represented by IQueryable&amp;lt;ProductCategory&amp;gt;. At this moment, the query is translated to SQL, and executed in database, then SQL execution results are read by EF Core and yielded.&lt;/p&gt;
&lt;p&gt;The C# || operator in the predicate expression tree is translated to SQL OR operator in WHERE clause:&lt;/p&gt;
&lt;p&gt;internal static void WhereWithOr(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;&lt;/p&gt;
&lt;p&gt;category.ProductCategoryID &amp;lt; 2 || category.ProductCategoryID &amp;gt; 3); // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines(category =&amp;gt; category.Name); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE ([category].[ProductCategoryID] &amp;lt; 2) OR ([category].[ProductCategoryID] &amp;gt; 3)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, the C# &amp;amp;&amp;amp; operator is translated to SQL AND operator:&lt;/p&gt;
&lt;p&gt;internal static void WhereWithAnd(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;&lt;/p&gt;
&lt;p&gt;category.ProductCategoryID &amp;gt; 0 &amp;amp;&amp;amp; category.ProductCategoryID &amp;lt; 5); // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines(category =&amp;gt; category.Name); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE ([category].[ProductCategoryID] &amp;gt; 0) AND ([category].[ProductCategoryID] &amp;lt; 5)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Multiple Where calls are also translated to one single WHERE clause with AND:&lt;/p&gt;
&lt;p&gt;internal static void WhereAndWhere(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source&lt;/p&gt;
&lt;p&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0)&lt;/p&gt;
&lt;p&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 5); // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines(category =&amp;gt; category.Name); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE ([category].[ProductCategoryID] &amp;gt; 0) AND ([category].[ProductCategoryID] &amp;lt; 5)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other filtering query, OfType, can be used for entity types in inheritance hierarchy. And it is equivalent to Where query with is operator. The following examples both query sales transactions from all transactions:&lt;/p&gt;
&lt;p&gt;internal static void WhereWithIs(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; transactions = source.Where(transaction =&amp;gt; transaction is SalesTransactionHistory); // Define query.&lt;/p&gt;
&lt;p&gt;transactions.WriteLines(transaction =&amp;gt; $&quot;{transaction.GetType().Name} {transaction.TransactionDate} {transaction.ActualCost}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [transaction].[TransactionID], [transaction].[ActualCost], [transaction].[ProductID], [transaction].[Quantity], [transaction].[TransactionDate], [transaction].[TransactionType]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[TransactionHistory] AS [transaction]&lt;/p&gt;
&lt;p&gt;// WHERE [transaction].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;) AND ([transaction].[TransactionType] = N&apos;S&apos;)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void OfTypeEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;WorkTransactionHistory&amp;gt; transactions = source.OfType&amp;lt;WorkTransactionHistory&amp;gt;(); // Define query.&lt;/p&gt;
&lt;p&gt;transactions.WriteLines(transaction =&amp;gt; $&quot;{transaction.GetType().Name} {transaction.TransactionDate} {transaction.ActualCost}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [t].[TransactionID], [t].[ActualCost], [t].[ProductID], [t].[Quantity], [t].[TransactionDate], [t].[TransactionType]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[TransactionHistory] AS [t]&lt;/p&gt;
&lt;p&gt;// WHERE [t].[TransactionType] = N&apos;W&apos;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When primitive type is specified for OfType, it works locally. The following example queries products with ProductSubcategoryID not null:&lt;/p&gt;
&lt;p&gt;internal static void OfTypePrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;int&amp;gt; products = source.Select(product =&amp;gt; product.ProductSubcategoryID).OfType&amp;lt;int&amp;gt;(); // Define query.&lt;/p&gt;
&lt;p&gt;products.ToArray().Length.WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [p].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [p]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In EF Core, the above query is translated to a basic SELECT statement without filtering. EF Core executes the translated SQL to query the specified nullable int column of all rows to local, then the int results are locally filtered from all the nullable int results.&lt;/p&gt;
&lt;h6&gt;Mapping (projection)&lt;/h6&gt;
&lt;p&gt;In above queries, Queryable.Select is not called, and the query results are entities. So in the translated SQL, the SELECT clause queries all the mapped columns in order to construct the result entities. When Select is called, the selector expression tree is translated into SELECT clause. The following example queries persons’ full names by concatenating the first name and last name:&lt;/p&gt;
&lt;p&gt;internal static void Select(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Person&amp;gt; source = adventureWorks.People;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; names = source.Select(person =&amp;gt;&lt;/p&gt;
&lt;p&gt;person.FirstName + &quot; &quot; + person.LastName); // Define query.&lt;/p&gt;
&lt;p&gt;names.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT ([person].[FirstName] + N&apos; &apos;) + [person].[LastName]&lt;/p&gt;
&lt;p&gt;// FROM [Person].[Person] AS [person]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In EF Core, Select also work with anonymous type. For example:&lt;/p&gt;
&lt;p&gt;internal static void SelectAnonymousType(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source.Select(product =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Name = product.Name, IsExpensive = product.ListPrice &amp;gt; 1_000 }); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], CASE&lt;/p&gt;
&lt;p&gt;// WHEN [product].[ListPrice] &amp;gt; 1000.0&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In EF Core, Select supports entity type too:&lt;/p&gt;
&lt;p&gt;internal static void SelectEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; products = source&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 1_000)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new Product()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;ProductID = product.ProductID,&lt;/p&gt;
&lt;p&gt;Name = product.Name&lt;/p&gt;
&lt;p&gt;}); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(product =&amp;gt; $&quot;{product.ProductID}: {product.Name}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID], [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 1000.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Generation&lt;/h6&gt;
&lt;p&gt;As fore mentioned, DefaultIfEmpty is the only built-in generation query:&lt;/p&gt;
&lt;p&gt;internal static void DefaultIfEmptyEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source&lt;/p&gt;
&lt;p&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(); // Define query.&lt;/p&gt;
&lt;p&gt;categories.ForEach( // Execute query.&lt;/p&gt;
&lt;p&gt;category =&amp;gt; (category == null).WriteLine()); // True&lt;/p&gt;
&lt;p&gt;// SELECT [t].[ProductCategoryID], [t].[Name]&lt;/p&gt;
&lt;p&gt;// FROM (&lt;/p&gt;
&lt;p&gt;// SELECT NULL AS [empty]&lt;/p&gt;
&lt;p&gt;// ) AS [empty]&lt;/p&gt;
&lt;p&gt;// LEFT JOIN (&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] &amp;lt; 0&lt;/p&gt;
&lt;p&gt;// ) AS [t] ON 1 = 1&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the above query, Where function call is translated to SQL query with WHERE clause. Since DefaultIfEmpty should yield at least 1 entity, it is translated to LEFT JOIN with a single row table on a condition that always holds, so that the final query result is guaranteed to have at least 1 row. Here Where filters out all entities, in another word, the right table of LEFT JOIN has no rows, so the LEFT JOIN results 1 row, where all columns are NULL, including primary key. Therefore, DefaultIfEmpty yields a null entity. Besides entity type, DefaultIfEmpty works with primitive type in the same way.&lt;/p&gt;
&lt;p&gt;The other DefaultIfEmpty overload accepts a specified default value. EF Core does not translate it to SQL, but execute the query logic locally. For example:&lt;/p&gt;
&lt;p&gt;internal static void DefaultIfEmptyWithDefaultEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;ProductCategory @default = new ProductCategory() { Name = nameof(ProductCategory) };&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; categories = source&lt;/p&gt;
&lt;p&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(@default); ; // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines( // Execute query.&lt;/p&gt;
&lt;p&gt;category =&amp;gt; category?.Name); // ProductCategory&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] &amp;lt; 0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the source query for DefaultIfEmpty is translated to SQL and executed, then EF Core reads the results to local, and detect the results locally. If there is no result row, the specified default value is used. DefaultIfEmpty works for specified default primitive value locally too.&lt;/p&gt;
&lt;p&gt;internal static void DefaultIfEmptyWithDefaultPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;int&amp;gt; categories = source&lt;/p&gt;
&lt;p&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)&lt;/p&gt;
&lt;p&gt;.Select(category =&amp;gt; category.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(-1); // Define query.&lt;/p&gt;
&lt;p&gt;categories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] &amp;lt; 0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice the default value –1 is translated into the remote SQL query. It is the query result if the right table of left outer join is empty. So there is no local query or local detection executed.&lt;/p&gt;
&lt;p&gt;Just like in LINQ to Objects, DefaultIfEmpty can also be used to implement outer join, which is discussed later.&lt;/p&gt;
&lt;h6&gt;Grouping&lt;/h6&gt;
&lt;p&gt;When Group query is not used with aggregation query, EF Core executes grouping locally. For example. The following examples group the subcategories by category:&lt;/p&gt;
&lt;p&gt;internal static void GroupBy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; grouped = source&lt;/p&gt;
&lt;p&gt;.GroupBy(keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;.SelectMany(group =&amp;gt; group); // Define query.&lt;/p&gt;
&lt;p&gt;grouped.WriteLines(subcategory =&amp;gt; subcategory.Name); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// ORDER BY [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithElementSelector(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; groups = source.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;elementSelector: subcategory =&amp;gt; subcategory.Name); // Define query.&lt;/p&gt;
&lt;p&gt;groups.WriteLines(group =&amp;gt; $&quot;{group.Key}: {string.Join(&quot;, &quot;, group)}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// ORDER BY [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core only translates GroupBy an additional ORDER BY clause with the grouping key, so that when reading the SQL execution results to local, the subcategories appears group by group.&lt;/p&gt;
&lt;p&gt;When GroupBy is used with supported aggregation query, it is translated to GROUP BY clause. This can be done with a GroupBy overload accepting a result selector, or equivalently an additional Select query. The following examples call aggregation query Count to flatten the results, and they have identical translation:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithResultSelector(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var groups = source.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;elementSelector: subcategory =&amp;gt; subcategory.Name,&lt;/p&gt;
&lt;p&gt;resultSelector: (key, group) =&amp;gt; new { CategoryID = key, SubcategoryCount = group.Count() }); // Define query.&lt;/p&gt;
&lt;p&gt;groups.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory].[ProductCategoryID] AS [CategoryID], COUNT(*) AS [SubcategoryCount]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// GROUP BY [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void GroupByAndSelect(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var groups = source&lt;/p&gt;
&lt;p&gt;.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;elementSelector: subcategory =&amp;gt; subcategory.Name)&lt;/p&gt;
&lt;p&gt;.Select(group =&amp;gt; new { CategoryID = group.Key, SubcategoryCount = group.Count() }); // Define query.&lt;/p&gt;
&lt;p&gt;groups.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory].[ProductCategoryID] AS [CategoryID], COUNT(*) AS [SubcategoryCount]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// GROUP BY [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupBy’s key selector can return anonymous type with multiple properties to support grouping by multiple keys:&lt;/p&gt;
&lt;p&gt;internal static void GroupByMultipleKeys(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var groups = source&lt;/p&gt;
&lt;p&gt;.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: product =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;ProductSubcategoryID = product.ProductSubcategoryID,&lt;/p&gt;
&lt;p&gt;ListPrice = product.ListPrice&lt;/p&gt;
&lt;p&gt;},&lt;/p&gt;
&lt;p&gt;resultSelector: (key, group) =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;ProductSubcategoryID = key.ProductSubcategoryID,&lt;/p&gt;
&lt;p&gt;ListPrice = key.ListPrice,&lt;/p&gt;
&lt;p&gt;Count = group.Count()&lt;/p&gt;
&lt;p&gt;})&lt;/p&gt;
&lt;p&gt;.Where(group =&amp;gt; group.Count &amp;gt; 1); // Define query.&lt;/p&gt;
&lt;p&gt;groups.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductSubcategoryID], [product].[ListPrice], COUNT(*) AS [Count]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// GROUP BY [product].[ProductSubcategoryID], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// HAVING COUNT(*) &amp;gt; 1&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The additional Where query is translated to HAVING clause, as expected.&lt;/p&gt;
&lt;h6&gt;Join&lt;/h6&gt;
&lt;h6&gt;Inner join&lt;/h6&gt;
&lt;p&gt;Similar to LINQ to Objects, Join is provided for inner join. The following example simply join the subcategories and categories with foreign key:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithJoin(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer.Join(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: category =&amp;gt; category.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// join subcategory in inner&lt;/p&gt;
&lt;p&gt;// on category.ProductCategoryID equals subcategory.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[Name], [subcategory].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// INNER JOIN [Production].[ProductSubcategory] AS [subcategory] ON [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Join’s key selectors can return anonymous type to join with multiple keys:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithMultipleKeys(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; inner = adventureWorks.Transactions;&lt;/p&gt;
&lt;p&gt;var transactions = outer.Join(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: product =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { ProductID = product.ProductID, UnitPrice = product.ListPrice },&lt;/p&gt;
&lt;p&gt;innerKeySelector: transaction =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { ProductID = transaction.ProductID, UnitPrice = transaction.ActualCost / transaction.Quantity },&lt;/p&gt;
&lt;p&gt;resultSelector: (product, transaction) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Name = product.Name, Quantity = transaction.Quantity }); // Define query.&lt;/p&gt;
&lt;p&gt;// var transactions =&lt;/p&gt;
&lt;p&gt;// from product in adventureWorks.Products&lt;/p&gt;
&lt;p&gt;// join transaction in adventureWorks.Transactions&lt;/p&gt;
&lt;p&gt;// on new { ProductID = product.ProductID, UnitPrice = product.ListPrice }&lt;/p&gt;
&lt;p&gt;// equals new { ProductID = transaction.ProductID, UnitPrice = transaction.ActualCost / transaction.Quantity }&lt;/p&gt;
&lt;p&gt;// select new { Name = product.Name, Quantity = transaction.Quantity };&lt;/p&gt;
&lt;p&gt;transactions.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [transaction].[Quantity]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// INNER JOIN [Production].[TransactionHistory] AS [transaction] ON ([product].[ProductID] = [transaction].[ProductID]) AND ([product].[ListPrice] = ([transaction].[ActualCost] / [transaction].[Quantity]))&lt;/p&gt;
&lt;p&gt;// WHERE [transaction].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Just like LINQ to Objects, inner join can be done by SelectMany, Select, and GroupJoin as well. In the following example, Select returns hierarchical data, so an additional SelectMany can flatten the result:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelect(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.Select(category =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Category = category,&lt;/p&gt;
&lt;p&gt;Subcategories = inner&lt;/p&gt;
&lt;p&gt;.Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;// LEFT OUTER JOIN if DefaultIfEmpty is called.&lt;/p&gt;
&lt;p&gt;})&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories,&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// select new&lt;/p&gt;
&lt;p&gt;// {&lt;/p&gt;
&lt;p&gt;// Category = category,&lt;/p&gt;
&lt;p&gt;// Subcategories = from subcategory in inner&lt;/p&gt;
&lt;p&gt;// where category.ProductCategoryID == subcategory.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select subcategory&lt;/p&gt;
&lt;p&gt;// } into category&lt;/p&gt;
&lt;p&gt;// from subcategory in category.Subcategories&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[Name], [subcategory].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// CROSS JOIN [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core translates the above query to CROOS JOIN with WHERE clause, which is equivalent to the previous INNER JOIN query, with the same query plan.&lt;/p&gt;
&lt;p&gt;The following example implement the same inner join directly with SelectMany. Its SQL translation is the same INNER JOIN as the first Join example:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelectMany(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; inner&lt;/p&gt;
&lt;p&gt;.Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID),&lt;/p&gt;
&lt;p&gt;// LEFT OUTER JOIN if DefaultIfEmpty is called.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// from subcategory in (from subcategory in inner&lt;/p&gt;
&lt;p&gt;// where category.ProductCategoryID == subcategory.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select subcategory)&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;// Or equivalently:&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// from subcategory in inner&lt;/p&gt;
&lt;p&gt;// where category.ProductCategoryID == subcategory.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above Select and SelectMany has a Where subquery to filter the related entities to join with. The Where subquery can be substituted by collection navigation property. After the substitution, the queries are translated to the same INNER JOIN as the first Join example:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelectAndRelationship(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.Select(category =&amp;gt; new { Category = category, Subcategories = category.ProductSubcategories })&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories,&lt;/p&gt;
&lt;p&gt;// LEFT OUTER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// select new { Category = category, Subcategories = category.ProductSubcategories } into category&lt;/p&gt;
&lt;p&gt;// from subcategory in category.Subcategories&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelectManyAndRelationship(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.ProductSubcategories,&lt;/p&gt;
&lt;p&gt;// LEFT OUTER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// from subcategory in category.ProductSubcategories&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupJoin also returns hierarchical result, so again an additional SelectMany can flatten the result. The following example still has the same INNER JOIN translation as the first Join example:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithGroupJoinAndSelectMany(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.GroupJoin(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: category =&amp;gt; category.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategories) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category, Subcategories = subcategories })&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories,&lt;/p&gt;
&lt;p&gt;// LEFT OUTER JOIN if DefaultIfEmpty is called.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// join subcategory in inner&lt;/p&gt;
&lt;p&gt;// on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories&lt;/p&gt;
&lt;p&gt;// from subcategory in subcategories&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Navigation property makes it very easy to join entities with relationship. The following example inner joins 3 entity types, where 2 entity types have many-to-many relationship with a junction entity type:&lt;/p&gt;
&lt;p&gt;internal static void MultipleInnerJoinsWithRelationship(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var productPhotos = source.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: product =&amp;gt; product.ProductProductPhotos,&lt;/p&gt;
&lt;p&gt;resultSelector: (product, productProductPhoto) =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Product = product.Name,&lt;/p&gt;
&lt;p&gt;Photo = productProductPhoto.ProductPhoto.LargePhotoFileName&lt;/p&gt;
&lt;p&gt;}); // Define query.&lt;/p&gt;
&lt;p&gt;// var productPhotos =&lt;/p&gt;
&lt;p&gt;// from product in source&lt;/p&gt;
&lt;p&gt;// from productProductPhoto in product.ProductProductPhotos&lt;/p&gt;
&lt;p&gt;// select new { Product = product.Name, Photo = productProductPhoto.ProductPhoto.LargePhotoFileName };&lt;/p&gt;
&lt;p&gt;productPhotos.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product.ProductProductPhotos.ProductPhoto].[LargePhotoFileName]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// INNER JOIN [Production].[ProductProductPhoto] AS [product.ProductProductPhotos] ON [product].[ProductID] = [product.ProductProductPhotos].[ProductID]&lt;/p&gt;
&lt;p&gt;// INNER JOIN [Production].[ProductPhoto] AS [product.ProductProductPhotos.ProductPhoto] ON [product.ProductProductPhotos].[ProductPhotoID] = [product.ProductProductPhotos.ProductPhoto].[ProductPhotoID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Left outer join&lt;/h6&gt;
&lt;p&gt;GroupJoin is provided for left outer join. The following example have categories to left outer join subcategories with foreign key, and the results have all categories with or without matching subcategories. It is translated to LEFT JOIN:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithGroupJoin(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.GroupJoin(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: category =&amp;gt; category.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategories) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category, Subcategories = subcategories }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// join subcategory in inner&lt;/p&gt;
&lt;p&gt;// on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories&lt;/p&gt;
&lt;p&gt;// select new { Category = category, Subcategories = subcategories };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(categorySubcategory =&amp;gt;&lt;/p&gt;
&lt;p&gt;$@&quot;{categorySubcategory.Category.Name}: {string.Join(&lt;/p&gt;
&lt;p&gt;&quot;, &quot;, categorySubcategory.Subcategories.Select(subcategory =&amp;gt; subcategory.Name))}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[ProductCategoryID], [category].[Name], [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// LEFT JOIN [Production].[ProductSubcategory] AS [subcategory] ON [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// ORDER BY [category].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupJoin returns hierarchical results. So here the translated SQL also sorts the result by the key, so that EF Core can read the query results group by group. To have flattened results from GroupJoin, SelectMany can be called. As discussed in the LINQ to Objects chapter, an DefaultIfEmpty subquery is required (It becomes inner join if DefaultIfEmpty is missing). The following example has the same SQL translation as above, it just yields result by result instead of group by group.&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithGroupJoinAndSelectMany(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.GroupJoin(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: category =&amp;gt; category.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategories) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category, Subcategories = subcategories }) // Define query.&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category, Subcategory = subcategory }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// join subcategory in inner&lt;/p&gt;
&lt;p&gt;// on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories&lt;/p&gt;
&lt;p&gt;// from subcategory in subcategories.DefaultIfEmpty()&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(categorySubcategory =&amp;gt;&lt;/p&gt;
&lt;p&gt;$&quot;{categorySubcategory.Category.Name} {categorySubcategory.Subcategory?.Name}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to inner join, left outer join can be done with Select and SelectMany too, with a DefaultIfEmpty subquery. The following queries have the same SQL translation:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelect(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.Select(category =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Category = category,&lt;/p&gt;
&lt;p&gt;Subcategories = inner&lt;/p&gt;
&lt;p&gt;.Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;})&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// select new&lt;/p&gt;
&lt;p&gt;// {&lt;/p&gt;
&lt;p&gt;// Category = category,&lt;/p&gt;
&lt;p&gt;// Subcategories = from subcategory in inner&lt;/p&gt;
&lt;p&gt;// where subcategory.ProductCategoryID == category.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select subcategory&lt;/p&gt;
&lt;p&gt;// } into category&lt;/p&gt;
&lt;p&gt;// from subcategory in category.Subcategories.DefaultIfEmpty()&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[Name], [t1].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// CROSS APPLY (&lt;/p&gt;
&lt;p&gt;// SELECT [t0].*&lt;/p&gt;
&lt;p&gt;// FROM (&lt;/p&gt;
&lt;p&gt;// SELECT NULL AS [empty]&lt;/p&gt;
&lt;p&gt;// ) AS [empty0]&lt;/p&gt;
&lt;p&gt;// LEFT JOIN (&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory0].*&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory0]&lt;/p&gt;
&lt;p&gt;// WHERE [category].[ProductCategoryID] = [subcategory0].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// ) AS [t0] ON 1 = 1&lt;/p&gt;
&lt;p&gt;// ) AS [t1]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelectMany(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; inner&lt;/p&gt;
&lt;p&gt;.Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// from subcategory in (from subcategory in inner&lt;/p&gt;
&lt;p&gt;// where category.ProductCategoryID == subcategory.ProductCategoryID&lt;/p&gt;
&lt;p&gt;// select subcategory).DefaultIfEmpty()&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In EF Core, the above 2 queries are both translated to CROSS APPLY, but this is logically equivalent to LEFT JOIN of the GroupJoin example.&lt;/p&gt;
&lt;p&gt;As demonstrated for inner join, in the above Select and SelectMany queries, the Where subquery is equivalent to collection navigation property. EF Core support collection navigation property for left outer join with Select and SelectMany. The following queries are translated to the same LEFT JOIN query:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelectAndRelationship(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer&lt;/p&gt;
&lt;p&gt;.Select(category =&amp;gt; new { Category = category, Subcategories = category.ProductSubcategories })&lt;/p&gt;
&lt;p&gt;.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.Subcategories&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// select new { Category = category, Subcategories = category.ProductSubcategories } into category&lt;/p&gt;
&lt;p&gt;// from subcategory in category.Subcategories.DefaultIfEmpty()&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [category].[Name] AS [Category], [category.ProductSubcategories].[Name] AS [Subcategory]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [category]&lt;/p&gt;
&lt;p&gt;// LEFT JOIN [Production].[ProductSubcategory] AS [category.ProductSubcategories] ON [category].[ProductCategoryID] = [category.ProductSubcategories].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelectManyAndRelationship(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;var categorySubcategories = outer.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: category =&amp;gt; category.ProductSubcategories&lt;/p&gt;
&lt;p&gt;.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.&lt;/p&gt;
&lt;p&gt;resultSelector: (category, subcategory) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var categorySubcategories =&lt;/p&gt;
&lt;p&gt;// from category in outer&lt;/p&gt;
&lt;p&gt;// from subcategory in category.ProductSubcategories.DefaultIfEmpty()&lt;/p&gt;
&lt;p&gt;// select new { Category = category.Name, Subcategory = subcategory.Name };&lt;/p&gt;
&lt;p&gt;categorySubcategories.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Cross join&lt;/h6&gt;
&lt;p&gt;Just like LINQ to Objects, cross join can be done with SelectMany and Join. The following example queries the expensive products (list price greater than 2000) and cheap products (list price less than 100), and then cross join them to get all possible product bundles, where each bundle has one expensive product and one cheap product:&lt;/p&gt;
&lt;p&gt;internal static void CrossJoinWithSelectMany(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; inner = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);&lt;/p&gt;
&lt;p&gt;var bundles = outer.SelectMany(&lt;/p&gt;
&lt;p&gt;collectionSelector: expensiveProduct =&amp;gt; inner,&lt;/p&gt;
&lt;p&gt;resultSelector: (expensiveProduct, cheapProduct) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Expensive = expensiveProduct.Name, Cheap = cheapProduct.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var bundles =&lt;/p&gt;
&lt;p&gt;// from outerProduct in outer&lt;/p&gt;
&lt;p&gt;// from innerProduct in inner&lt;/p&gt;
&lt;p&gt;// select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name };&lt;/p&gt;
&lt;p&gt;bundles.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product0].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// CROSS JOIN [Production].[Product] AS [product0]&lt;/p&gt;
&lt;p&gt;// WHERE ([product].[ListPrice] &amp;gt; 2000.0) AND ([product0].[ListPrice] &amp;lt; 100.0)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following implementation with Join is equivalent, just have the 2 key selectors always return equal values:&lt;/p&gt;
&lt;p&gt;internal static void CrossJoinWithJoin(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; inner = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);&lt;/p&gt;
&lt;p&gt;var bundles = outer.Join(&lt;/p&gt;
&lt;p&gt;inner: inner,&lt;/p&gt;
&lt;p&gt;outerKeySelector: product =&amp;gt; 1,&lt;/p&gt;
&lt;p&gt;innerKeySelector: product =&amp;gt; 1,&lt;/p&gt;
&lt;p&gt;resultSelector: (outerProduct, innerProduct) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }); // Define query.&lt;/p&gt;
&lt;p&gt;// var bundles =&lt;/p&gt;
&lt;p&gt;// from outerProduct in outer&lt;/p&gt;
&lt;p&gt;// join innerProduct in inner&lt;/p&gt;
&lt;p&gt;// on 1 equals 1&lt;/p&gt;
&lt;p&gt;// select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name };&lt;/p&gt;
&lt;p&gt;bundles.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [t].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// INNER JOIN (&lt;/p&gt;
&lt;p&gt;// SELECT [product1].*&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product1]&lt;/p&gt;
&lt;p&gt;// WHERE [product1].[ListPrice] &amp;lt; 100.0&lt;/p&gt;
&lt;p&gt;// ) AS [t] ON 1 = 1&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 2000.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is translated to INNER JOIN, which is equivalent to previous CROSS JOIN, with the same query plan.&lt;/p&gt;
&lt;h6&gt;Concatenation&lt;/h6&gt;
&lt;p&gt;The following example concatenates the cheap products and the expensive products, and query the products’ names:&lt;/p&gt;
&lt;p&gt;internal static void ConcatEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; concat = first&lt;/p&gt;
&lt;p&gt;.Concat(second)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name); // Define query.&lt;/p&gt;
&lt;p&gt;concat.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product1].[ProductID], [product1].[ListPrice], [product1].[Name], [product1].[ProductSubcategoryID], [product1].[RowVersion]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product1]&lt;/p&gt;
&lt;p&gt;// WHERE [product1].[ListPrice] &amp;lt; 100.0&lt;/p&gt;
&lt;p&gt;// SELECT [product2].[ProductID], [product2].[ListPrice], [product2].[Name], [product2].[ProductSubcategoryID], [product2].[RowVersion]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product2]&lt;/p&gt;
&lt;p&gt;// WHERE [product2].[ListPrice] &amp;gt; 2000.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core supports Concat for primitive type locally as well. In the above example, Select is called after Concat. It is logically equivalent to call Select before Concat, which works in EF Core:&lt;/p&gt;
&lt;p&gt;internal static void ConcatPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; first = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;lt; 100)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; second = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; concat = first.Concat(second); // Define query.&lt;/p&gt;
&lt;p&gt;concat.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;lt; 100.0&lt;/p&gt;
&lt;p&gt;// SELECT [product0].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product0]&lt;/p&gt;
&lt;p&gt;// WHERE [product0].[ListPrice] &amp;gt; 2000.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core translates Concat’s 2 data sources to 2 SQL queries, reads the query results to local, and concatenates them locally.&lt;/p&gt;
&lt;h6&gt;Set&lt;/h6&gt;
&lt;p&gt;Distinct works with entity type and primitive type. It is translated to the DISTINCT keyword:&lt;/p&gt;
&lt;p&gt;internal static void DistinctEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; distinct = source&lt;/p&gt;
&lt;p&gt;.Select(subcategory =&amp;gt; subcategory.ProductCategory)&lt;/p&gt;
&lt;p&gt;.Distinct(); // Define query.&lt;/p&gt;
&lt;p&gt;distinct.WriteLines(category =&amp;gt; $&quot;{category.ProductCategoryID}: {category.Name}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT DISTINCT [subcategory.ProductCategory].[ProductCategoryID], [subcategory.ProductCategory].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// INNER JOIN [Production].[ProductCategory] AS [subcategory.ProductCategory] ON [subcategory].[ProductCategoryID] = [subcategory.ProductCategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void DistinctPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{ IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;int&amp;gt; distinct = source&lt;/p&gt;
&lt;p&gt;.Select(subcategory =&amp;gt; subcategory.ProductCategoryID)&lt;/p&gt;
&lt;p&gt;.Distinct(); // Define query.&lt;/p&gt;
&lt;p&gt;distinct.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT DISTINCT [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupBy returns groups with distinct keys, so in theory it can be used to query the same result as Distinct:&lt;/p&gt;
&lt;p&gt;internal static void DistinctWithGroupBy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;int&amp;gt; distinct = source.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,&lt;/p&gt;
&lt;p&gt;resultSelector: (key, group) =&amp;gt; key); // Define query.&lt;/p&gt;
&lt;p&gt;distinct.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [subcategory].[ProductCategoryID] AS [Key]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductSubcategory] AS [subcategory]&lt;/p&gt;
&lt;p&gt;// GROUP BY [subcategory].[ProductCategoryID]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;However, as fore mentioned, in EF Core, GroupBy executes locally. The above example only queries grouping keys, however it reads all rows of the table to local, which can be a performance issue.&lt;/p&gt;
&lt;p&gt;GroupBy can also be used for more complex scenarios. The following example queries the full product entities with distinct list price:&lt;/p&gt;
&lt;p&gt;internal static void DistinctWithGroupByAndFirstOrDefault(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; distinct = source.GroupBy(&lt;/p&gt;
&lt;p&gt;keySelector: product =&amp;gt; product.ListPrice,&lt;/p&gt;
&lt;p&gt;resultSelector: (key, group) =&amp;gt; group.FirstOrDefault()); // Define query.&lt;/p&gt;
&lt;p&gt;distinct.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, EF Core does not translate grouping to SQL. In this example, only 1 entities for each key is queried, but EF Core reads all rows to local, and execute the grouping logic locally.&lt;/p&gt;
&lt;p&gt;EF Core supports Union for entity and primitive types locally.&lt;/p&gt;
&lt;p&gt;internal static void UnionEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 100);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ProductSubcategoryID == 1);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; union = first.Union(second); // Define query.&lt;/p&gt;
&lt;p&gt;union.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 100.0&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// [product0].[ProductSubcategoryID] = 1&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void UnionPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;var first = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 100)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });&lt;/p&gt;
&lt;p&gt;var second = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ProductSubcategoryID == 1)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });&lt;/p&gt;
&lt;p&gt;var union = first.Union(second); // Define query.&lt;/p&gt;
&lt;p&gt;union.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 100.0&lt;/p&gt;
&lt;p&gt;// SELECT [product0].[Name], [product0].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product0]&lt;/p&gt;
&lt;p&gt;// WHERE [product0].[ProductSubcategoryID] = 1&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core executes Intersect and Except locally as well.&lt;/p&gt;
&lt;p&gt;internal static void IntersectEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 100);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;lt; 2000);&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; intersect = first.Intersect(second); // Define query.&lt;/p&gt;
&lt;p&gt;intersect.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product0].[ProductID], [product0].[ListPrice], [product0].[Name], [product0].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product0]&lt;/p&gt;
&lt;p&gt;// WHERE [product0].[ListPrice] &amp;lt; 2000.0&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 100.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void ExceptPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;var first = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 100)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });&lt;/p&gt;
&lt;p&gt;var second = adventureWorks.Products&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });&lt;/p&gt;
&lt;p&gt;var except = first.Except(second); // Define query.&lt;/p&gt;
&lt;p&gt;except.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product0].[Name], [product0].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product0]&lt;/p&gt;
&lt;p&gt;// WHERE [product0].[ListPrice] &amp;gt; 2000.0&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 100.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Partitioning&lt;/h6&gt;
&lt;p&gt;Skip is translate to OFFSET filter:&lt;/p&gt;
&lt;p&gt;internal static void Skip(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; names = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name)&lt;/p&gt;
&lt;p&gt;.Skip(10); // Define query.&lt;/p&gt;
&lt;p&gt;names.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// exec sp_executesql N&apos;SELECT [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY (SELECT 1)&lt;/p&gt;
&lt;p&gt;// OFFSET @__p_0 ROWS&apos;,N&apos;@__p_0 int&apos;,@__p_0=10&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In SQL, OFFSET is considered to be a part of the ORDER BY clause, so here EF Core generates ORDERBY (SELECT 1) clause.&lt;/p&gt;
&lt;p&gt;When Take is called without Skip, it is translate to TOP filter:&lt;/p&gt;
&lt;p&gt;internal static void Take(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; products = source&lt;/p&gt;
&lt;p&gt;.Take(10)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// exec sp_executesql N&apos;SELECT TOP(@__p_0) [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&apos;,N&apos;@__p_0 int&apos;,@__p_0=10&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When Take is called with Skip, they are translated to FETCH and OFFSET filters:&lt;/p&gt;
&lt;p&gt;internal static void SkipAndTake(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;string&amp;gt; products = source&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.Name)&lt;/p&gt;
&lt;p&gt;.Skip(20)&lt;/p&gt;
&lt;p&gt;.Take(10)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// exec sp_executesql N&apos;SELECT [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY (SELECT 1)&lt;/p&gt;
&lt;p&gt;// OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY&apos;,N&apos;@__p_0 int,@__p_1 int&apos;,@__p_0=20,@__p_1=10&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Ordering&lt;/h6&gt;
&lt;p&gt;OrderBy/OrderByDescending are translated to ORDER BY clause with without/with DESC, for example:&lt;/p&gt;
&lt;p&gt;internal static void OrderBy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.ListPrice)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void OrderByDescending(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source&lt;/p&gt;
&lt;p&gt;.OrderByDescending(product =&amp;gt; product.ListPrice)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[ListPrice] DESC&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To sort with multiple keys, call OrderBy/OrderByDescending and ThenBy/ThenByDescending:&lt;/p&gt;
&lt;p&gt;internal static void OrderByAndThenBy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.ListPrice)&lt;/p&gt;
&lt;p&gt;.ThenBy(product =&amp;gt; product.Name)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[ListPrice], [product].[Name]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In EF Core, when the key selector returns anonymous type to sort by multiple keys, the sorting is executed locally:&lt;/p&gt;
&lt;p&gt;internal static void OrderByMultipleKeys(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; new { ListPrice = product.ListPrice, Name = product.Name })&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY (SELECT 1)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Multiple OrderBy/OrderByDescending calls are translated to SQL reversely. The following example sort all products by list price, then sort all products again by subcategory, which is equivalent to sort all products by subcategory first, then sort products in the same subcategory by list price:&lt;/p&gt;
&lt;p&gt;internal static void OrderByAndOrderBy(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var products = source&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.ListPrice)&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.ProductSubcategoryID)&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Name = product.Name,&lt;/p&gt;
&lt;p&gt;ListPrice = product.ListPrice,&lt;/p&gt;
&lt;p&gt;Subcategory = product.ProductSubcategoryID&lt;/p&gt;
&lt;p&gt;}); // Define query.&lt;/p&gt;
&lt;p&gt;products.WriteLines(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[ProductSubcategoryID], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Conversion&lt;/h6&gt;
&lt;p&gt;Cast can work with entity type. The following example casts base entity to derived entity:&lt;/p&gt;
&lt;p&gt;internal static void CastEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; transactions = source&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ActualCost &amp;gt; 500)&lt;/p&gt;
&lt;p&gt;.Cast&amp;lt;SalesTransactionHistory&amp;gt;(); // Define query.&lt;/p&gt;
&lt;p&gt;transactions.WriteLines(transaction =&amp;gt;&lt;/p&gt;
&lt;p&gt;$&quot;{transaction.GetType().Name}: {transaction.TransactionDate}&quot;); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[TransactionID], [product].[ActualCost], [product].[ProductID], [product].[Quantity], [product].[TransactionDate], [product].[TransactionType]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[TransactionHistory] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;) AND ([product].[ActualCost] &amp;gt; 500.0)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core does not support Cast for primitive type.&lt;/p&gt;
&lt;p&gt;Queryable has an additional query, AsQueryable, which accepts IEnumerable&amp;lt;T&amp;gt; and returns IQueryable&amp;lt;T&amp;gt;. Remember Enumerable.AsEnumerable can convert more derived sequence (like List&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt;, etc.) to IEnumerable&amp;lt;T&amp;gt;. So the Queryable.AsQueryable/Eumerable.AsEnumerable queries look similar to the ParallelEnumerable.AsParallel/ParallelEnumerable.AsSequential queries, which convert between sequential and parallel local queries at any point. However, AsQueryable/AsEnumerable usually do not convert freely between local and remote queries. The following is the implementation of AsEnumerable and AsQueryable:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;public static class Enumerable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; source;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;public static class Queryable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;public static IQueryable&amp;lt;TElement&amp;gt; AsQueryable&amp;lt;TElement&amp;gt;(this IEnumerable&amp;lt;TElement&amp;gt; source) =&amp;gt;&lt;/p&gt;
&lt;p&gt;source as IQueryable&amp;lt;TElement&amp;gt; ?? new EnumerableQuery&amp;lt;TElement&amp;gt;(source);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;AsQueryable accepts an IEnumerable&amp;lt;T&amp;gt; source. If the source is indeed an IQueryable&amp;lt;T&amp;gt; source, then do nothing and just return it; if not, wrap the source into an System.Linq.EnumerableQuery&amp;lt;T&amp;gt; instance, and return it. EnumerableQuery&amp;lt;T&amp;gt; is a special implementation of IQueryable&amp;lt;T&amp;gt;. If an IQueryable&amp;lt;T&amp;gt; query is an EnumerableQuery&amp;lt;T&amp;gt; instance, when this query is executed, it internally calls System.Linq.EnumerableRewriter to translate itself to local query, then execute the translated query locally. For example, AdventureWorks.Products return IQueryable&amp;lt;Product&amp;gt;, which is actually a DbSet&amp;lt;T&amp;gt; instance, so calling AsQueryable with AdventureWorks.Products does nothing and returns the DbSet&amp;lt;Product&amp;gt; instance itself, which can have its subsequent queries to be translated to SQL by EF Core. In contrast, calling AsQueryable with a T[] array returns an EnumerableQuery&amp;lt;T&amp;gt; wrapper, which is a local mocking of remote query and can have its subsequent queries to be translated to local queries, As a result, AsEnumerable can always convert a remote LINQ to Entities query to local LINQ to Objects query, but AsQueryable cannot always convert arbitrary local LINQ to Objects query to a remote LINQ to Entities query (and logically, an arbitrary local .NET data source cannot be converted to a remote data source like SQL database). For example:&lt;/p&gt;
&lt;p&gt;internal static void AsEnumerableAsQueryable(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var remoteAndLocal = source // DbSet&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return EntityQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;.AsEnumerable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 0) // Enumerable.Where. Return a generator wrapping the EntityQueryable&amp;lt;T&amp;gt; source.&lt;/p&gt;
&lt;p&gt;.AsQueryable() // Return an EnumerableQuery&amp;lt;T&amp;gt; instance wrapping the source generator.&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.Name); // Queryable.OrderBy. Return EnumerableQuery&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;remoteAndLocal.WriteLines();&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;var remote = source // DbSet&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return EntityQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;.AsEnumerable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.&lt;/p&gt;
&lt;p&gt;.AsQueryable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ListPrice &amp;gt; 0) // Still LINQ to Entities. Return EntityQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;.OrderBy(product =&amp;gt; product.Name); // Still LINQ to Entities. Return EntityQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;remote.WriteLines();&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 0.0&lt;/p&gt;
&lt;p&gt;// ORDER BY [product].[Name]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the first query, the LINQ to Entities source is chained with Select, then AsEnumerable returns IEnumerable&amp;lt;T&amp;gt;, so the following Where is Enumerable.Where, and it returns a generator. Then AsQueryable detects if the generator is IQueryable&amp;lt;T&amp;gt;. Since the generator is not IQueryable&amp;lt;T&amp;gt;, AsQueryable returns a EnumerableQuery&amp;lt;T&amp;gt; wrapper, which can have the following OrderBy translated to local query. So in this entire query chaining, only Select, which is before AsEnumerable, can be translated to SQL and executed remotely, all the other queries are executed locally.&lt;/p&gt;
&lt;p&gt;· The source is a DbSet&amp;lt;T&amp;gt; instance, which implements IQueryable&amp;lt;T&amp;gt; and represents the LINQ to Entities data source - rows in remote SQL database table.&lt;/p&gt;
&lt;p&gt;· Queryable.Select is called on DbSet&amp;lt;T&amp;gt; source, in this case it returns a Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable&amp;lt;T&amp;gt; instance in EF Core, which implements IQueryable&amp;lt;T&amp;gt; and represents LINQ to Entities query.&lt;/p&gt;
&lt;p&gt;· Enumerable.AsEnumerable does nothing and directly returns its source, the EntityQueryable&amp;lt;T&amp;gt; instance&lt;/p&gt;
&lt;p&gt;· Enumerable.Where is called, since AsEnumerable returns IEnumerable&amp;lt;T&amp;gt; type. Where returns a generator wrapping its source, the EntityQueryable&amp;lt;T&amp;gt; instance.&lt;/p&gt;
&lt;p&gt;· Queryable.AsQueryable is called. Its source, the generator from Where, implements IEnumerable&amp;lt;T&amp;gt;, not IQueryable&amp;lt;T&amp;gt;, so AsQueryable return an EnumerableQuery&amp;lt;T&amp;gt; instance wrapping the generator. As fore mentioned, EnumerableQuery&amp;lt;T&amp;gt; has nothing to do with database.&lt;/p&gt;
&lt;p&gt;· Queryable.OrderBy is called with EnumerableQuery&amp;lt;T&amp;gt; instance, in this case it returns another EnumerableQuery&amp;lt;T&amp;gt; instance, which has nothing to do with database either.&lt;/p&gt;
&lt;p&gt;So the first query is a hybrid query. When it is executed, only Select is remote LINQ to Entities query and is translated to SQL. After AsEnumerable, Where goes local, then AsQueryable cannot convert back to remote LINQ to Entities query anymore. So, Where and OrderBy are both local queries, and not translated to SQL.&lt;/p&gt;
&lt;p&gt;The second query is a special case, where AsEnumerable is chained with AsQueryable right away. In this case, AsEnumerable and AsQueryable both do nothing at all. The following Where and OrderBy are both LINQ to Entities queries, and translated to SQL along with Select.&lt;/p&gt;
&lt;h4&gt;Value query&lt;/h4&gt;
&lt;p&gt;Queries in this category accepts an IQueryable&amp;lt;T&amp;gt; source and returns a single value. As fore mentioned, the aggregation queries can be used with GroupBy. When value queries are called at the end of a LINQ to Entities query, they executes the query immediately.&lt;/p&gt;
&lt;h6&gt;Element&lt;/h6&gt;
&lt;p&gt;First and FirstOrDefault execute the LINQ to Entities queries immediately. They are translated to TOP(1) filter in the SELECT clause. If a predicate is provided, the predicate is translated to WHERE clause. For example:&lt;/p&gt;
&lt;p&gt;internal static void First(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;string first = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.Name)&lt;/p&gt;
&lt;p&gt;.First() // Execute query.&lt;/p&gt;
&lt;p&gt;.WriteLine();&lt;/p&gt;
&lt;p&gt;// SELECT TOP(1) [product].[Name]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void FirstOrDefault(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var firstOrDefault = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })&lt;/p&gt;
&lt;p&gt;.FirstOrDefault(product =&amp;gt; product.ListPrice &amp;gt; 5000); // Execute query.&lt;/p&gt;
&lt;p&gt;firstOrDefault?.Name.WriteLine();&lt;/p&gt;
&lt;p&gt;// SELECT TOP(1) [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 5000.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As discussed in LINQ to Objects, Single and SingleOrDefault are more strict. They are translated to TOP(2) filter, so that, if there are 0 or more than 1 results, InvalidOperationException is thrown. Similar to First and FirstOrDefault, if a predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;p&gt;internal static void Single(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var single = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })&lt;/p&gt;
&lt;p&gt;.Single(product =&amp;gt; product.ListPrice &amp;lt; 50); // Execute query.&lt;/p&gt;
&lt;p&gt;$&quot;{single.Name}: {single.ListPrice}&quot;.WriteLine();&lt;/p&gt;
&lt;p&gt;// SELECT TOP(2) [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;lt; 50.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void SingleOrDefault(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var singleOrDefault = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })&lt;/p&gt;
&lt;p&gt;.SingleOrDefault(product =&amp;gt; product.ListPrice &amp;lt; 1); // Execute query.&lt;/p&gt;
&lt;p&gt;singleOrDefault?.Name.WriteLine();&lt;/p&gt;
&lt;p&gt;// SELECT TOP(2) [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;lt; 1.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core supports Last and LastOrDefault, locally. Again, if a predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;p&gt;internal static void Last(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;Product last = source.Last(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [p].[ProductID], [p].[ListPrice], [p].[Name], [p].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [p]&lt;/p&gt;
&lt;p&gt;$&quot;{last.Name}: {last.ListPrice}&quot;.WriteLine();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void LastOrDefault(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;var lastOrDefault = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })&lt;/p&gt;
&lt;p&gt;.LastOrDefault(product =&amp;gt; product.ListPrice &amp;lt;= 0); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT [product].[Name], [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;lt;= 0.0&lt;/p&gt;
&lt;p&gt;(lastOrDefault == null).WriteLine(); // True&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above examples can read many results from remote database to locally, and try to query the last result locally, which can cause performance issue.&lt;/p&gt;
&lt;h6&gt;Aggregation&lt;/h6&gt;
&lt;p&gt;Count/LongCount are translated to SQL aggregate functions COUNT/COUNT_BIG. if a is provided, it is translated to WHERE clause. The following examples query the System.Int32 count of categories, and the System.Int64 count of the products with list price greater than 0:&lt;/p&gt;
&lt;p&gt;internal static void Count(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;&lt;/p&gt;
&lt;p&gt;int count = source.Count().WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT COUNT(*)&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductCategory] AS [p]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void LongCount(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;long longCount = source.LongCount(product =&amp;gt; product.ListPrice &amp;gt; 0).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT COUNT_BIG(*)&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 0.0&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Max/Min/Sum/Average are translated to MAX/MIN/SUM/AVG functions. The following examples query the latest ModifiedDate of photos, the lowest list price of products, and the total cost of transactions, and the average ListPrice of products:&lt;/p&gt;
&lt;p&gt;internal static void Max(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;ProductPhoto&amp;gt; source = adventureWorks.ProductPhotos;&lt;/p&gt;
&lt;p&gt;DateTime max = source.Select(photo =&amp;gt; photo.ModifiedDate).Max().WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT MAX([photo].[ModifiedDate])&lt;/p&gt;
&lt;p&gt;// FROM [Production].[ProductPhoto] AS [photo]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void Min(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;decimal min = source.Min(product =&amp;gt; product.ListPrice).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT MIN([product].[ListPrice])&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void Sum(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;&lt;/p&gt;
&lt;p&gt;decimal sum = source.Sum(transaction =&amp;gt; transaction.ActualCost).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT SUM([transaction].[ActualCost])&lt;/p&gt;
&lt;p&gt;// FROM [Production].[TransactionHistory] AS [transaction]&lt;/p&gt;
&lt;p&gt;// WHERE [transaction].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;)&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void Average(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;decimal average = source.Select(product =&amp;gt; product.ListPrice).Average().WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT AVG([product].[ListPrice])&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h6&gt;Quantifier&lt;/h6&gt;
&lt;p&gt;EF Core supports Contains for entity type, locally.&lt;/p&gt;
&lt;p&gt;internal static void ContainsEntity(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;Product single = source.Single(product =&amp;gt; product.ListPrice == 20.24M); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT TOP(2) [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] = 20.24&lt;/p&gt;
&lt;p&gt;bool contains = source&lt;/p&gt;
&lt;p&gt;.Where(product =&amp;gt; product.ProductSubcategoryID == 7)&lt;/p&gt;
&lt;p&gt;.Contains(single).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// exec sp_executesql N&apos;SELECT CASE&lt;/p&gt;
&lt;p&gt;// WHEN @__p_0_ProductID IN (&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ProductID]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ProductSubcategoryID] = 7&lt;/p&gt;
&lt;p&gt;// )&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&apos;,N&apos;@__p_0_ProductID int&apos;,@__p_0_ProductID=952&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core both support Contains for primitive types. In this case, Contains is translated to EXISTS predicate:&lt;/p&gt;
&lt;p&gt;internal static void ContainsPrimitive(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;bool contains = source&lt;/p&gt;
&lt;p&gt;.Select(product =&amp;gt; product.ListPrice).Contains(100)&lt;/p&gt;
&lt;p&gt;.WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// exec sp_executesql N&apos;SELECT CASE&lt;/p&gt;
&lt;p&gt;// WHEN @__p_0 IN (&lt;/p&gt;
&lt;p&gt;// SELECT [product].[ListPrice]&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// )&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&apos;,N&apos;@__p_0 decimal(3,0)&apos;,@__p_0=100&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Any is also translated to EXISTS. If predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;p&gt;internal static void Any(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;bool any = source.Any().WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT CASE&lt;/p&gt;
&lt;p&gt;// WHEN EXISTS (&lt;/p&gt;
&lt;p&gt;// SELECT 1&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [p])&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;internal static void AnyWithPredicate(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;bool any = source.Any(product =&amp;gt; product.ListPrice &amp;gt; 10).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT CASE&lt;/p&gt;
&lt;p&gt;// WHEN EXISTS (&lt;/p&gt;
&lt;p&gt;// SELECT 1&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;gt; 10.0)&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;All is translated to NOT EXISTS, with the predicate translated to reverted condition in WHERE clause:&lt;/p&gt;
&lt;p&gt;internal static void AllWithPredicate(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;&lt;/p&gt;
&lt;p&gt;bool all = source.All(product =&amp;gt; product.ListPrice &amp;gt; 10).WriteLine(); // Execute query.&lt;/p&gt;
&lt;p&gt;// SELECT CASE&lt;/p&gt;
&lt;p&gt;// WHEN NOT EXISTS (&lt;/p&gt;
&lt;p&gt;// SELECT 1&lt;/p&gt;
&lt;p&gt;// FROM [Production].[Product] AS [product]&lt;/p&gt;
&lt;p&gt;// WHERE [product].[ListPrice] &amp;lt;= 10.0)&lt;/p&gt;
&lt;p&gt;// THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)&lt;/p&gt;
&lt;p&gt;// END&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Text:&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (3) Logging and Tracing Queries</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries/</guid><description>As fore mentioned, LINQ to Entities queries are translated to database queries. To understand how EF Core work with databases, it is important to uncover the actual underlying operations to the SQL da</description><pubDate>Sat, 05 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ to Entities queries are translated to database queries. To understand how EF Core work with databases, it is important to uncover the actual underlying operations to the SQL database, which can be traced or logged in C# application side and in SQL database.&lt;/p&gt;
&lt;h3&gt;Application side logging&lt;/h3&gt;
&lt;p&gt;EF Core follows the ASP.NET Core logging infrastructure. To log EF Core operations, a logger (implementing Microsoft.Extensions.Logging.ILogger) and a logger provider (implementing Microsoft.Extensions.Logging.ILoggerProvider) can be defined. The following is a simple example to simply trace everything:&lt;/p&gt;
&lt;p&gt;public class TraceLogger : ILogger&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly string categoryName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TraceLogger(string categoryName) =&amp;gt; this.categoryName = categoryName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool IsEnabled(LogLevel logLevel) =&amp;gt; true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Log&amp;lt;TState&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LogLevel logLevel,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventId eventId,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TState state,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Exception exception,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TState, Exception, string&amp;gt; formatter)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine($&quot;{DateTime.Now.ToString(&quot;o&quot;)} {logLevel} {eventId.Id} {this.categoryName}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(formatter(state, exception));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IDisposable BeginScope&amp;lt;TState&amp;gt;(TState state) =&amp;gt; null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class TraceLoggerProvider : ILoggerProvider
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public ILogger CreateLogger(string categoryName) =&amp;gt; new TraceLogger(categoryName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Dispose() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the logger provider can be hooked up with EF Core:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LoggerFactory loggerFactory = new LoggerFactory();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;loggerFactory.AddProvider(new TraceLoggerProvider());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;optionsBuilder.UseLoggerFactory(loggerFactory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following is a simple example of LINQ to Entities query. It pulls all ProductCategory entities from AdventureWorks.ProductCategories data source:&lt;/p&gt;
&lt;p&gt;internal static void Logger()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.WriteLines(category =&amp;gt; category.Name); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:43.4625876-08:00 Debug 2 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiling query model:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;from ProductCategory &amp;lt;generated&amp;gt;_0 in DbSet&amp;lt;ProductCategory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// select &amp;lt; generated&amp;gt;_0&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:43.4932882-08:00 Debug 3 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Optimized query model:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &apos;from ProductCategory &amp;lt;generated&amp;gt;_0 in DbSet&amp;lt;ProductCategory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// select &amp;lt; generated&amp;gt;_0&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:43.6179834-08:00 Debug 5 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TRACKED: True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (QueryContext queryContext) =&amp;gt; IEnumerable&amp;lt;ProductCategory&amp;gt; _ShapedQuery(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// queryContext: queryContext,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// shaperCommandContext: SelectExpression:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [p].[ProductCategoryID], [p].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// shaper: UnbufferedEntityShaper&amp;lt;ProductCategory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// )
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:43.7272876-08:00 Debug 3 Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerConnection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Opening connection to database &apos;AdventureWorks&apos; on server &apos;tcp:dixin.database.windows.net,1433&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:44.1024201-08:00 Information 1 Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Executed DbCommand (66ms) [Parameters=[], CommandType=&apos;Text&apos;, CommandTimeout=&apos;30&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [p].[ProductCategoryID], [p].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [p]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2017-01-11T22:15:44.1505353-08:00 Debug 4 Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerConnection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Closing connection to database &apos;AdventureWorks&apos; on server &apos;tcp:dixin.database.windows.net,1433&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The logs uncovers that a SELECT statement is executed in database to query all categories. The logs also uncovers how exactly EF Core execute the operation – it compiles LINQ to Entities query and generates SQL, then opens a connection to SQL database, execute the generated SQL in database, and close the connection. This mechanism is discussed in the query translation part.&lt;/p&gt;
&lt;p&gt;EF Core also provides a TagWith query to annotate the translated database query:&lt;/p&gt;
&lt;p&gt;internal static void TagWith(AdventureWorks adventureWorks)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.TagWith(&quot;Query categories with id greater than 1.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 1); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.WriteLines(category =&amp;gt; category.Name); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// -- Query categories with id greater than 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// SELECT [category].[ProductCategoryID], [category].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// FROM [Production].[ProductCategory] AS [category]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WHERE [category].[ProductCategoryID]&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Database side tracing with Extended Events&lt;/h3&gt;
&lt;p&gt;SQL database provides variant mechanisms to collect the information of executed operations. Extended Events is such a feature available in all cloud and on-premise SQL database editions. For Windows, SQL Server Management Studio is a rich tools to setup and views the event tracing. And this can also be done from other platform. In any SQL tool (like mssql extension for Visual Studio Code, which works on Linux, Mac, and Windows), connect to the Azure SQL database (or SQL Server on-premise database), and execute the following SQL to create an Extended Events session called Queries:&lt;/p&gt;
&lt;p&gt;CREATE EVENT SESSION [Queries] ON DATABASE -- ON SERVER for SQL Server on-premise database.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.begin_tran_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.commit_tran_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.error_reported(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.rollback_tran_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.rpc_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.sp_statement_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.sql_batch_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD EVENT sqlserver.sql_statement_completed(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ADD TARGET package0.ring_buffer(SET max_events_limit = (100)) -- Most recent 100 events.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WITH (STARTUP_STATE = OFF);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;It traces the transactions, SQL executions, and errors, etc. To start the session and collect events, execute the following SQL:&lt;/p&gt;
&lt;p&gt;ALTER EVENT SESSION [Queries] ON DATABASE -- ON SERVER for SQL Server on-premise database.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;STATE = START;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;The collected events data is stored as XML, the following query formats the XML data to a statistics table, along with an event table which has the operations requested by .NET Core (or .NET Framework) application:&lt;/p&gt;
&lt;p&gt;DECLARE @target_data XML =&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(SELECT CONVERT(XML, [targets].[target_data])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FROM sys.dm_xe_database_session_targets AS [targets] -- sys.dm_xe_session_targets for SQL Server on-premise database.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;INNER JOIN sys.dm_xe_database_sessions AS [sessions] -- sys.dm_xe_sessions for SQL Server on-premise database.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ON [sessions].[address] = [targets].[event_session_address]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WHERE [sessions].[name] = N&apos;Queries&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@truncated)[1]&apos;, &apos;bigint&apos;) AS [truncated],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@processingTime)[1]&apos;, &apos;bigint&apos;) AS [processingTime],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@totalEventsProcessed)[1]&apos;, &apos;bigint&apos;) AS [totalEventsProcessed],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@eventCount)[1]&apos;, &apos;bigint&apos;) AS [eventCount],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@droppedCount)[1]&apos;, &apos;bigint&apos;) AS [droppedCount],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@target_data.value(&apos;(RingBufferTarget/@memoryUsed)[1]&apos;, &apos;bigint&apos;) AS [memoryUsed];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;@timestamp[1]&apos;, &apos;datetime&apos;) AS [timestamp],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;client_hostname&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [client_hostname],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;client_pid&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [client_pid],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;client_connection_id&quot;]/value)[1]&apos;, &apos;uniqueidentifier&apos;) AS [client_connection_id],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;session_id&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [session_id],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;request_id&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [request_id],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;database_name&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [database_name],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;@name[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [name],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;duration&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [duration],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;result&quot;]/text)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [result],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;row_count&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [row_count],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;cpu_time&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [cpu_time],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;logical_reads&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [logical_reads],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;physical_reads&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [physical_reads],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;writes&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [writes],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(action[@name=&quot;sql_text&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [sql_text],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;statement&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [statement],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;error_number&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [error_number],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[event].value(&apos;(data[@name=&quot;message&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [message]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FROM @target_data.nodes(&apos;//RingBufferTarget/event&apos;) AS [Rows]([event])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WHERE [event].value(&apos;(action[@name=&quot;client_app_name&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) = N&apos;Core .Net SqlClient Data Provider&apos; -- N&apos;.Net SqlClient Data Provider&apos; for .NET Framework.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ORDER BY [timestamp];&lt;/p&gt;
&lt;p&gt;The following is an example of how the traced database operations look like:&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (2) Modeling Database: Object-Relational Mapping</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping/</guid><description>In LINQ to Entities, the queries are based on Object-relational mapping. .NET and SQL database and have 2 different data type systems. For example, .NET has System.Int64 and System.String, while SQL d</description><pubDate>Fri, 04 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;In LINQ to Entities, the queries are based on Object-relational mapping. .NET and SQL database and have 2 different data type systems. For example, .NET has System.Int64 and System.String, while SQL database has bigint and nvarchar; .NET has sequences and objects, while SQL database has tables and rows;, etc. Object-relational mapping is a popular technology to map and convert between application data objects and database relational data.&lt;/p&gt;
&lt;h3&gt;Data types&lt;/h3&gt;
&lt;p&gt;EF Core can map most SQL data types to .NET types:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;SQL type category&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;SQL type&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET type&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;C# primitive&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Exact numeric&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;bit&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Boolean&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;bool&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;tinyint&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Byte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;byte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;smallint&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Int16&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;short&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;int&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Int32&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;int&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;bigint&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Int64&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;long&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;smallmoney, money, decimal, numeric&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Decimal&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;decimal&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Approximate numeric&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;real&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Single&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;float&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;float&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Double&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;double&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Character string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;char, varchar, text&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.String&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;nchar, nvarchar, ntext&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.String&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Binary string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;binary, varbinary&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 12;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;image&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 13;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;rowversion (timestamp)&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;byte[]&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 14;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Date time&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;date&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.DateTime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 15;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;time&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.TimeSpan&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 16;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;smalldatetime, datetime, datetime2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.DateTime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 17;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;datetimeoffset&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.DateTimeOffset&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 18;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Other&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;hierarchyid&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;No built-in support&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 19;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;xml&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.String&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 20;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;uniqueidentifier&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Guid&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 21; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;sql_variant&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Object&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;object&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;The mapping of spatial types are supported through NetTopologySuite, a free and open source library. For SQL database, just install the Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite NuGet package.&lt;/p&gt;
&lt;h3&gt;Database&lt;/h3&gt;
&lt;p&gt;A SQL database is mapped to a type derived from Microsoft.EntityFrameworkCore.DbContext:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks : DbContext { }&lt;/p&gt;
&lt;p&gt;The following is the definition of DbContext:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.EntityFrameworkCore&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class DbContext : IDisposable, IInfrastructure&amp;lt;IServiceProvider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbContext(DbContextOptions options);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ChangeTracker ChangeTracker { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual DatabaseFacade Database { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual int SaveChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected internal virtual void OnModelCreating(ModelBuilder modelBuilder);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DbContext implements IDisposable. Generally, a database instance should be constructed and disposed for each unit of work - a collection of data operations that should succeed or fail as a unit:&lt;/p&gt;
&lt;p&gt;internal static void Dispose()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Unit of work.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core also support DbContext pooling to improve performance. In the application or service, If DbContext is used through dependency injection, and it is no custom state (just like the above AdventureWorks type with no fields), then DbContext pooling can be enabled to reuse DbContext without disposing.&lt;/p&gt;
&lt;p&gt;In EF Core, most of the object-relational mapping can be implemented declaratively, and the rest of the mapping can be implemented imperatively by overriding DbContext.OnModelCreating, which is automatically called by EF Core during initialization:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected override void OnModelCreating(ModelBuilder modelBuilder)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;base.OnModelCreating(modelBuilder);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MapCompositePrimaryKey(modelBuilder);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MapManyToMany(modelBuilder);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MapDiscriminator(modelBuilder);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above MapCompositePrimaryKey, MapManyToMany, MapDiscriminator functions are implemented later in this chapter.&lt;/p&gt;
&lt;h3&gt;Connection resiliency and execution retry strategy&lt;/h3&gt;
&lt;p&gt;The connection to the mapped database can be specified from the constructor of DbContext:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public AdventureWorks(DbConnection connection = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: base(GetDbContextOptions(connection))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static DbContextOptions GetDbContextOptions(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DbConnection connection = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new DbContextOptionsBuilder&amp;lt;AdventureWorks&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.UseSqlServer(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection: connection ??
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new SqlConnection(ConnectionStrings.AdventureWorks),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sqlServerOptionsAction: options =&amp;gt; options.EnableRetryOnFailure(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;errorNumbersToAdd: null))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Options;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here when database connection is not provided to the constructor, a new database connection is created with the previously defined connection string. Also, regarding the connection between application and SQL database may be interrupted over the network, EF Core supports connection resiliency for SQL database. This is very helpful for Azure SQL database deployed in the cloud instead of local network. In the above example, EF Core is specified to automatically retries up to 5 times with the retry interval of 30 seconds.&lt;/p&gt;
&lt;h3&gt;Tables&lt;/h3&gt;
&lt;p&gt;There are tens of tables in the AdventureWorks database, but don’t panic, this book only involves a few tables, and a few columns of these tables. In EF Core, a table definition can be mapped to an entity type definition, where each column is mapped to a entity property. For example, the AdventureWorks database has a Production.ProductCategory table. Its definition can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE SCHEMA [Production];&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CREATE TYPE [dbo].[Name] FROM nvarchar(50) NULL;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductCategory](
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductCategoryID] int IDENTITY(1,1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_ProductCategory_ProductCategoryID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Name] [dbo].[Name] NOT NULL, -- nvarchar(50).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[rowguid] uniqueidentifier ROWGUIDCOL NOT NULL -- Ignored in mapping.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [DF_ProductCategory_rowguid] DEFAULT (NEWID()),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ModifiedDate] datetime NOT NULL -- Ignored in mapping.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [DF_ProductCategory_ModifiedDate] DEFAULT (GETDATE()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;This table definition can be mapped to a ProductCategory entity definition:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public const string Production = nameof(Production); // Production schema.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductCategory), Schema = AdventureWorks.Production)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductCategory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductCategoryID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string Name { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other columns are ignored.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The [Table] attribute specifies the table name and schema. [Table] can be omitted when the table name is the same as the entity name, and the table is under the default dbo schema. In the table-entity mapping:&lt;/p&gt;
&lt;p&gt;· The ProductCategoryID column of int type is mapped to a System.Int32 property with the same name. The [Key] attribute indicates it is a primary key. EF Core requires a table to have primary key to be mapped. [DatabaseGenerated] indicates it is an identity column, with value generated by database.&lt;/p&gt;
&lt;p&gt;· The Name column is of dbo.Name type. which is actually nvarchar(50), so it is mapped to Name property of type System.String. The [MaxLength] attribute indicates the max length of the string value is 50. [Required] indicates it should not be null or empty string or whitespace string.&lt;/p&gt;
&lt;p&gt;· The other columns rowguid and ModifiedDate are not mapped. They are not used in this book to keep the code examples simple.&lt;/p&gt;
&lt;p&gt;At runtime, each row of Production.ProductCategory table is mapped to a ProductCategory entity instance. The entire table can be mapped to an IQueryable&amp;lt;T&amp;gt; data source, exposed as a property of the database mapping. EF Core provides DbSet&amp;lt;T&amp;gt;, which implements IQueryable&amp;lt;T&amp;gt;, to represent a table data source:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;ProductCategory&amp;gt;ProductCategories { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core also supports immutable entity definition:&lt;/p&gt;
&lt;p&gt;[Table(nameof(ProductCategory), Schema = AdventureWorks.Production)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductCategory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public ProductCategory(int productCategoryID, string name) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.ProductCategoryID, this.Name) = (productCategoryID, name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductCategoryID { get; private set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string Name { get; private set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This book defines all table mapping as mutable, since it is easier to update the entities and save back to database.&lt;/p&gt;
&lt;h3&gt;Relationships&lt;/h3&gt;
&lt;p&gt;In SQL database, tables can have foreign key relationships, including one-to-one, one-to-many, and many-to-many relationships.&lt;/p&gt;
&lt;h3&gt;One-to-one&lt;/h3&gt;
&lt;p&gt;The following Person.Person table and HumanResources.Employee table has a one-to-one relationship:&lt;/p&gt;
&lt;p&gt;HumanResources.Employee table’s BusinessEntityID column is a foreign key that refers to Person.Person table’s primary key. Their definition can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE TABLE [Person].[Person](&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[BusinessEntityID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_Person_BusinessEntityID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[FirstName] [dbo].[Name] NOT NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[LastName] [dbo].[Name] NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [HumanResources].[Employee](
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[BusinessEntityID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_Employee_BusinessEntityID] PRIMARY KEY CLUSTERED
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_Employee_Person_BusinessEntityID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Person].[Person] ([BusinessEntityID]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[JobTitle] nvarchar(50) NOT NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[HireDate] date NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;So each row in HumanResources.Employee table refers to one row in Person.Person table (an employee must be a person). On the other hand, each row in Person.Person table can be referred by 0 or 1 row in HumanResources.Employee table (a person can be an employee, or not). This relationship can be represented by navigation property of entity type:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public const string Person = nameof(Person);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public const string HumanResources = nameof(HumanResources);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;Person&amp;gt; People { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;Employee&amp;gt; Employees { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(Person), Schema = AdventureWorks.Person)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class Person
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int BusinessEntityID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string FirstName { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string LastName { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Employee Employee { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(Employee), Schema = AdventureWorks.HumanResources)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class Employee
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ForeignKey(nameof(Person))]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int BusinessEntityID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string JobTitle { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime HireDate { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Person Person { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The [ForeignKey] attribute indicates Employee entity’s BusinessEntityID property is the foreign key for the relationship represented by navigation property. Here Person is called the primary entity, and Employee is called the dependent entity. Their navigation properties are called reference navigation properties, because each navigation property can refer to a single entity. The navigation property is designed to be virtual to enable proxy entity to implement lazy loading. Proxy entity and lazy loading is discussed in the query translation and data loading chapter.&lt;/p&gt;
&lt;h3&gt;One-to-many&lt;/h3&gt;
&lt;p&gt;The Production.ProductCategory and Production.ProductSubcategory tables have a one-to-many relationship, so are Production.ProductSubcategory and Production.Product:&lt;/p&gt;
&lt;p&gt;Each row in Production.ProductCategory table can refer to many rows in Production.ProductSubcategory table (category can have many subcategories), and each row in Production.ProductSubcategory table can refer to many rows in Production.Product table (subcategory can have many products). Their definitions can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE TABLE [Production].[ProductSubcategory](&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ProductSubcategoryID] int IDENTITY(1,1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_ProductSubcategory_ProductSubcategoryID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Name] [dbo].[Name] NOT NULL, -- nvarchar(50).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductCategoryID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_ProductSubcategory_ProductCategory_ProductCategoryID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Production].[ProductCategory] ([ProductCategoryID]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[Product](
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductID] int IDENTITY(1,1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Name] [dbo].[Name] NOT NULL, -- nvarchar(50).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ListPrice] money NOT NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductSubcategoryID] int NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_Product_ProductSubcategory_ProductSubcategoryID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Production].[ProductSubcategory] ([ProductSubcategoryID])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;These one-to-many relationships can be represented by navigation property of type ICollection&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;public partial class ProductCategory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ICollection&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; } // Collection navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductSubcategory), Schema = AdventureWorks.Production)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductSubcategory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductSubcategoryID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string Name { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductCategoryID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ProductCategory ProductCategory { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; } // Collection navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(Product), Schema = AdventureWorks.Production)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Required]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string Name { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public decimal ListPrice { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int? ProductSubcategoryID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ProductSubcategory ProductSubcategory { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice Production.Product table’s ProductSubcategoryID column is nullable, so it is mapped to a int? property. Here [ForeignKey] attribute is omitted, because each dependent entity’ foreign key is separated from its primary key, so the foreign key can be automatically discovered by EF Core.&lt;/p&gt;
&lt;h3&gt;Many-to-many&lt;/h3&gt;
&lt;p&gt;Production.Product and Production.ProductPhoto tables has many-to-many relationship.&lt;/p&gt;
&lt;p&gt;This is implemented by 2 one-to-many relationships with another Production.ProductProductPhoto junction table. These tables’ definitions can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE TABLE [Production].[ProductPhoto](&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ProductPhotoID] int IDENTITY(1,1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_ProductPhoto_ProductPhotoID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[LargePhotoFileName] nvarchar(50) NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ModifiedDate] datetime NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [DF_ProductPhoto_ModifiedDate] DEFAULT (GETDATE())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductProductPhoto](
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_ProductProductPhoto_Product_ProductID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Production].[Product] ([ProductID]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductPhotoID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_ProductProductPhoto_ProductPhoto_ProductPhotoID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Production].[ProductPhoto] ([ProductPhotoID]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_ProductProductPhoto_ProductID_ProductPhotoID] PRIMARY KEY NONCLUSTERED ([ProductID], [ProductPhotoID])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;So the many-to-many relationship can be mapped to 2 one-to-many relationships with the junction:&lt;/p&gt;
&lt;p&gt;public partial class Product&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } // Collection navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductPhoto), Schema = AdventureWorks.Production)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductPhoto
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductPhotoID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[MaxLength(50)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string LargePhotoFileName { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ConcurrencyCheck]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime ModifiedDate { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } // Collection navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductProductPhoto), Schema = AdventureWorks.Production)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductProductPhoto
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Column(Order = 0)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Column(Order = 1)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductPhotoID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Product Product { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ProductPhoto ProductPhoto { get; set; } // Reference navigation property.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;ProductPhoto.ModifiedDate has a [ConcurrencyCheck] attribute for concurrency conflict check, which is discussed in the data manipulation chapter. Production.ProductProductPhoto table has a composite primary key. As a junction table, each row in the table has a unique combination of ProductID and ProductPhotoID. EF Core requires additional initialization for composite primary key, which should be executed in DbContext’s OnModelCreating method:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static void MapCompositePrimaryKey(ModelBuilder modelBuilder) // Called by OnModelCreating.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasKey(productProductPhoto =&amp;gt; new
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductID = productProductPhoto.ProductID,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ProductPhotoID = productProductPhoto.ProductPhotoID
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;EF Core also requires additional initialization for many-to-many relationship represented by 2 one-to-many relationships, which should be executed in OnModelCreating as well:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static void MapManyToMany(ModelBuilder modelBuilder) // Called by OnModelCreating.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasOne(productProductPhoto =&amp;gt; productProductPhoto.Product)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMany(product =&amp;gt; product.ProductProductPhotos)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasForeignKey(productProductPhoto =&amp;gt; productProductPhoto.ProductID);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasOne(productProductPhoto =&amp;gt; productProductPhoto.ProductPhoto)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMany(photo =&amp;gt; photo.ProductProductPhotos)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasForeignKey(productProductPhoto =&amp;gt; productProductPhoto.ProductPhotoID);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Finally, all the above tables can be exposed as properties of AdventureWorks:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;Person&amp;gt; People { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;Employee&amp;gt; Employees { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;ProductSubcategory&amp;gt;ProductSubcategories { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;ProductPhoto&amp;gt; ProductPhotos { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Inheritance&lt;/h3&gt;
&lt;p&gt;EF Core supports table per hierarchy (TPH) inheritance for entity types. With TPH, one table is mapped to many entity types in the inheritance hierarchy, so a discriminator column is needed to identify each specific row’s mapping entity. Take the Production.TransactionHistory table as example, its definition can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE TABLE [Production].[TransactionHistory](&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TransactionID] int IDENTITY(100000,1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [PK_TransactionHistory_TransactionID] PRIMARY KEY CLUSTERED,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ProductID] int NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [FK_TransactionHistory_Product_ProductID] FOREIGN KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;REFERENCES [Production].[Product] ([ProductID]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[TransactionDate] datetime NOT NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[TransactionType] nchar(1) NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CONSTRAINT [CK_Product_Style]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CHECK (UPPER([TransactionType]) = N&apos;P&apos; OR UPPER([TransactionType]) = N&apos;S&apos; OR UPPER([TransactionType]) = N&apos;W&apos;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Quantity] int NOT NULL,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ActualCost] money NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other columns. */);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;Its TransactionType column allows value “P”, “S”, or “W” to indicate each row representing a purchase transaction, sales transaction, or work transaction. So the mapping entities’ hierarchy can be:&lt;/p&gt;
&lt;p&gt;[Table(nameof(TransactionHistory), Schema = AdventureWorks.Production)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class TransactionHistory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int TransactionID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int ProductID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime TransactionDate { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Quantity { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public decimal ActualCost { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class PurchaseTransactionHistory : TransactionHistory { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class SalesTransactionHistory : TransactionHistory { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;public class WorkTransactionHistory : TransactionHistory { }&lt;/p&gt;
&lt;p&gt;Then the discriminator must be specified when OnModelCreating is executed:&lt;/p&gt;
&lt;p&gt;public enum TransactionType { P, S, W }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static void MapDiscriminator(ModelBuilder modelBuilder) // Called by OnModelCreating.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;modelBuilder.Entity&amp;lt;TransactionHistory&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasDiscriminator&amp;lt;string&amp;gt;(nameof(TransactionType))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasValue&amp;lt;PurchaseTransactionHistory&amp;gt;(nameof(TransactionType.P))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasValue&amp;lt;SalesTransactionHistory&amp;gt;(nameof(TransactionType.S))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.HasValue&amp;lt;WorkTransactionHistory&amp;gt;(nameof(TransactionType.W));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now these entities can all be exposed as data sources:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;TransactionHistory&amp;gt;Transactions { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;PurchaseTransactionHistory&amp;gt; PurchaseTransactions { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;SalesTransactionHistory&amp;gt;SalesTransactions { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;WorkTransactionHistory&amp;gt;WorkTransactions { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Views&lt;/h3&gt;
&lt;p&gt;A view can also be mapped as if it is a table, if the view has one or more columns which can be virtually viewed as primary key. Take the Production.vEmployee view as example, its definition can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;CREATE VIEW [HumanResources].[vEmployee]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AS
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;e.[BusinessEntityID],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;p.[FirstName],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;p.[LastName],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;e.[JobTitle]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;-- Other columns.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FROM [HumanResources].[Employee] e
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;INNER JOIN [Person].[Person] p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ON p.[BusinessEntityID] = e.[BusinessEntityID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* Other tables. */;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;The BusinessEntityID is unique and can be the virtual primary key. So it can be mapped as the following entity:&lt;/p&gt;
&lt;p&gt;[Table(nameof(vEmployee), Schema = AdventureWorks.HumanResources)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class vEmployee
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Key]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int BusinessEntityID { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string FirstName { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string LastName { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string JobTitle { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And then expose as data source:&lt;/p&gt;
&lt;p&gt;public partial class AdventureWorks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DbSet&amp;lt;vEmployee&amp;gt; vEmployees { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Text:&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities in Depth (1) Remote Query</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-1-remote-query/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-1-remote-query/</guid><description>The previous chapters discussed LINQ to Objects, LINQ to XML, and Parallel LINQ. All of these LINQ technologies query local in-memory objects managed by .NET. This chapter discusses a different kind o</description><pubDate>Tue, 01 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core (EF Core) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework (EF) series&lt;/a&gt;]&lt;/h2&gt;
&lt;h3&gt;Entity Framework Core&lt;/h3&gt;
&lt;p&gt;The previous chapters discussed LINQ to Objects, LINQ to XML, and Parallel LINQ. All of these LINQ technologies query local in-memory objects managed by .NET. This chapter discusses a different kind of LINQ technology, LINQ to Entities, which queries relational data managed by databases. LINQ to Entities was initially provided by Entity Framework (EF), a Microsoft library released since .NET Framework 3.5 Service Pack 1. Since 2016, Microsoft also released Entity Framework Core (EF Core), along with .NET Core. EF Core is based on .NET Standard, so it works cross-platform.&lt;/p&gt;
&lt;p&gt;EF Core implements a provider model, so that LINQ to Entities can be implemented by different providers to work with different kinds of databases, including SQL Server (on-premise database) and Azure SQL Database (cloud database, aka SQL Azure), DB2, MySQL, Oracle, PostgreSQL, SQLLite, etc.&lt;/p&gt;
&lt;h3&gt;SQL database&lt;/h3&gt;
&lt;p&gt;To demonstrate LINQ to Entities queries and other database operations, this book uses the classic sample SQL database AdventureWorks provided by Microsoft as the data source, because this sample database has a very intuitive structure, it also works with Azure SQL Database and all SQL Server editions. The full sample database provided by Microsoft is relatively large, so a trimmed version is provided in the code samples repo of this book:&lt;/p&gt;
&lt;p&gt;· The AdventureWorks.bacpac file is for Azure SQL Database&lt;/p&gt;
&lt;p&gt;· The AdventureWorks_Data.mdf and AdventureWorks_Log.ldf files are for SQL Server&lt;/p&gt;
&lt;p&gt;There are many free options to setup SQL database. To setup in the cloud, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Sign up &lt;a href=&quot;https://azure.com/free&quot;&gt;Azure free trial&lt;/a&gt; program, or sign up &lt;a href=&quot;https://www.visualstudio.com/dev-essentials/&quot;&gt;Visual Studio Dev Essentials&lt;/a&gt; program, to get free Azure account and free credits.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sign in to Azure portal, create a storage account, then create a container, and upload the above bacpac file into the container.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Azure portal, create a SQL Database server, then add local IP address to the server’s firewall settings to enable access.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Azure portal, import the uploaded bacpac file from the storage account to the server, and create a SQL database. There the many pricing tier options for the database creation, where the Basic tier starts from about $5 per month, which can be covered by the free credit.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a alternative to cloud, SQL Server on premise can also be installed locally, then the above mdf and ldf files can be attached:&lt;/p&gt;
&lt;p&gt;· On Windows, there are several free options to install SQL Server:&lt;/p&gt;
&lt;p&gt;o SQL Server LocalDB: the easiest option, with no configuration required for setup.&lt;/p&gt;
&lt;p&gt;o SQL Server Express Core&lt;/p&gt;
&lt;p&gt;o SQL Server Express with Advanced Services&lt;/p&gt;
&lt;p&gt;o SQL Server Developer Edition: free after signing up &lt;a href=&quot;https://www.visualstudio.com/dev-essentials/&quot;&gt;Visual Studio Dev Essentials&lt;/a&gt; program&lt;/p&gt;
&lt;p&gt;o SQL Server Evaluation for the next version&lt;/p&gt;
&lt;p&gt;· On Linux, SQL Server Express, Developer, and Evaluation editions are freely licensed.&lt;/p&gt;
&lt;p&gt;· On Mac, SQL Server can be installed using a Windows/Linux virtual machine, or Docker&lt;/p&gt;
&lt;p&gt;After setting up, tools can be optionally installed to connect to and manage the SQL database:&lt;/p&gt;
&lt;p&gt;· On Windows, there are rich tools:&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt204009.aspx&quot;&gt;SQL Server Data Tools&lt;/a&gt; for Visual Studio, a free Visual Studio extension enabling SQL database management inside Visual Studio&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt238290.aspx&quot;&gt;SQL Server Management Tools&lt;/a&gt;, which includes &lt;a href=&quot;https://en.wikipedia.org/wiki/SQL_Server_Management_Studio&quot;&gt;SQL Server Management Studio&lt;/a&gt; (a free integration environment to manage SQL database), &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms181091.aspx&quot;&gt;SQL Server Profiler&lt;/a&gt; (a free tracing tool for SQL Server on premise), and other tools.&lt;/p&gt;
&lt;p&gt;· On Windows, Linux, and macOS:&lt;/p&gt;
&lt;p&gt;o SQL Server (mssql) for Visual Studio Code, an extension for Visual Studio Code to execute SQL&lt;/p&gt;
&lt;p&gt;o Azure Data Studio, a free cross-platform tool to manage data and edit query.&lt;/p&gt;
&lt;p&gt;To connect to the sample database, its connection string can be saved in the configuration of application or service during development and test. For .NET Core, the connection string can be saved for the application as a JSON file, for example, as app.json file:&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;ConnectionStrings&quot;: {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;AdventureWorks&quot;: &quot;Server=tcp:dixin.database.windows.net,1433;Initial Catalog=AdventureWorks;Persist Security Info=False;User ID=***;Password=***;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For .NET Framework, the connection string can be saved in the application’s app.config file:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;connectionStrings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;add name=&quot;AdventureWorks&quot; connectionString=&quot;Server=tcp:dixin.database.windows.net,1433;Initial Catalog=AdventureWorks;Persist Security Info=False;User ID=***;Password=***;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/connectionStrings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/configuration&amp;gt;&lt;/p&gt;
&lt;p&gt;Then the connection string can be loaded and used in C# code:&lt;/p&gt;
&lt;p&gt;internal static class ConnectionStrings&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static string AdventureWorks { get; } =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#if NETFX
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConfigurationManager.ConnectionStrings[nameof(AdventureWorks)].ConnectionString;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new ConfigurationBuilder().AddJsonFile(&quot;App.json&quot;).Build()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetConnectionString(nameof(AdventureWorks));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The connection string for production should be protected with encryption or tools like Azure Key Vault configuration provider.&lt;/p&gt;
&lt;h3&gt;Remote query vs. local query&lt;/h3&gt;
&lt;p&gt;LINQ to Objects, Parallel LINQ query .NET objects in current .NET application’s local memory, these queries are called local queries. LINQ to XML queries XML data source, which are local .NET objects representing XML structures as well, so LINQ to XML queries are also local queries. As demonstrated at the beginning of this book, LINQ can also query data in other data domains, like tweets in Twitter, rows in database tables, etc. Apparently, these data source are not .NET objects directly available in local memory. These queries are called remote queries.&lt;/p&gt;
&lt;p&gt;Remote LINQ (like LINQ to Entities) is provided as paraty of local LINQ (like LINQ to Objects). Since local data sources and local queries are represented by IEnumerable&amp;lt;T&amp;gt;, remote LINQ data sources (like a table in database) and remote queries (like a database query), are represented by System.Linq.IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;LINQ to (local) Objects&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;LINQ to (remote) Entities&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Collections.IEnumerable&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.IQueryable&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.IQueryable&amp;lt;T&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.IOrderedEnumerable&amp;lt;T&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.IOrderedQueryable&amp;lt;T&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.Enumerable&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 11pt;&quot;&amp;gt;System.Linq.Queryable&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryable : IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression Expression { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Type ElementType { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider Provider { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedQueryable : IQueryable, IEnumerable { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedQueryable&amp;lt;out T&amp;gt; : IQueryable&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IOrderedQueryable, IQueryable, IEnumerable { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET Standard and Microsoft libraries provide many implementation of IEnumerable&amp;lt;T&amp;gt;, like T[] representing array, List&amp;lt;T&amp;gt; representing mutable list, Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt; representing immutable list, etc. EF Core also provides implementation of IQueryable&amp;lt;T&amp;gt;, including Microsoft.EntityFrameworkCore.DbSet&amp;lt;T&amp;gt; representing database table, Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable&amp;lt;T&amp;gt; representing database query, etc.&lt;/p&gt;
&lt;p&gt;As the parity with System.Linq.Enumerable, System.Linq.Queryable static type provides the remote version of standard queries. For example, the following are the local and remote Where/Select/Concat/Cast queries side by side:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source1, IEnumerable&amp;lt;TSource&amp;gt; source2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IQueryable source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When defining each standard query in remote LINQ, the generic source and generic output are represented by IQueryable&amp;lt;T&amp;gt; instead of IEnumerable&amp;lt;T&amp;gt;, and the non-generic source is represented by IQueryable instead of IEnumerable. The iteratee functions are replaced by expression trees. Similarly, the following are the ordering queries side by side, where the ordered source and ordered output are represented by IOrderedQueryable&amp;lt;T&amp;gt; instead of IOrderedEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With this design, the fluent function chaining and the LINQ query expression pattern are automatically enabled for remote LINQ queries. It is the same syntax to write LINQ to Objects query and remote LINQ query.&lt;/p&gt;
&lt;p&gt;Queryable does not provide the following queries:&lt;/p&gt;
&lt;p&gt;· Empty/Range/Repeat: it does not make sense for .NET to locally generate a remote data source or remote query on the fly; the other generation query DefaultIfEmpty is available, because DefaultIfEmpty works with an existing IQueryable&amp;lt;T&amp;gt; source.&lt;/p&gt;
&lt;p&gt;· AsEnumerable: Enumerable.AsEnumerable types any IEnumerable&amp;lt;T&amp;gt; source just as IEnumerable&amp;lt;T&amp;gt;. Since IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;, Enumerable.AsEnumerable also works for IQueryanle&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;· ToArray/ToDictionary/ToList/ToLookup: LINQ to Objects provides these colection queries to pull values from any IEnumerable&amp;lt;T&amp;gt; source and create local .NET collections. Since IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;, these queries provided by LINQ to Objects also works for IQueryanle&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;· Max/Min overloads for .NET primary types: these are specific types of local .NET application, not the remote data domain.&lt;/p&gt;
&lt;p&gt;Queryable also provides an additional query AsQueryable, as the paraty with AsEnumerable. However, unlike AsSequential/AsParallel switching between sequential and parallel query, AsEnumerable/AsQueryable cannot freely switch between local and remote query. This query is discussed later.&lt;/p&gt;
&lt;h3&gt;Function vs. expression tree&lt;/h3&gt;
&lt;p&gt;Enumerable queries accept iteratee functions, and Queryable queries accept expression trees. As discussed in the lamda expression chapter, functions are executable .NET code, and expression trees are data structures representing the abstract syntax tree of functions, which can be translated to other domain-specific language. The lambda expression chapter also demonstrates compiling an arithmetic expression tree to CIL code at runtime, and executing it dynamically. The same approach can be used to translate arithmetic expression tree to SQL query, and execute it in a remote SQL database. The following function traverses an arithmetic expression tree with +, -, *, / operators, and compile it to a SQL SELECT statement with infix arithmetic expression:&lt;/p&gt;
&lt;p&gt;internal static string InOrder(this LambdaExpression expression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string VisitNode(Expression node)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (node.NodeType)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Constant when node is ConstantExpression constant:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return constant.Value.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Parameter when node is ParameterExpression parameter:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;@{parameter.Name}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// In-order output: left child, current node, right child.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Add when node is BinaryExpression binary:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;({VisitNode(binary.Left)} + {VisitNode(binary.Right)})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Subtract when node is BinaryExpression binary:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;({VisitNode(binary.Left)} - {VisitNode(binary.Right)})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Multiply when node is BinaryExpression binary:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;({VisitNode(binary.Left)} * {VisitNode(binary.Right)})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Divide when node is BinaryExpression binary:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;({VisitNode(binary.Left)} / {VisitNode(binary.Right)})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;default:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(expression));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;SELECT {VisitNode(expression.Body)};&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here @ is prepended to each parameter name, which is the SQL syntax. The following code demonstrates the compilation:&lt;/p&gt;
&lt;p&gt;internal static void Infix()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string sql = expression.InOrder();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sql.WriteLine(); // SELECT (((@a + @b) - ((@c * @d) / 2)) + (@e * 3));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following ExecuteSql function is defined to execute the compiled SQL statement with SQL parameters and SQL database connection string provided, and return the execution result from SQL database:&lt;/p&gt;
&lt;p&gt;internal static double ExecuteSql(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string connection,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string sql,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IDictionary&amp;lt;string, double&amp;gt; parameters)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (SqlConnection sqlConnection = new SqlConnection(connection))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sqlConnection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters.ForEach(parameter =&amp;gt; sqlCommand.Parameters.AddWithValue(parameter.Key, parameter.Value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (double)sqlCommand.ExecuteScalar();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following TranslateToSql function is defined to wrap the entire work. It accept an arithmetic expression tree, call the above InOrder to compile it to SQL, then emit a dynamic function, which extracts the parameters and calls above ExecuteScalar function to execute the SQL:&lt;/p&gt;
&lt;p&gt;public static TDelegate TranslateToSql&amp;lt;TDelegate&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this Expression&amp;lt;TDelegate&amp;gt; expression, string connection)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DynamicMethod dynamicMethod = new DynamicMethod(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string.Empty,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expression.ReturnType,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodBase.GetCurrentMethod().Module);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EmitCil(dynamicMethod.GetILGenerator(), expression.InOrder());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (TDelegate)(object)dynamicMethod.CreateDelegate(typeof(TDelegate));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void EmitCil(ILGenerator generator, string sql)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Dictionary&amp;lt;string, double&amp;gt; dictionary = new Dictionary&amp;lt;string, double&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.DeclareLocal(typeof(Dictionary&amp;lt;string, double&amp;gt;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OpCodes.Newobj,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;typeof(Dictionary&amp;lt;string, double&amp;gt;).GetConstructor(Array.Empty&amp;lt;Type&amp;gt;()));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Stloc_0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; expression.Parameters.Count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// dictionary.Add($&quot;@{expression.Parameters[i].Name}&quot;, args[i]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldloc_0); // dictionary.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldstr, $&quot;@{expression.Parameters[index].Name}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldarg_S, index);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OpCodes.Callvirt,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;typeof(Dictionary&amp;lt;string, double&amp;gt;).GetMethod(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nameof(Dictionary&amp;lt;string, double&amp;gt;.Add),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ExecuteSql(connection, expression, dictionary);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldstr, connection);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldstr, sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ldloc_0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OpCodes.Call,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;string, string, IDictionary&amp;lt;string, double&amp;gt;, double&amp;gt;(ExecuteSql).Method);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ret); // Returns the result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, .NET built-in Expression&amp;lt;TDelegate&amp;gt;.Compile method compiles expression tree to CIL, and emits a function to execute the CIL locally with current .NET application process. In contrast, here TranslateToSql compiles the arithmetic expression tree to SQL query, and emits a function to execute the SQL in a specified remote SQL database:&lt;/p&gt;
&lt;p&gt;internal static void TranslateAndExecute()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double, double, double, double, double&amp;gt; local = expression.Compile();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;local(1, 2, 3, 4, 5).WriteLine(); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double, double, double, double, double&amp;gt; remote = expression.TranslateToSql(ConnectionStrings.AdventureWorks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remote(1, 2, 3, 4, 5).WriteLine(); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (4) Performance</title><link>https://dixin.github.io/posts/parallel-linq-4-performance/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-4-performance/</guid><description>The purpose of PLINQ is to utilize multiple CPUs for better performance than LINQ to Objects However, PLINQ can also introduces performance overhead, like source partitioning and result merging. There</description><pubDate>Tue, 24 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The purpose of PLINQ is to utilize multiple CPUs for better performance than LINQ to Objects However, PLINQ can also introduces performance overhead, like source partitioning and result merging. There are many aspects that impact PLINQ query performance.&lt;/p&gt;
&lt;h3&gt;Sequential query vs. parallel query&lt;/h3&gt;
&lt;p&gt;To compare the performance of sequential and parallel query, take OrderBy query as example. PLINQ’s OrderBy requires partitioning the source, as well as buffering and merging the results. The following function compares the query execution duration of sequential OrderBy and parallel OrderBy:&lt;/p&gt;
&lt;p&gt;internal static void OrderByTest(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; keySelector, int sourceCount, int testRepeatCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] source = EnumerableX
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.RandomInt32(min: int.MinValue, max: int.MaxValue, count: sourceCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stopwatch stopwatch = Stopwatch.StartNew();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, testRepeatCount).ForEach(_ =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] sequentialResults = source.OrderBy(keySelector).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Stop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Sequential:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, testRepeatCount).ForEach(_ =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] parallel1Results = source.AsParallel().OrderBy(keySelector).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Stop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Parallel:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It calls the RandomInt32 query, which is defined in the LINQ to Objects custom queries chapter, to generate an array of random int values with the specified length. Then it executes the sequential and parallel OrderBy queries repeatedly for the specified times, so that the total execution time can be controlled in a reasonable range, the following code calls the OrderByTest function compares the sequential/parallel OrderBy execution on arrays of small/medium/large size, with the same simple key selector:&lt;/p&gt;
&lt;p&gt;internal static void OrderByTestForSourceCount()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(keySelector: value =&amp;gt; value, sourceCount: 5, testRepeatCount: 10_000);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:11 Parallel:1422
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(keySelector: value =&amp;gt; value, sourceCount: 5_000, testRepeatCount: 100);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:114 Parallel:107
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(keySelector: value =&amp;gt; value, sourceCount: 500_000, testRepeatCount: 100);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:18210 Parallel:8204
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following code compares the sequential/parallel OrderBy execution on arrays of the same size, with different key selector of light/medium/heavy workload:&lt;/p&gt;
&lt;p&gt;internal static void OrderByTestForKeySelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: value =&amp;gt; value + ComputingWorkload(baseIteration: 1),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceCount: Environment.ProcessorCount, testRepeatCount: 100_000);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:37 Parallel:2218
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: value =&amp;gt; value + ComputingWorkload(baseIteration: 10_000),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceCount: Environment.ProcessorCount, testRepeatCount: 1_000);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:115 Parallel:125
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OrderByTest(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: value =&amp;gt; value + ComputingWorkload(baseIteration: 100_000),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceCount: Environment.ProcessorCount, testRepeatCount: 100);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sequential:1240 Parallel:555
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It turns out PLINQ has better performance than LINQ to Objects with larger source and expensive iteratee function, which has a better chance to offset the overhead of partitioning and buffering/merging.&lt;/p&gt;
&lt;h3&gt;CPU bound operation vs. I/O bound operation&lt;/h3&gt;
&lt;p&gt;So far, all the examples are CPU bound operations. In most cases, PLINQ by default takes the logic processor count as the degree of parallelism. This makes sense for CPU bound operations, but may be not ideal for I/O bound operations. For example, when downloading files from Internet with parallel threads, it could be nice if the worker thread count can be controlled accurately disregarding the CPU core count. The following ForceParallel extension method can be implementation for this purpose:&lt;/p&gt;
&lt;p&gt;internal static void ForceParallel&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; iteratee, int degreeOfParallelism)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (degreeOfParallelism &amp;lt;= 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(degreeOfParallelism));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; partitions = Partitioner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Create(source, EnumerablePartitionerOptions.NoBuffering) // Stripped partitioning.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetPartitions(degreeOfParallelism);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConcurrentBag&amp;lt;Exception&amp;gt; exceptions = new ConcurrentBag&amp;lt;Exception&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void IteratePartition(IEnumerator&amp;lt;TSource&amp;gt; partition)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (partition)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (partition.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iteratee(partition.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (Exception exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;exceptions.Add(exception);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Thread[] threads = partitions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Skip(1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(partition =&amp;gt; new Thread(() =&amp;gt; IteratePartition(partition)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;threads.ForEach(thread =&amp;gt; thread.Start());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IteratePartition(partitions[0]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;threads.ForEach(thread =&amp;gt; thread.Join());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!exceptions.IsEmpty)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new AggregateException(exceptions);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It calls Partitioner.Create with EnumerablePartitionerOptions.NoBuffering, to enable stripped partitioning for better load balance. It then calls the created partitioner to create the specified number of partitions, and uses current thread and additional threads to simultaneously pull each partition and call the iterate function.&lt;/p&gt;
&lt;p&gt;To demonstrate the I/O bound operation, the following function first visualizes sequential download, then visualizes parallel download with PLINQ, and finally visualizes parallel download with above ForceParallel function. Again, assuming a quad core CPU, the degree of parallelism is specified as 10, which is higher than the core count:&lt;/p&gt;
&lt;p&gt;internal static void DownloadTest(string[] uris)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;byte[] Download(string uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (WebClient webClient = new WebClient())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return webClient.DownloadData(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;uris.Visualize(EnumerableEx.ForEach, uri =&amp;gt; Download(uri).Length.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int DegreeOfParallelism = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;uris.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithDegreeOfParallelism(DegreeOfParallelism)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.ForAll, uri =&amp;gt; Download(uri).Length.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;uris.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query: (source, iteratee) =&amp;gt; source.ForceParallel(iteratee, DegreeOfParallelism),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iteratee: uri =&amp;gt; Download(uri).Length.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following code queries some thumbnail picture file URIs from the Flickr RSS feed with LINQ to XML, then pass the URIs to above function to visualize the download:&lt;/p&gt;
&lt;p&gt;internal static void RunDownloadTestWithSmallFiles()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string[] smallThumbnailUris = XDocument
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Descendants((XNamespace)&quot;http://search.yahoo.com/mrss/&quot; + &quot;thumbnail&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Attributes(&quot;url&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(uri =&amp;gt; (string)uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DownloadTest(smallThumbnailUris);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here sequential download takes longer time, as expected. The PLINQ query is specified with a max degree of parallelism 10, but it decides to utilize 5 threads. ForceParallel starts 10 threads exactly as specified, and its execution time is about half of PLINQ.&lt;/p&gt;
&lt;p&gt;The following code queries for the same Flickr RSS feed, but for large picture file URIs, and visualize the download:&lt;/p&gt;
&lt;p&gt;internal static void RunDownloadTestWithLargeFiles()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string[] largePictureUris = XDocument
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Descendants((XNamespace)&quot;http://search.yahoo.com/mrss/&quot; + &quot;content&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Attributes(&quot;url&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(uri =&amp;gt; (string)uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DownloadTest(largePictureUris);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This time PLINQ still utilizes 5 threads from the beginning, then decides to start 2 more threads a while later. ForceParallel simply start 10 threads since the beginning. However, the duration of sequential download, PLINQ download, and ForceParallel download are about the same. This is because when downloading larger files, the network bandwidth is fully occupied and becomes the performance bottleneck, so the degree of parallelism does not make much difference.&lt;/p&gt;
&lt;h3&gt;Factors to impact performance&lt;/h3&gt;
&lt;p&gt;This part and the previous parts have demonstrated many aspects that can have performance impact for PLINQ, and here is a summary:&lt;/p&gt;
&lt;p&gt;· The partitioning strategy can impact performance, because different partitioning algorithms introduce different synchronization and load balance.&lt;/p&gt;
&lt;p&gt;· The 2 execution modes, Default (sequential or parallel) and ForceParallel, can result different performance&lt;/p&gt;
&lt;p&gt;· The degree of parallelism can impact performance, when degree of parallelism is set to 1, PLINQ works like sequential LINQ to Object.&lt;/p&gt;
&lt;p&gt;· The merge option can also impact performance, smaller buffer size can have the early value results available faster, but can also make the query execute longer.&lt;/p&gt;
&lt;p&gt;· The order preservation can impact the performance, query as unordered can have better performance, but can lead to incorrect results.&lt;/p&gt;
&lt;p&gt;· The source size can impact performance, for source with smaller size, the overhead of parallelization can be more significant, and result even lower performance than sequential query.&lt;/p&gt;
&lt;p&gt;· The iteratee function provided to query can impact performance, more expensive iteratee functions can have better performance with parallel queries.&lt;/p&gt;
&lt;p&gt;· The type of operation can impact performance, utilize more CPU cores can improve the performance of compute bound operation, but I/O bound operations can also depend on the I/O hardware.&lt;/p&gt;
&lt;p&gt;In the real world, the performance of each PLINQ query has to be measured and optimized accordingly.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;PLINQ’s query execution performance is impacted by many aspects. First PLINQ partitions source for parallel query. PLINQ implements range partitioning, chuck partitioning, hash partitioning, and stripped partitioning. These partitioning algorithms require different synchronization, and result different load balance among the query threads to impact the overall performance. .NET Standard also provides APIs to define custom static, dynamic, and orderable partitioners. To utilize multi-processor and offset the overhead of partitioning and merging, PLINQ can have better performance with larger size source and more expensive iteratee function. PLINQ’s query performance also should be optimized according to the type of operation.&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (3) Query Methods (Operators)</title><link>https://dixin.github.io/posts/parallel-linq-3-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-3-query-methods/</guid><description>Most of the PLINQ standard queries are the parities with LINQ to Objects standard queries, with the same syntax and functionality. For the additional queries in PLINQ, AsParallel, AsSequential and For</description><pubDate>Mon, 23 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Most of the PLINQ standard queries are the parities with LINQ to Objects standard queries, with the same syntax and functionality. For the additional queries in PLINQ, AsParallel, AsSequential and ForAll has been discussed. The rest of this chapter discusses the other additional queries, overloads, and the ordering relevant queries that have different behaviour from LINQ to Objects.&lt;/p&gt;
&lt;h3&gt;Query settings&lt;/h3&gt;
&lt;p&gt;PLINQ provides a few queries to configure the current cancellation token, degree of parallelism, execution mode, and merge options.&lt;/p&gt;
&lt;h3&gt;Cancellation&lt;/h3&gt;
&lt;p&gt;PLINQ query execution can be cancelled by providing a System.Threading.CancellationToken instance:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithCancellation&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, CancellationToken cancellationToken);&lt;/p&gt;
&lt;p&gt;A CancellationToken instance can be created with System.Threading.CancellationTokenSource:&lt;/p&gt;
&lt;p&gt;internal static void Cancel()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (CancellationTokenSource cancellationTokenSource =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new CancellationTokenSource(delay: TimeSpan.FromSeconds(1)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CancellationToken cancellationToken = cancellationTokenSource.Token;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Range(0, Environment.ProcessorCount * 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithCancellation(cancellationToken)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WiteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (OperationCanceledException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;exception.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The query has been canceled via the token supplied to WithCancellation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If the query executes for longer than 1 second, it is signalled to cancel, and throws an OperationCanceledException.&lt;/p&gt;
&lt;h3&gt;Degree of parallelism&lt;/h3&gt;
&lt;p&gt;WithDegreeOfParallelism specifies the maximum number of concurrent executing tasks:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithDegreeOfParallelism&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, int degreeOfParallelism);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void DegreeOfParallelism()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int maxConcurrency = Environment.ProcessorCount * 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, maxConcurrency)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithDegreeOfParallelism(maxConcurrency)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;WithDegreeOfParallelism accepts any int value from 1 to 512 (System.Linq.Parallel.Scheduling’s MAX_SUPPORTED_DOP constant field). At runtime, the actual query execution thread count is less than or equal to the specified maximum count. In the above example, WithDegreeOfParallelism is called with 40. However, when executing above query on a quad core CPU, the visualization shows PLINQ only utilizes 6 threads.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image002_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image002_thumb.gif&quot; alt=&quot;clip_image002&quot; title=&quot;clip_image002&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If WithDegreeOfParallelism is not called, the default degree of parallelism is the minimum value of current device’s processor count and 512:&lt;/p&gt;
&lt;p&gt;namespace System.Linq.Parallel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static class Scheduling
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal const int MAX_SUPPORTED_DOP = 512;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int DefaultDegreeOfParallelism = Math.Min(Environment.ProcessorCount, MAX_SUPPORTED_DOP);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int GetDefaultDegreeOfParallelism() =&amp;gt; DefaultDegreeOfParallelism;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Execution mode&lt;/h3&gt;
&lt;p&gt;WithExecutionMode specifies whether the query is allowed to execute sequentially or not:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithExecutionMode&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, ParallelExecutionMode executionMode);&lt;/p&gt;
&lt;p&gt;ParallelExecutionMode is an enumeration type with 2 members. The Default mode of PLINQ means PLINQ can detect the composition of the query and possibly decide to execute the query sequentially; And ForceParallelism requires the query to execute in parallel. For example:&lt;/p&gt;
&lt;p&gt;internal static void ExecutionMode()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = Environment.ProcessorCount * 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-2, nameof(ParallelExecutionMode.Default)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany((value, index) =&amp;gt; EnumerableEx.Return(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ElementAt(count - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-3, nameof(ParallelExecutionMode.ForceParallelism)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany((value, index) =&amp;gt; EnumerableEx.Return(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ElementAt(count - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image004_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image004_thumb.jpg&quot; alt=&quot;clip_image004&quot; title=&quot;clip_image004&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When PLINQ execute the above query composed with indexed SelectMany and ElementAt, in the default mode, it is the same sequential execution as LINQ to Objects. To have parallel query execution, the ForceParallelism mode has to be specified.&lt;/p&gt;
&lt;h3&gt;Merging&lt;/h3&gt;
&lt;p&gt;PLINQ can partition the source values so that the query can be executed in parallel. To merge the results, WithMergeOptions can be used to suggest the strategy:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithMergeOptions&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, ParallelMergeOptions mergeOptions);&lt;/p&gt;
&lt;p&gt;ParallelMergeOptions is an enumeration with 4 members. NotBuffered means when each result value is available, it is yielded immediately without being buffered., which is similar to lazy evaluation in LINQ to Objects; FullyBuffered means all results are stored in the fully sized buffer, then, they are yielded, which is similar to eager evaluation in LINQ to Objects; AutoBuffered is between NotBuffered and FullyBuffered, means the buffer size is determined by PLINQ, some results are stored in the auto sized buffer, and ones the buffer is full, the results are yielded; And Default is the same as AutoBuffered. The following code demonstrates the difference of these options:&lt;/p&gt;
&lt;p&gt;internal static void MergeForSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stopwatch stopwatch = Stopwatch.StartNew();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt;notBuffered = ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.NotBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;notBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:217 3:283 6:363 8:462 1:521 4:612 7:629 9:637 2:660 5:695
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt;autoBuffered = ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.AutoBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;autoBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 6:459 8:493 7:498 9:506 0:648 1:654 2:656 3:684 4:686 5:688
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt;fullyBuffered = ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.FullyBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;fullyBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:584 1:589 2:618 3:627 4:629 5:632 6:634 7:636 8:638 9:641
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For above Select query execution, if NotBuffered is specified, the first result value is yielded faster; if FullyBuffered is specified, the last result value is yielded faster; if AutoBuffered is specified, the behaviour is between NotBuffered and FullyBuffered. Also, since FullyBuffered buffers all results, it can preserve their order, while NotBuffered and AutoBuffered cannot. When pulling the results, ForEach is used here instead of ForAll to demonstrate that ParallelMergeOptions also impact the ordering of PLINQ query. When everything is fully buffered, PLINQ can have the ability to merge everything as ordered.&lt;/p&gt;
&lt;p&gt;WithMergeOptions just provides a suggestion to PLINQ, so PLINQ can still make its own decision. For example, ForAll is NotBuffered, and yields whatever is pulled. If above queries are executed with ForAll instead of ForEach, all queries’ results become unordered. Another example is, OrderBy has to evaluate all source values, fully buffer them, then sort them:&lt;/p&gt;
&lt;p&gt;internal static void MergeForOrderBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = Environment.ProcessorCount * 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stopwatch stopwatch = Stopwatch.StartNew();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.NotBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:132 2:273 1:315 4:460 3:579 6:611 5:890 7:1103
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.NotBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(value =&amp;gt; value) // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:998 1:999 2:999 3:1000 4:1000 5:1000 6:1001 7:1001
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WithMergeOptions(ParallelMergeOptions.FullyBuffered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(value =&amp;gt; value) // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:984 1:985 2:985 3:986 4:987 5:987 6:988 7:989
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So OrderBy ignores the suggested ParallelMergeOptions and always fully buffer the results.&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;In PLINQ, it is more complex to control the order of values than in sequential LINQ to Objects. Apparently, the order of values may not be persisted when they are not sequentially processed. As demonstrated above, WithMergeOptions is one way to impact the order of query results, where ParallelMergeOptions.FullyBuffered can be specified to preserve the order. PLINQ also provides other APIs to control the order.&lt;/p&gt;
&lt;h3&gt;Preserving the order&lt;/h3&gt;
&lt;p&gt;AsOrdered query can be called to specify the order in the source should be preserved for its subsequent queries:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsOrdered&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;AsOrdered can only be called on the ParallelQuery&amp;lt;T&amp;gt; instance which is the output of ParallelEnumerable.AsParallel, ParallelEnumerable.Range, or ParallelEnumerable.Repeat. It throws InvalidOperationException for ParallelQuery&amp;lt;T&amp;gt; instance output by any other queries.&lt;/p&gt;
&lt;p&gt;internal static void AsOrdered()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; value.WriteLine()); // 3 1 2 0 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsOrdered()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; value.WriteLine()); // 0 1 2 3 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here ForEach is used instead of ForAll again to demonstrate the order of query results. In contrast, AsUnordered is provided to ignore the order in the source for its subsequent queries:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsUnordered&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;Ignoring the order may improve the query performance. Take GroupBy as example, it can run faster if the PLINQ query is explicitly specified to be unordered. The following example uses a tuple of string and int to represent a product’s name and weight, and group many products by their weight:&lt;/p&gt;
&lt;p&gt;internal static void AsUnordered()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Random random = new Random();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string Name, int Weight)[] products = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 10_000)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(_ =&amp;gt; (Name: Guid.NewGuid().ToString(), Weight: random.Next(1, 10)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stopwatch stopwatch = Stopwatch.StartNew();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(model =&amp;gt; model.Weight)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(group =&amp;gt; group.Key.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Stop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.ElapsedMilliseconds.WriteLine(); // 800.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Restart();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;products
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsUnordered()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(model =&amp;gt; model.Weight)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(group =&amp;gt; group.Key.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.Stop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stopwatch.ElapsedMilliseconds.WriteLine(); // 103.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When ordering queries OrderBy, OrderByDescending, ThenBy, ThenByDescending and Reverse) are called, the order is introduced and preserved in the subsequent queries:&lt;/p&gt;
&lt;p&gt;internal static void OrderBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value) // Order is not preserved.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; value.WriteLine()); // 3 1 2 0 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value) // Order is not preserved.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(value =&amp;gt; value) // Order is preserved.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value) // Order is preserved.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; value.WriteLine()); // 0 1 2 3 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Order and correctness&lt;/h3&gt;
&lt;p&gt;In PLINQ, many queries are order sensitive. If the source is unordered, the following queries output indeterministic results:&lt;/p&gt;
&lt;p&gt;· Sequence queries:&lt;/p&gt;
&lt;p&gt;o Reverse: does nothing&lt;/p&gt;
&lt;p&gt;o SequenceEqual: compares values in arbitrary order&lt;/p&gt;
&lt;p&gt;o Skip: skips arbitrary values&lt;/p&gt;
&lt;p&gt;o SkipWhile: skips arbitrary values&lt;/p&gt;
&lt;p&gt;o Take: takes arbitrary values&lt;/p&gt;
&lt;p&gt;o TakeWhile: takes arbitrary values with the predicate&lt;/p&gt;
&lt;p&gt;o Zip: zips unordered values&lt;/p&gt;
&lt;p&gt;· Value queries:&lt;/p&gt;
&lt;p&gt;o ElementAt: returns arbitrary value&lt;/p&gt;
&lt;p&gt;o ElementAtOrDefault: returns arbitrary value or default&lt;/p&gt;
&lt;p&gt;o First: returns arbitrary value&lt;/p&gt;
&lt;p&gt;o FirstOrDefault: returns arbitrary value or default&lt;/p&gt;
&lt;p&gt;o Last: returns arbitrary value&lt;/p&gt;
&lt;p&gt;o LastOrDefault: returns arbitrary value or default&lt;/p&gt;
&lt;p&gt;These queries must be used with ordered source to have the correct query results.&lt;/p&gt;
&lt;p&gt;And, once again, ForAll pulls values and calls the specified function in parallel, and does not maintain the order as well.&lt;/p&gt;
&lt;p&gt;PLINQ also provides ordered partitioner for order preservation. The partitioner and ordered partitioner are discussed in the next chapter.&lt;/p&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;In PLINQ, Aggregate query requires the provided accumulator functions to be both commutative and associative.&lt;/p&gt;
&lt;h3&gt;Commutativity, associativity and correctness&lt;/h3&gt;
&lt;p&gt;Assume func is a function that accepts 2 parameters and returns a result, if func(a, b) ≡ func(b, a), then func is commutative; if func(func(a, b), c) ≡ func(a, func(b, c)), then func is associative. For example:&lt;/p&gt;
&lt;p&gt;internal static void CommutativeAssociative()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func1 = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1(1, 2) == func1(2, 1)).WriteLine(); // True, commutative
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1(func1(1, 2), 3) == func1(1, func1(2, 3))).WriteLine(); // True, associative.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func2 = (a, b) =&amp;gt; a * b + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func2(1, 2) == func2(2, 1)).WriteLine(); // True, commutative
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func2(func2(1, 2), 3) == func2(1, func2(2, 3))).WriteLine(); // False, not associative.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func3 = (a, b) =&amp;gt; a;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func3(1, 2) == func3(2, 1)).WriteLine(); // False, not commutative
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func3(func3(1, 2), 3) == func3(1, func3(2, 3))).WriteLine(); // True, associative.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func4 = (a, b) =&amp;gt; a - b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func4(1, 2) == func4(2, 1)).WriteLine(); // False, not commutative
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func4(func4(1, 2), 3) == func4(1, func4(2, 3))).WriteLine(); // False, not associative.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To demonstrate how parallel aggregation is impacted by commutativity and associativity, it can be compared with sequential aggregation:&lt;/p&gt;
&lt;p&gt;internal static void AggregateCorrectness()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = Environment.ProcessorCount * 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sequentialAdd = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a + b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequentialAdd.WriteLine(); // 28
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parallelAdd = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a + b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parallelAdd.WriteLine(); // 28
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sequentialSubtract = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a - b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequentialSubtract.WriteLine(); // -28
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parallelSubtract = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a - b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parallelSubtract.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, parallelSubtract has incorrect result value, because the function provided to Aggregate is neither commutative nor associative. The following code visualizes the aggregation:&lt;/p&gt;
&lt;p&gt;internal static void VisualizeAggregate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = Environment.ProcessorCount * 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-1, &quot;Sequential subtract&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Sequential subtract&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sequentialSubtract = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, $&quot;{a}, {b} =&amp;gt; {a - b}&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return a - b + ComputingWorkload();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-2, &quot;Parallel subtract&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Parallel subtract&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parallelSubtract = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, $&quot;{a}, {b} =&amp;gt; {a - b}&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return a - b + ComputingWorkload();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The sequential aggregation has the expected process:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image006_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image006_thumb.gif&quot; alt=&quot;clip_image006&quot; title=&quot;clip_image006&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The parallel aggregation has different behaviours:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image008_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_12942/clip_image008_thumb.gif&quot; alt=&quot;clip_image008&quot; title=&quot;clip_image008&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It follows the pattern of parallel query methods. It first partitions the data. On this quad core CPU, it splits the 8 source values into 4 partitions, (0, 1), (2, 3), (4, 5), (6, 7). Then it execute the provided function for each parallel in parallel, the 4 partitions’ result values are –1, –1, –1, –1. And finally it merges the 4 result values with the provided function, so the final aggregation result is 2. This demonstrates that the accumulator function must be commutative and associative for the parallel aggregation.&lt;/p&gt;
&lt;h3&gt;Merging&lt;/h3&gt;
&lt;p&gt;PLINQ provides 2 additional Aggregate overloads, where the seed for each partition is specified with either a value or a value factory function:&lt;/p&gt;
&lt;p&gt;public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate seed,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;updateAccumulatorFunc,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TAccumulate, TAccumulate&amp;gt;combineAccumulatorsFunc,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate&amp;gt;seedFactory,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;updateAccumulatorFunc,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TAccumulate, TAccumulate&amp;gt;combineAccumulatorsFunc,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);&lt;/p&gt;
&lt;p&gt;They also both accept 2 accumulator functions. First, updateAccumulatorFunc can be read as “source value accumulator”, it accumulates the values within each partition to a partition result. Then, combineAccumulatorsFunc can be read as “partition result accumulator”, it accumulates all partitions’ results to a single final result. The following example calculates the sum of squares:&lt;/p&gt;
&lt;p&gt;internal static void MergeForAggregate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = Environment.ProcessorCount * 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parallelSumOfSquares1 = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: 0, // Seed for each partition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;updateAccumulatorFunc: (accumulation, value) =&amp;gt; accumulation + value * value, // Source value accumulator for each partition&apos;s result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;combineAccumulatorsFunc: (accumulation, partition) =&amp;gt; accumulation + partition, // Partition result accumulator for final result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: result =&amp;gt; result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parallelSumOfSquares1.WriteLine(); // 140
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parallelSumOfSquares2 = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seedFactory: () =&amp;gt; 0, // Seed factory for each partition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;updateAccumulatorFunc: (accumulation, value) =&amp;gt; accumulation + value * value, // Source value accumulator for each partition&apos;s result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;combineAccumulatorsFunc: (accumulation, partition) =&amp;gt; accumulation + partition, // Partition result accumulator for final result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: result =&amp;gt; result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parallelSumOfSquares2.WriteLine(); // 140
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the parallel aggregation, first the sum of squares is calculated for each partition. Then all partitions’ results are summed up to the final result.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;PLINQ is a parity with LINQ to Objects that supports parallel execution. The query execution can be rendered as intuitive charts with Microsoft’s Concurrency Visualizer tool. PLINQ provides parallel standard queries as parities with LINQ to Objects’ sequential standard queries. PLINQ also provides additional queries for conversion between sequential query and parallel query, configuring parallel query, etc. Some PLINQ queries require the source to be ordered to have accurate query results, and the Aggregate query requires the accumulator function to be commutative and associative to have accurate query result.&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (2) Partitioning</title><link>https://dixin.github.io/posts/parallel-linq-2-partitioning/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-2-partitioning/</guid><description>The previous chapter discussed what is PLINQ and how to use PLINQ. This chapter looks into PLINQ’s internals and execution, including data processing and query performance.</description><pubDate>Sun, 22 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous chapter discussed what is PLINQ and how to use PLINQ. This chapter looks into PLINQ’s internals and execution, including data processing and query performance.&lt;/p&gt;
&lt;h2&gt;Internal partitioning and load balancing&lt;/h2&gt;
&lt;p&gt;To execute query with multithreading, PLINQ must split the data source’s values for those query threads as the first step. Internally, PLINQ has 4 different data partitioning algorithms – range partitioning, chunk partitioning, strip partitioning, and hash partitioning. These partitioning algorithms lead to different load balancing among the multiple query threads, and impact the overall performance.&lt;/p&gt;
&lt;h3&gt;Range partitioning&lt;/h3&gt;
&lt;p&gt;Range partitioning works with indexed source with a known length, such as T [] arrays with an indexer and Length property, and IList&amp;lt;T&amp;gt; lists with an indexer and Count property. Assume on a quad core CPU, there are 12 values in the source array, by default PLINQ splits these 12 values (at indexes 0, 1, 2, …, 11) into 4 partition A, B, C, D as the following:&lt;/p&gt;
&lt;p&gt;Index: 0 1 2 3 4 5 6 7 8 9 10 11&lt;/p&gt;
&lt;p&gt;Partition: A A A B B B C C C D D D&lt;/p&gt;
&lt;p&gt;If there are 13 source values, there are partitioned as: AAAA, BBB, CCC, DDD; 14 values are partitioned as AAAA, BBBB, CCC, DDD; 15 values are partitioned as AAAA, BBBB, CCCC, DDD; 16 values are partitioned as AAAA, BBBB, CCCC, DDDD; and so on.&lt;/p&gt;
&lt;p&gt;With the Visualize and ComputingWorkload functions defined in the previous chapter, the following code can visualize how an array is partitioned by range of index:&lt;/p&gt;
&lt;p&gt;internal static void RangePartitioningForArray()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] array = Enumerable.Range(0, Environment.ProcessorCount * 4).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;array.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Execute the above code with Concurrency Visualizer for Visual Studio, the following chart is rendered:&lt;/p&gt;
&lt;p&gt;Here the timespan of processing value 12 is longer than the timespan of processing value 15, because CPU was fully utilized at the beginning. Regarding there are also other processes and threads running on the device, when processing value 12, the query thread cannot ideally utilize 25% of CPU (100% of one core). In range partitioning, since each value of the source goes to a deterministic partition based on the value’s index, synchronization is not required for multiple query threads to simultaneously pull values from a shared source. This algorithm does not consider the actual work of the query threads, so it does not balance the load very well. For example, the partition (0, 1, 2, 3) is quickly processed by a query thread, then that thread becomes idle and just waits for other threads to be done with other partitions.&lt;/p&gt;
&lt;h3&gt;Chunk partitioning&lt;/h3&gt;
&lt;p&gt;Chunk partitioning can be used for sequence without index, where each thread pulls a chunk of values at a time. The chunk size starts from 1, and increases to 2, 4, 8, 16, …. Initially the chunk size is 1, each thread repeatedly pulls N chunks; Then the chunk size increases to 2, and each thread repeatedly pulls N chunks again; Then the chunk size increase to 4, and each thread repeatedly pulls another N chunk again; and so on. For a sequence, the chunk repeat count N is implemented as 8. Assume a quad core CPU, PLINQ split values in source into 4 partitions A, B, C, D by default, then the partitioning for source values is: ABCD, ABCD, …, AABBCCDD, AABBCCDD, …, AAAABBBBCCCCDDDD, AAAABBBBCCCCDDDD, ..., assuming each value’s processing cost the same time. The following code visualizes the chunk partitioning for a sequence without index:&lt;/p&gt;
&lt;p&gt;internal static void ChunkPartitioningForSequence()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int ChunkRepeatCount = 8;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; sequence = Enumerable.Range(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;0, (1 + 2) * ChunkRepeatCount * Environment.ProcessorCount + 4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequence.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When executing this query on a quad core CPU, for each query thread, the first 8 chunks have 1 value in each chunk, the next 8 chunks have 2 continuous values in each chunk, the last chunk has 4 continuous values, and they are all partitioned to one thread:&lt;/p&gt;
&lt;p&gt;With chuck partitioning, synchronization is required for multiple query threads to access the shared source, so that each chunk of values is exclusively pulled by one thread. Internally, PLINQ utilizes C# lock statement with a synchronization object to synchronize the query threads. This approach can balance the load at chunk level, which has an incremental size.&lt;/p&gt;
&lt;p&gt;When chunk partitioning is used for partitioner, the chunk repeat count N is implemented as 3. The easiest way to create a partitioner is to call Partitioner.Create with a sequence:&lt;/p&gt;
&lt;p&gt;internal static void ChunkPartitioningForPartitioner()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int ChunkRepeatCount = 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Partitioner&amp;lt;int&amp;gt; partitioner = Partitioner.Create(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, (1 + 2) * ChunkRepeatCount * Environment.ProcessorCount + 4));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partitioner.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here Partitioner.Create has a Partitioner&amp;lt;T&amp;gt; output. The Partitioner&amp;lt;TSource&amp;gt; type is the contract to implement partitioning, which is discussed later in this chapter. Then the ParallelEnumerable.AsParallel overload for Partitioner&amp;lt;T&amp;gt; can be called:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsParallel&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this Partitioner&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;From there the PLINQ queries can be used subsequently. With a smaller repeat count, the chunks are more intuitive:&lt;/p&gt;
&lt;h3&gt;Hash partitioning&lt;/h3&gt;
&lt;p&gt;When PLINQ query needs to compare and group values in the source, like GroupBy, Join, GroupJoin, etc., it partitions the values based on hash code. To demonstrate this behaviour, a data structure with a custom hash algorithm can be defined:&lt;/p&gt;
&lt;p&gt;internal readonly struct Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Data(int value) =&amp;gt; this.Value = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Value { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override int GetHashCode() =&amp;gt; this.Value % Environment.ProcessorCount;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override string ToString() =&amp;gt; this.Value.ToString(); // For span label.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It just wraps an int value, but only produces 4 different hash code on a quad core CPU. The following code visualize how GroupBy query executes its elementSelector function:&lt;/p&gt;
&lt;p&gt;internal static void HashPartitioningForGroupBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Data&amp;gt; sequence = new int[] { 0, 1, 2, 2, 2, 2, 3, 4, 5, 6, 10 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; new Data(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequence.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(source, elementSelector) =&amp;gt; source.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: data =&amp;gt; data, // Key&apos;s GetHashCode is called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: elementSelector),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;data =&amp;gt; ComputingWorkload(data.Value).ToString()) // elementSelector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(group =&amp;gt; string.Join(&quot;, &quot;, group));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Parallel&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// source.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// keySelector: data =&amp;gt; data,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// elementSelector: data =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, data.ToString()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return ComputingWorkload(data.Value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .WriteLines(group =&amp;gt; string.Join(&quot;, &quot;, group));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here GroupBy uses Data instances as the keys, it internally calls each Data instance’s GetHashCode method, and uses the output hash codes for equality comparison and grouping, then it processes the Data instances group by group with multiple query threads. As a result, Data instances with the same hash code is partitioned together and processed by the same query thread. Apparently, hash partitioning balances the load at group level. The synchronization work is required when pulling each group exclusively.&lt;/p&gt;
&lt;p&gt;Similarly, the following example visualizes how Join query executes its resultSelector function:&lt;/p&gt;
&lt;p&gt;internal static void HashPartitioningForJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Data&amp;gt; outerSource = new int[] { 0, 1, 2, 2, 2, 2, 3, 6 }.Select(value =&amp;gt; new Data(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Data&amp;gt; innerSource = new int[] { 4, 5, 6, 7 }.Select(value =&amp;gt; new Data(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerSource.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(source, resultSelector) =&amp;gt; source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: innerSource.AsParallel(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: data =&amp;gt; data, // Key&apos;s GetHashCode is called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: data =&amp;gt; data, // Key&apos;s GetHashCode is called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (outerData, innerData) =&amp;gt; resultSelector(outerData)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;data =&amp;gt; ComputingWorkload(data.Value)) // resultSelector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, Data instances with the same hash code are partitioned together and processed by the same query thread:&lt;/p&gt;
&lt;h3&gt;Stripped partitioning&lt;/h3&gt;
&lt;p&gt;Stripped partitioning can work with source with or without index. In this algorithm, each PLINQ query thread just pulls one value from the source each time. when the thread finishes processing that value, it pulls another one value again, until the source has no value available. Still assume a quad core CPU, and assume it costs the same time for to process each value, then the partitioning result is:&lt;/p&gt;
&lt;p&gt;Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...&lt;/p&gt;
&lt;p&gt;Partition: A B C D A B C D A B C D A B C D ...&lt;/p&gt;
&lt;p&gt;Partitioner.Create has an overload for sequence source to create partitioner that implements stripped partitioning:&lt;/p&gt;
&lt;p&gt;internal static void StrippedPartitioningForPartitionerWithSequence()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Partitioner&amp;lt;int&amp;gt; partitioner = Partitioner.Create(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, Environment.ProcessorCount * 10),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerablePartitionerOptions.NoBuffering);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partitioner.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Patitioner.Create’s EnumerablePartitionerOptions parameter has 2 members, None and NoBuffering. If None is specified, a partitioner is created to implement chunk partitioning; If NoBuffering is specified, a partitioner is created to implement stripped partitioning. The above code renders the following chart:&lt;/p&gt;
&lt;p&gt;Partitioner.Create also provides similar overloads for array and list. Take the previous array as example:&lt;/p&gt;
&lt;p&gt;internal static void StrippedPartitioningForPartitionerWithArray()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] array = Enumerable.Range(0, Environment.ProcessorCount * 4).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Partitioner&amp;lt;int&amp;gt; partitioner = Partitioner.Create(array, loadBalance: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partitioner.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Partitioner.Create’s loadBalance parameter is a bool value. If false is specified, a partitioner is created to implement range partitioning; If true is specified, a partitioner is created to implement stripped partitioning. The above code renders the following chart:&lt;/p&gt;
&lt;h2&gt;Implementing custom partitioner&lt;/h2&gt;
&lt;p&gt;.NET Standard also provides APIs to implement custom partitioning. The contract is the System.Collections.Partitioner&amp;lt;TSource&amp;gt; abstract class:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Concurrent&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Partitioner&amp;lt;TSource&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected Partitioner() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual bool SupportsDynamicPartitions =&amp;gt; false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; GetPartitions(int partitionCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IEnumerable&amp;lt;TSource&amp;gt; GetDynamicPartitions() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotSupportedException(&quot;Dynamic partitions are not supported by this partitioner.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Static partitioner&lt;/h3&gt;
&lt;p&gt;A partitioner’s SupportsDynamicPartitions property has a bool output. When it is false, the partitioner is a static partitioner, which means its GetPartitions method is available. To call GetPartitions, the partition count must be specified at the beginning, so the partition count is static and cannot be changed once partitioning is started. The output of GetPartitions method is a list of iterators, where each iterator is used to yield the values of a partition. This design of having multiple IEnumerator&amp;lt;T&amp;gt; iterators to share one IEnumerable&amp;lt;T&amp;gt; sequence, is the same idea as the EnumerableEx.Share and IBuffer&amp;lt;T&amp;gt; from Ix library discussed in the Ix chapter. So a simple static partitioner can be implemented as a wrapper of IBuffer&amp;lt;T&amp;gt; created by Share:&lt;/p&gt;
&lt;p&gt;internal class StaticPartitioner&amp;lt;TSource&amp;gt; : Partitioner&amp;lt;TSource&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly IBuffer&amp;lt;TSource&amp;gt; Buffer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal StaticPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; this.Buffer = source.Share();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; GetPartitions(int partitionCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (partitionCount &amp;lt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(partitionCount));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, partitionCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(_ =&amp;gt; this.Buffer.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As demonstrated above, AsParallel can be called with partitioner:&lt;/p&gt;
&lt;p&gt;internal static void QueryStaticPartitioner()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, Environment.ProcessorCount * 4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The output IBuffer&amp;lt;T&amp;gt; of EnumerableEx.Share implements stripped partitioning. Similar to PLINQ, it internally also utilizes C# lock statement with a synchronization object to make sure each value is exclusively pulled by one thread. The above code renders the following chart:&lt;/p&gt;
&lt;h3&gt;Dynamic partitioner&lt;/h3&gt;
&lt;p&gt;When the output of SupportsDynamicPartitions property is true, the partitioner is a dynamic partitioner. Besides GetPartitions that splits source into specified number of partitions, dynamic partitioner’s GetDynamicPartitions is also available to split source into arbitrary number of partitions. The output of GetDynamicPartitions is a IEnumerable&amp;lt;T&amp;gt; sequence, whose GetEnumerator method can be called to output a IEnumerator&amp;lt;T&amp;gt; iterator that represents a partition. After partitioning is started, the output IEnumerable&amp;lt;T&amp;gt; sequence’s GetEnumerator method can be called again for arbitrary times, so the caller can have dynamic number of partitions. This scenario is still supported by IBuffer&amp;lt;T&amp;gt; from EnumerableEx.Share:&lt;/p&gt;
&lt;p&gt;internal class DynamicPartitioner&amp;lt;TSource&amp;gt; : StaticPartitioner&amp;lt;TSource&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal DynamicPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source) : base(source) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool SupportsDynamicPartitions =&amp;gt; true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override IEnumerable&amp;lt;TSource&amp;gt; GetDynamicPartitions() =&amp;gt; this.Buffer;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides PLINQ queries, dynamic partitioner can also be used with System.Threading.Tasks.Parallel’s ForEach function:&lt;/p&gt;
&lt;p&gt;namespace System.Threading.Tasks&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Parallel
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelLoopResult ForEach&amp;lt;TSource&amp;gt;(Partitioner&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; body);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Parallel.ForEach first checks SupportsDynamicPartitions. If it gets false, it throws an InvalidOperationException: The Partitioner used here must support dynamic partitioning; If it gets true, it then calls GetDynamicPartitions to partition the values and call the specified iteratee function in parallel for each partition:&lt;/p&gt;
&lt;p&gt;internal static void QueryDynamicPartitioner()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, Environment.ProcessorCount * 4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Parallel.ForEach(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new DynamicPartitioner&amp;lt;int&amp;gt;(source), value =&amp;gt; ComputingWorkload(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Parallel.ForEach has another overload accepting an IEnumerable&amp;lt;T&amp;gt; sequence, which is more commonly used:&lt;/p&gt;
&lt;p&gt;public static ParallelLoopResult ForEach&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; body);&lt;/p&gt;
&lt;p&gt;Internally, it calls the fore mentioned Partitioner.Create to create a dynamic partitioner from the source sequence.&lt;/p&gt;
&lt;h3&gt;Orderable partitioner&lt;/h3&gt;
&lt;p&gt;.NET also provides APIs for partitioning with order control. The contract is the System.Collections.OrderablePartitioner&amp;lt;TSource&amp;gt; abstract class, which is a subtype of Partitioner&amp;lt;TSource&amp;gt;. The following are the members of OrderablePartitioner&amp;lt;TSource&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Concurrent&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class OrderablePartitioner&amp;lt;TSource&amp;gt; : Partitioner&amp;lt;TSource&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected OrderablePartitioner(bool keysOrderedInEachPartition, bool keysOrderedAcrossPartitions, bool keysNormalized)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.KeysOrderedInEachPartition = keysOrderedInEachPartition;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.KeysOrderedAcrossPartitions = keysOrderedAcrossPartitions;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.KeysNormalized = keysNormalized;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool KeysNormalized { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool KeysOrderedInEachPartition { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool KeysOrderedAcrossPartitions { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract IList&amp;lt;IEnumerator&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;&amp;gt;GetOrderablePartitions(int partitionCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IEnumerable&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;GetOrderableDynamicPartitions() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotSupportedException(&quot;Dynamic partitions are not supported by this partitioner.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Instead of providing partitions of values, orderable partitioner provides partitions of key-value pairs, where key is the index of the value. Its GetOrderablePartitions method is the orderable parity with Partitioner&amp;lt;TSource&amp;gt;.GetPartitions, which gives a static count of partitions represented by iterators of index-value pairs; Its GetOrderableDynamicPartitions method is the orderable parity with Partitioner&amp;lt;TSource&amp;gt;.GetDynamicPartitions, which gives a sequence, where GetEnumerator can be called arbitrary times to get dynamic count of partitions; Its KeysNormalized property outputs a bool value to indicate whether the indexes increase from 0; Its KeysOrderedInEachPartition property indicates whether inside each partition, the indexes always increase, so that a later value’s index is always greater than an former value’s index; And its KeysOrderedAcrossPartitions property indicates whether indexes increase partition by partition, so that a later partition’s indexes are all greater than an former partition’s indexes. Once again, it is easy to implement orderable partitioner with EnumerableEx.Share and IBuffer&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal class OrderableDynamicPartitioner&amp;lt;TSource&amp;gt; : OrderablePartitioner&amp;lt;TSource&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly IBuffer&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt; buffer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal OrderableDynamicPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: base(keysOrderedInEachPartition: true, keysOrderedAcrossPartitions: true, keysNormalized: true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.buffer = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; new KeyValuePair&amp;lt;long, TSource&amp;gt;(Interlocked.Increment(ref index), value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Share();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool SupportsDynamicPartitions =&amp;gt; true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override IList&amp;lt;IEnumerator&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;&amp;gt;GetOrderablePartitions(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int partitionCount) =&amp;gt; Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, partitionCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(_ =&amp;gt; this.buffer.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override IEnumerable&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;GetOrderableDynamicPartitions() =&amp;gt; this.buffer;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Once orderable partitioner is converted with AsParallel, AsOrdered can be used to preserve the order:&lt;/p&gt;
&lt;p&gt;internal static partial class Partitioning&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void QueryOrderablePartitioner()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] source = Enumerable.Range(0, Environment.ProcessorCount * 2).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OrderableDynamicPartitioner&amp;lt;int&amp;gt;(source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(); // 1 0 5 3 4 6 2 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OrderableDynamicPartitioner&amp;lt;int&amp;gt;(source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsOrdered()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(); // 0 1 2 3 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new DynamicPartitioner&amp;lt;int&amp;gt;(source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsOrdered()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; value + ComputingWorkload())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// InvalidOperationException: AsOrdered may not be used with a partitioner that is not orderable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (1) Local Parallel Query and Visualization</title><link>https://dixin.github.io/posts/parallel-linq-1-local-parallel-query-and-visualization/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-1-local-parallel-query-and-visualization/</guid><description>LINQ to Objects and LINQ to XML queries are designed to work sequentially, and do not involve multi-threading, concurrency, or parallel computing. To scale LINQ query in multi-processor environment, .</description><pubDate>Fri, 20 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;LINQ to Objects and LINQ to XML queries are designed to work sequentially, and do not involve multi-threading, concurrency, or parallel computing. To scale LINQ query in multi-processor environment, .NET Standard provides parallel version of LINQ to Objects, called Parallel LINQ or PLINQ.&lt;/p&gt;
&lt;h2&gt;Parallel LINQ query&lt;/h2&gt;
&lt;p&gt;Parallel LINQ (to Objects) APIs are provided as a parity with (sequential) LINQ to Objects APIs:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;LINQ to Objects types&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;PLINQ types&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Collections.IEnumerable&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq.ParallelQuery&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq.ParallelQuery&amp;lt;T&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Linq.IOrderedEnumerable&amp;lt;T&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq.OrderedParallelQuery&amp;lt;T&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Linq.Enumerable&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq.ParallelEnumerable&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;As the parity with System.Linq.Enumerable, System.Linq.ParallelEnumerable static type provides the parallel version of standard queries. For example, the following is the comparison of the Range/Repeat generation queries’ sequential and parallel versions:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;int&amp;gt; Range(int start, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following are the sequential and parallel Where/Select/Concat/Cast queries side by side:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; first, ParallelQuery&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this ParallelQuery source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When defining each standard query in PLINQ, the generic source and generic output are represented by ParallelQuery&amp;lt;T&amp;gt; instead of IEnumerable&amp;lt;T&amp;gt;, and the non-generic source is represented by ParallelQuery instead of IEnumerable. The other parameter types remain the same. Similarly, the following are the ordering queries side by side, where the ordered source and ordered output are represented by OrderedParallelQuery&amp;lt;T&amp;gt; instead of IOrderedEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static OrderedParallelQuery&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static OrderedParallelQuery&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static OrderedParallelQuery&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this OrderedParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static OrderedParallelQuery&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this OrderedParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With this design, the fluent function chaining and the LINQ query expression pattern are automatically enabled for PLINQ queries. It is the same syntax to write LINQ to Objects query and PLINQ query.&lt;/p&gt;
&lt;p&gt;Besides the parities with Enumerable queries, ParallelEnumerable also provides additional queries and additional overloads for Aggregate query:&lt;/p&gt;
&lt;p&gt;· Sequence queries&lt;/p&gt;
&lt;p&gt;o Conversion: AsParallel, AsSequential&lt;/p&gt;
&lt;p&gt;o Query settings: WithCancellation, WithDegreeOfParallelism, WithExecutionMode, WithMergeOptions&lt;/p&gt;
&lt;p&gt;o Ordering: AsOrdered, AsUnordered&lt;/p&gt;
&lt;p&gt;· Value queries&lt;/p&gt;
&lt;p&gt;o Aggregation: Aggregate&lt;/p&gt;
&lt;p&gt;· Void queries&lt;/p&gt;
&lt;p&gt;o Iteration: ForAll&lt;/p&gt;
&lt;h3&gt;Parallel query vs. sequential query&lt;/h3&gt;
&lt;p&gt;A ParallelQuery&amp;lt;T&amp;gt; source can be created by calling generation queries provided by ParallelEnumerable, like Range, Repeat, etc., then the other parallel queries can be used subsequently:&lt;/p&gt;
&lt;p&gt;internal static void Generation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;double&amp;gt;sequentialQuery = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Repeat(0, 5) // Output IEnumerable&amp;lt;int&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(Enumerable.Range(0, 5)) // Call Enumerable.Concat.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(int32 =&amp;gt; int32 &amp;gt; 0) // Call Enumerable.Where.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; Math.Sqrt(int32)); // Call Enumerable.Select.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;double&amp;gt; parallelQuery = ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Repeat(0, 5) // Output ParallelQuery&amp;lt;int&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(ParallelEnumerable.Range(0, 5)) // Call ParallelEnumerable.Concat.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(int32 =&amp;gt; int32 &amp;gt; 0) // Call ParallelEnumerable.Where.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; Math.Sqrt(int32)); // Call ParallelEnumerable.Select.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A PLINQ query can also be started by calling ParallelEnumerable.AsParallel to convert IEnumerable&amp;lt;T&amp;gt;/IEnumerable to ParallelQuery&amp;lt;T&amp;gt;/ParallelQuery:&lt;/p&gt;
&lt;p&gt;public static ParallelQuery AsParallel(this IEnumerable source);&lt;/p&gt;
&lt;p&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsParallel&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;p&gt;internal static void AsParallel(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable source2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt;parallelQuery1 = source1 // IEnumerable&amp;lt;int&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel(); // Output ParallelQuery&amp;lt;int&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt; parallelQuery2 = source2 // IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel() // Output ParallelQuery.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;int&amp;gt;(); // Call ParallelEnumerable.Cast.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;AsParallel also has an overload accepting a partitioner. Partitioner is discussed in the next chapter.&lt;/p&gt;
&lt;p&gt;To use sequential queries for a ParallelQuery&amp;lt;T&amp;gt; source, just call ParallelEnumerable.AsSequential or ParallelEnumerable.AsEnumerable to convert ParallelQuery&amp;lt;T&amp;gt; to IEnumerable&amp;lt;T&amp;gt;, then the sequential queries can be used subsequently:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsSequential&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;ParallelEnumerable.AsEnumerable simply calls AsSequential internally, so they are identical. For example:&lt;/p&gt;
&lt;p&gt;internal static partial class QueryMethods&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static readonly Assembly CoreLibrary = typeof(object).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void SequentialParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; obsoleteTypes = CoreLibrary.GetExportedTypes() // Output IEnumerable&amp;lt;Type&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsParallel() // Output ParallelQuery&amp;lt;Type&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(type =&amp;gt; type.GetCustomAttribute&amp;lt;ObsoleteAttribute&amp;gt;() != null) // Call ParallelEnumerable.Where.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(type =&amp;gt; type.FullName) // Call ParallelEnumerable.Select.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsSequential() // Output IEnumerable&amp;lt;Type&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(name =&amp;gt; name); // Call Enumerable.OrderBy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;obsoleteTypes.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above query can be written in query expression syntax:&lt;/p&gt;
&lt;p&gt;internal static void QueryExpression()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;obsoleteTypes =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from name in
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(from type in CoreLibrary.GetExportedTypes().AsParallel()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where type.GetCustomAttribute&amp;lt;ObsoleteAttribute&amp;gt;() != null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select type.FullName).AsSequential()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;obsoleteTypes.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Parallel query execution&lt;/h3&gt;
&lt;p&gt;The foreach statement or the EnumerableEx.ForEach query provided by Ix can be used to sequentially pull the results and start LINQ to Objects query execution. Their parallel version is the ParallelEnumerable.ForAll query.&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class EnumerableEx
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source, Action&amp;lt;TSource&amp;gt;onNext);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void ForAll&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt;source, Action&amp;lt;TSource&amp;gt;action);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;ForAll can simultaneously pull results from ParallelQuery&amp;lt;T&amp;gt; source with multiple threads, and simultaneously call the specified function on those threads:&lt;/p&gt;
&lt;p&gt;internal static void ForEachForAll()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(value =&amp;gt; value.WriteLine()); // 0 1 2 3 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForAll(value =&amp;gt; value.WriteLine()); // 2 6 4 0 5 3 7 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Above is the output after executing the code in a quad core CPU, Unlike ForEach, the values pulled and traced by ForAll is unordered. And if this code runs multiple times, the values can be in different order from time to time. This indeterministic order is the consequence of parallel pulling. The order preservation in parallel query execution is discussed in detail later.&lt;/p&gt;
&lt;p&gt;Earlier a WriteLines extension method is defined for IEnumerable&amp;lt;T&amp;gt; as a shortcut to call EnumerableEx.ForEach to pull all values and trace them. The following WriteLines overload can be defined for ParallelQuery&amp;lt;T&amp;gt; to call ParallelEnumerable.ForAll to simply execute parallel query without calling a function for each query result:&lt;/p&gt;
&lt;p&gt;public static void WriteLines&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, string&amp;gt; messageFactory = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (messageFactory == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.ForAll(value =&amp;gt; Trace.WriteLine(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.ForAll(value =&amp;gt; Trace.WriteLine(messageFactory(value)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Visualizing parallel query execution&lt;/h2&gt;
&lt;p&gt;It would be nice if the internal execution of sequential/parallel LINQ queries can be visualized with charts. On Windows, Microsoft provides a tool called Concurrency Visualizer for this purpose. It consists of a library of APIs to trace the execution information, and a Visual Studio extension to render the execution information to chart. This tool is very easy and intuitive. Unfortunately, it only renders chart on Windows along with Visual Studio.&lt;/p&gt;
&lt;h3&gt;Using Concurrency Visualizer&lt;/h3&gt;
&lt;p&gt;To install the Visual Studio extension, just launch Visual Studio, go to Tools =&amp;gt; extensions and Updates… =&amp;gt; Online, search “Concurrency Visualizer”, and install. Then restart Visual Studio to complete the installation, and go to Analyze =&amp;gt; Concurrency Visualizer =&amp;gt; Advanced Settings. In the Filter tab, check Sample Events only:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image002_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image002_thumb.jpg&quot; alt=&quot;clip_image002&quot; title=&quot;clip_image002&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to Markers tab, check ConcurrencyVisualizer.Markers only:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image004_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image004_thumb.jpg&quot; alt=&quot;clip_image004&quot; title=&quot;clip_image004&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Files tab, specified a proper directory for trace files. Notice the trace files can be very large, which depends on how much information is collected.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image006_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image006_thumb.jpg&quot; alt=&quot;clip_image006&quot; title=&quot;clip_image006&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, a reference to Concurrency Visualizer library need to be added to project. Microsoft provides this library as a binary on its web page. For convenience, I have created a NuGet package ConcurrencyVisualizer for .NET Framework and .NET Standard. The library provides the following APIs to render timespans on the time line:&lt;/p&gt;
&lt;p&gt;namespace Microsoft.ConcurrencyVisualizer.Instrumentation&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Markers
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Span EnterSpan(int category, string text);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static MarkerSeries CreateMarkerSeries(string markSeriesName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class MarkerSeries
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Span EnterSpan(int category, string text);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The category parameter is used to determine the color of the rendered timespan, and the text parameter is the label for the rendered timespan.&lt;/p&gt;
&lt;p&gt;For Linux and macOS, where Visual Studio is not available, the above Marker, MarkerSeries, and Span types can be manually defined to trace text information:&lt;/p&gt;
&lt;p&gt;public class Markers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Span EnterSpan(int category, string spanName) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Span(category, spanName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static MarkerSeries CreateMarkerSeries(string markSeriesName) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new MarkerSeries(markSeriesName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Span : IDisposable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int category;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly string spanName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly DateTime start;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Span(int category, string spanName, string markSeriesName = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.category = category;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.spanName = string.IsNullOrEmpty(markSeriesName)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? spanName : $&quot;{markSeriesName}/{spanName}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.start = DateTime.Now;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{this.start.ToString(&quot;o&quot;)}: thread id: {Thread.CurrentThread.ManagedThreadId}, category: {this.category}, span: {this.spanName}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Dispose()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime end = DateTime.Now;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{end.ToString(&quot;o&quot;)}: thread id: {Thread.CurrentThread.ManagedThreadId}, category: {this.category}, span: {this.spanName}, duration: {end – this.start}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class MarkerSeries
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly string markSeriesName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public MarkerSeries(string markSeriesName) =&amp;gt; this.markSeriesName = markSeriesName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Span EnterSpan(int category, string spanName) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Span(category, spanName, this.markSeriesName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a lot of information is traced, more trace listeners can be optionally added to save the information to file or print to console:&lt;/p&gt;
&lt;p&gt;public partial class Markers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;static Markers()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Trace to file:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Listeners.Add(new TextWriterTraceListener(@&quot;D:\Temp\Trace.txt&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Trace to console:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Visualizing sequential and parallel query execution&lt;/h3&gt;
&lt;p&gt;Now, the Marker, MarkerSeries, and Span types can be used with LINQ queries and ForEach/ForAll to visualize the sequence/parallel execution on Windows, or trace the execution on Linux and macOS:&lt;/p&gt;
&lt;p&gt;internal static void RenderForEachForAllSpans()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string SequentialSpan = nameof(EnumerableEx.ForEach);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Render a timespan for the entire sequential LINQ query execution, with text label &quot;ForEach&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-1, SequentialSpan))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(SequentialSpan);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, Environment.ProcessorCount * 2).ForEach(value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Render a sub timespan for each iteratee execution, with each value as text label.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Add workload to extend the iteratee execution to a more visible timespan.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10_000_000; i++) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 0 1 2 3 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string ParallelSpan = nameof(ParallelEnumerable.ForAll);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Render a timespan for the entire parallel LINQ query execution, with text label &quot;ForAll&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(-2, ParallelSpan))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(ParallelSpan);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Range(0, Environment.ProcessorCount * 2).ForAll(value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Render a sub timespan for each iteratee execution, with each value as text label.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Add workload to extends the iteratee execution to a more visible timespan.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10_000_000; i++) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 2 6 4 0 5 3 7 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In ForEach and ForAll’s iteratee functions, a for loop of 10 million iterations is executed to add some CPU computing workload to make the function call take longer time, otherwise the rendered timespan of function call can be too small to read. On Windows, click Visual Studio =&amp;gt; Analyze =&amp;gt; Concurrency Visualizer =&amp;gt; Start with Current Project. When the code finishes running, a rich UI is generated. The first tab Utilization shows that the CPU usage was about 25% for a while, which is the sequential LINQ query executing on the quad core CPU. Then the CPU usage became almost 100%, which is the PLINQ execution.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image008_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image008_thumb.gif&quot; alt=&quot;clip_image008&quot; title=&quot;clip_image008&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The second tab Threads has the chart of timespans. In the thread list on the left, right click the threads not working on LINQ queries and hide them, so that the chart only has the rendered timespans:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image010_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image010_thumb.gif&quot; alt=&quot;clip_image010&quot; title=&quot;clip_image010&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It uncovers how the LINQ queries execute on this quad core CPU. ForEach query pulls the values and call the specified function sequentially with the main thread. ForAll query does the work with 4 threads (main threads and 3 other worker threads), each thread processed 2 values. The values 6, 0, 4, 2 are processed before 7, 1, 5, 3, which leads to the trace output: 2 6 4 0 5 3 7 1.&lt;/p&gt;
&lt;p&gt;Click the ForEach timespan, the Current panel shows the execution duration is 4750 milliseconds. Click ForAll, it shows 1314 milliseconds:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image012_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image012_thumb.gif&quot; alt=&quot;clip_image012&quot; title=&quot;clip_image012&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is about 27% of ForEach execution time, which is close to a quarter as expected. It cannot be exactly 25%, because on the device, there are other running processes and threads using CPU, the parallel query also has extra work to manage multithreading, which is covered later in this chapter.&lt;/p&gt;
&lt;p&gt;In the last tab Cores, select the LINQ query threads (main thread and other 3 worker thread), and 6760. It shows how the workload is distributed in the 4 cores:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image014_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image014_thumb.gif&quot; alt=&quot;clip_image014&quot; title=&quot;clip_image014&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Above LINQ visualization code looks noisy, because it mixes the LINQ query code and the visualization code. Following the Single Responsibility Principle, the visualization can be encapsulated for IEnumerable&amp;lt;T&amp;gt; and ParallelQuery&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal const string ParallelSpan = &quot;Parallel&quot;;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal const string SequentialSpan = &quot;Sequential&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Visualize&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, Action&amp;lt;TSource&amp;gt;&amp;gt; query,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;TSource&amp;gt; iteratee, string span = SequentialSpan, int category = -1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(category, span))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iteratee(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Visualize&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;ParallelQuery&amp;lt;TSource&amp;gt;, Action&amp;lt;TSource&amp;gt;&amp;gt; query,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;TSource&amp;gt; iteratee, string span = ParallelSpan, int category = -2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Markers.EnterSpan(category, span))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iteratee(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the additional CPU computing workload can also be defined as a function:&lt;/p&gt;
&lt;p&gt;internal static int ComputingWorkload(int value = 0, int baseIteration = 10_000_000)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; baseIteration * (value + 1); i++) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When it is called as ComputingWorkload() or ComputingWorkload(0), it runs 10 million iterations and output 0; when it is called as ComputingWorkload(1), it runs 20 million iterations and output 1; and so on.&lt;/p&gt;
&lt;p&gt;Now the LINQ queries can be visualized in a much cleaner way:&lt;/p&gt;
&lt;p&gt;internal static void VisualizeForEachForAll()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerableEx.ForEach,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; (value + ComputingWorkload()).WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.ForAll,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; (value + ComputingWorkload()).WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Visualizing chaining queries&lt;/h3&gt;
&lt;p&gt;Besides visualizing query execution with ForEach and ForAll, the following Visualize overloads can be defined to visualize sequential and parallel queries and render their iteratee function execution as timespans, like Select’s selector, Where’s predicate, etc.:&lt;/p&gt;
&lt;p&gt;internal static TResult Visualize&amp;lt;TSource, TMiddle, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, Func&amp;lt;TSource, TMiddle&amp;gt;, TResult&amp;gt; query,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TMiddle&amp;gt; iteratee,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, string&amp;gt; spanFactory = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string span = SequentialSpan)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;spanFactory = spanFactory ?? (value =&amp;gt; value.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return query(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Thread.CurrentThread.ManagedThreadId, spanFactory(value)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return iteratee(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static TResult Visualize&amp;lt;TSource, TMiddle, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this ParallelQuery&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;ParallelQuery&amp;lt;TSource&amp;gt;, Func&amp;lt;TSource, TMiddle&amp;gt;, TResult&amp;gt; query,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TMiddle&amp;gt; iteratee,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, string&amp;gt; spanFactory = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string span = ParallelSpan)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;spanFactory = spanFactory ?? (value =&amp;gt; value.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return query(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (markerSeries.EnterSpan(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Thread.CurrentThread.ManagedThreadId, spanFactory(value)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return iteratee(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Take a simple Where and Select query chaining as example,&lt;/p&gt;
&lt;p&gt;internal static void VisualizeWhereSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Where,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; ComputingWorkload() &amp;gt;= 0, // Where&apos;s predicate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; $&quot;{nameof(Enumerable.Where)} {value}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Select,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; ComputingWorkload(), // Select&apos;s selector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; $&quot;{nameof(Enumerable.Select)} {value}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, Environment.ProcessorCount * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Where,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; ComputingWorkload() &amp;gt;= 0, // Where&apos;s predicate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; $&quot;{nameof(ParallelEnumerable.Where)} {value}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Visualize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelEnumerable.Select,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; ComputingWorkload(), // Select&apos;s selector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; $&quot;{nameof(ParallelEnumerable.Select)} {value}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The sequential and parallel queries are visualized as:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image016_2.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1_B83B/clip_image016_thumb.gif&quot; alt=&quot;clip_image016&quot; title=&quot;clip_image016&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (3) Manipulating XML</title><link>https://dixin.github.io/posts/linq-to-xml-3-manipulating-xml/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-3-manipulating-xml/</guid><description>Besides creating and querying XML, LINQ to XML also provides APIs for other XML manipulations, including cloning, deleting, replacing, and updating XML structures:</description><pubDate>Tue, 27 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Besides creating and querying XML, LINQ to XML also provides APIs for other XML manipulations, including cloning, deleting, replacing, and updating XML structures:&lt;/p&gt;
&lt;p&gt;· Clone&lt;/p&gt;
&lt;p&gt;o Explicit Clone: constructors of XAttribute, XCData, XComment, XDeclaration, XDocument, XElement, XProcessingInstruction, XText&lt;/p&gt;
&lt;p&gt;· Add&lt;/p&gt;
&lt;p&gt;o Add annotations: XObject.AddAnnotation&lt;/p&gt;
&lt;p&gt;o Add children: XContainer.Add, XContainer.AddFirst, XStreamingElement.Add&lt;/p&gt;
&lt;p&gt;o Add siblings: XNode.AddAfterSelf, XNode.AddBeforeSelf&lt;/p&gt;
&lt;p&gt;· Delete&lt;/p&gt;
&lt;p&gt;o Delete annotations: XObject.RemoveAnnotations&lt;/p&gt;
&lt;p&gt;o Delete attributes: XElement.RemoveAttributes, XAttribute.Remove&lt;/p&gt;
&lt;p&gt;o Delete self: XNode.Remove&lt;/p&gt;
&lt;p&gt;o Delete children: XContainer.RemoveNodes, XElement.RemoveAll&lt;/p&gt;
&lt;p&gt;· Replace&lt;/p&gt;
&lt;p&gt;o Replace attributes: XElement.ReplaceAttributes&lt;/p&gt;
&lt;p&gt;o Replace self: XNode.ReplaceWith&lt;/p&gt;
&lt;p&gt;o Replace children: XContainer.ReplaceNodes, XElement.ReplaceAll&lt;/p&gt;
&lt;p&gt;· Update&lt;/p&gt;
&lt;p&gt;o Update attribute: XAttribute.Value&lt;/p&gt;
&lt;p&gt;o Update comment: XComment.Value&lt;/p&gt;
&lt;p&gt;o Update declaration: XDeclaration.Encoding, XDeclaration.Standalone, XDeclaration.Version&lt;/p&gt;
&lt;p&gt;o Update document: XDocument.XDeclaration, XDocumentType.InternalSubset, XDocumentType.Name, XDocumentType.PublicId, XDocumentType.SystemId&lt;/p&gt;
&lt;p&gt;o Update element: XElement.Name, XElement.Value, XElement.SetAttributeValue, XElement.SetElementValue, XElement.SetValue&lt;/p&gt;
&lt;p&gt;.NET Framework also provides APIs for validating and transforming XML:&lt;/p&gt;
&lt;p&gt;· Validate with XSD&lt;/p&gt;
&lt;p&gt;o Query schema: XAttribute.GetSchemaInfo*, XElement.GetSchemaInfo*&lt;/p&gt;
&lt;p&gt;o Validate schema: XAttribute.Validate*, XDocument.Validate*, XElement.Validate*&lt;/p&gt;
&lt;p&gt;· Transform with XSL: XslCompiledTransform.Transform&lt;/p&gt;
&lt;p&gt;The APIs with * are extension methods provided by System.Xml.Schema.Extensions.&lt;/p&gt;
&lt;h3&gt;Clone&lt;/h3&gt;
&lt;p&gt;Most structures can be cloned by calling their constructors with the source instance:&lt;/p&gt;
&lt;p&gt;internal static void ExplicitClone()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement sourceElement = XElement.Parse(&quot;&amp;lt;element /&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement clonedElement = new XElement(sourceElement);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XText sourceText = new XText(&quot;text&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XText clonedText = new XText(sourceText);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument sourceDocument = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument clonedDocument = new XDocument(sourceDocument);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(sourceDocument, clonedDocument).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.Equals(sourceDocument, clonedDocument).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EqualityComparer&amp;lt;XDocument&amp;gt;.Default.Equals(sourceDocument, clonedDocument).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceDocument.Equals(clonedDocument).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(sourceDocument == clonedDocument).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.DeepEquals(sourceDocument, clonedDocument).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.EqualityComparer.Equals(sourceDocument, clonedDocument).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If an XObject instance is in an XML tree, when it is added to a different XML tree, it is cloned, and the new instance is actually added to the target. The exceptions are XName and XNamespace, which are cached at runtime. For example:&lt;/p&gt;
&lt;p&gt;internal static void ImplicitClone()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement child = XElement.Parse(&quot;&amp;lt;child /&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName parentName = &quot;parent&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement parent1 = new XElement(parentName, child); // Attach.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(child, parent1.Elements().Single()).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(parentName, parent1.Name).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement parent2 = new XElement(parentName, child); // Clone and attach.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(child, parent2.Elements().Single()).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(parentName, parent2.Name).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.Add(element); // Clone and attach.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(element, element.Elements().Single()).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Adding, deleting, replacing, updating, and events&lt;/h3&gt;
&lt;p&gt;Most of APIs to add/replace/delete/update XML structures are very intuitive. And when changing a XObject instance, XObject.Changing and XObject.Changed events are fired before and after the change. For example:&lt;/p&gt;
&lt;p&gt;internal static void Manipulate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement child = new XElement(&quot;child&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Changing += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {child}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Changed += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {child}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement parent = new XElement(&quot;parent&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Changing += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Changed += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Value = &quot;value1&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XText value1) =&amp;gt; &amp;lt;child /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XText value1) =&amp;gt;&amp;lt; child&amp;gt;value1&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Value = &quot;value2&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove: (XText value1) =&amp;gt;&amp;lt; child&amp;gt;value1&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: (XText value1) =&amp;gt;&amp;lt; child /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XText value2) =&amp;gt;&amp;lt; child /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XText value2) =&amp;gt;&amp;lt; child&amp;gt;value2&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Value = string.Empty;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove: (XText value2) =&amp;gt;&amp;lt; child&amp;gt;value2&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: (XText value2) =&amp;gt;&amp;lt; child /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Value: (XElement &amp;lt;child /&amp;gt;) =&amp;gt; &amp;lt;child /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Value: (XElement&amp;lt; child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Add(child);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XElement &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt;&amp;lt; parent /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XElement&amp;lt; child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Add(new XAttribute(&quot;attribute&quot;, &quot;value&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.AddBeforeSelf(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XText 0) =&amp;gt;&amp;lt; parent&amp;gt;0&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.ReplaceAll(new XText(&quot;Text.&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;0&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: (XText 0) =&amp;gt;&amp;lt; parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove: (XElement &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: (XElement &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XText Text.) =&amp;gt;&amp;lt; parent /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XText Text.) =&amp;gt;&amp;lt; parent&amp;gt;Text.&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Name = &quot;name&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Name: (XElement&amp;lt; parent&amp;gt;Text.&amp;lt;/parent&amp;gt;) =&amp;gt; &amp;lt;parent&amp;gt;Text.&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Name: (XElement&amp;lt; name&amp;gt;Text.&amp;lt;/name&amp;gt;) =&amp;gt; &amp;lt;name&amp;gt;Text.&amp;lt;/name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement clonedChild = new XElement(child);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;clonedChild.SetValue(DateTime.Now); // No tracing.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There are many APIs to manipulate XML, but there are only 4 kinds of Changing/Changed events: add object, deleting object, update object value, update element/attribute name. For example, as shown above, the APIs to replace objects are shortcuts of deleting old objects and adding new objects. When setting a string as an element’s value, the element first removes its children if there is any, then add the string as a child text node, if the string is not empty string. Also, an object’s events propagate/bubble up to the ancestors, and children and siblings are not impacted. When an object is cloned, the new object’s events is not observed by the original event handlers.&lt;/p&gt;
&lt;p&gt;XElement.SetAttributeValue and XElement.SetElementValue are different from other APIs. They can&lt;/p&gt;
&lt;p&gt;· add a new attribute/child element if it does not exist&lt;/p&gt;
&lt;p&gt;· update the attribute/child element value if it exists:&lt;/p&gt;
&lt;p&gt;· remove the attribute/child element if it exists and the provided value to null.&lt;/p&gt;
&lt;p&gt;internal static void SetAttributeValue()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.Changing += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {element}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.Changed += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {element}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.SetAttributeValue(&quot;attribute&quot;, &quot;value1&quot;); // Equivalent to: child1.Add(new XAttribute(&quot;attribute&quot;, &quot;value1&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value1&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.SetAttributeValue(&quot;attribute&quot;, &quot;value2&quot;); // Equivalent to: child1.Attribute(&quot;attribute&quot;).Value = &quot;value2&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Value: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value1&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Value: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value2&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.SetAttributeValue(&quot;attribute&quot;, null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value2&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void SetElementValue()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement parent = new XElement(&quot;parent&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Changing += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Before {e.ObjectChange}: {sender} =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.Changed += (sender, e) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;After {e.ObjectChange}: {sender} =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.SetElementValue(&quot;child&quot;, string.Empty); // Add child element.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.SetElementValue(&quot;child&quot;, &quot;value&quot;); // Update child element.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Value:&amp;lt; child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Value: &amp;lt;child /&amp;gt; =&amp;gt;&amp;lt; parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Add: value =&amp;gt;&amp;lt; parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Add: value =&amp;gt; &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parent.SetElementValue(&quot;child&quot;, null); // Remove child element.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Before Remove:&amp;lt; child&amp;gt;value&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// After Remove: &amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Annotation&lt;/h3&gt;
&lt;p&gt;Annotation is not a part of the XML. It is a separate arbitrary data in the memory, and associated with a XObject instance in the memory. The annotation APIs provided by XObject allows adding/querying/deleting any .NET data. Apparently, when cloning or serializing XObject, annotation is ignored on the new XObject and the generated string.&lt;/p&gt;
&lt;p&gt;internal static void Annotation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.AddAnnotation(new Uri(&quot;https://microsoft.com&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri annotation = element.Annotation&amp;lt;Uri&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;annotation.WriteLine(); // https://microsoft.com
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.WriteLine(); // &amp;lt;element /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement clone = new XElement(element); // element is cloned.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;clone.Annotations&amp;lt;Uri&amp;gt;().Any().WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.RemoveAnnotations&amp;lt;Uri&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(element.Annotation&amp;lt;Uri&amp;gt;() == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Validating XML with XSD&lt;/h3&gt;
&lt;p&gt;XSD (XML Schema Definition) is the metadata of XML tree, including XML&apos;s elements, attributes, constrains rules, etc. System.Xml.Schema.Extensions provides a few APIs to validate XML with provided schema. To obtain a schema, one option is to infer it from existing XML:&lt;/p&gt;
&lt;p&gt;public static XmlSchemaSet InferSchema(this XNode source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlSchemaInference schemaInference = new XmlSchemaInference();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlReader reader = source.CreateReader())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return schemaInference.InferSchema(reader);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The returned XmlSchemaSet instance contains s sequence of XmlSchema instances, one for each namespace in the source XML. XmlSchema can be converted to XDocument with the help of XmlWriter:&lt;/p&gt;
&lt;p&gt;public static XDocument ToXDocument(this XmlSchema source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document = new XDocument();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlWriter writer = document.CreateWriter())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Write(writer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return document;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Still take an RSS feed as example, the following code outputs the RSS feed’s schema:&lt;/p&gt;
&lt;p&gt;internal static void InferSchemas()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument aspNetRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlSchemaSet schemaSet = aspNetRss.InferSchema();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;schemaSet.Schemas().Cast&amp;lt;XmlSchema&amp;gt;().WriteLines(schema =&amp;gt; schema.ToXDocument().ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The printed schema is:&lt;/p&gt;
&lt;p&gt;&amp;lt;xs:schema attributeFormDefault=&quot;unqualified&quot; elementFormDefault=&quot;qualified&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;rss&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;channel&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;title&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;link&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;description&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element maxOccurs=&quot;unbounded&quot; name=&quot;item&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;title&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;link&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;description&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;pubDate&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element name=&quot;guid&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:simpleContent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:extension base=&quot;xs:string&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:attribute name=&quot;isPermaLink&quot; type=&quot;xs:boolean&quot; use=&quot;required&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:extension&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:simpleContent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:element maxOccurs=&quot;unbounded&quot; name=&quot;category&quot; type=&quot;xs:string&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:sequence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:attribute name=&quot;version&quot; type=&quot;xs:decimal&quot; use=&quot;required&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:complexType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xs:element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/xs:schema&amp;gt;&lt;/p&gt;
&lt;p&gt;The data is all gone, and there is only structural description for that RSS feed. Save it to a .xsd file, then it can be visualized in Visual Studio’s XML Schema Explorer:&lt;/p&gt;
&lt;p&gt;Now, this RSS feed’s schema, represented by XmlSchemaSet, can be used to validate XML. The following example calls the Validate extension methods for XDocument to validate another RSS feed from Flickr. As demonstrated before, Flickr RSS has more elements. Apparently the validation fails:&lt;/p&gt;
&lt;p&gt;internal static void Validate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlSchemaSet schemaSet = aspNetRss.InferSchema();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;flickrRss.Validate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;schemaSet,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(sender, args) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{args.Severity}: ({sender.GetType().Name}) =&amp;gt; {args.Message}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Error: (XElement) =&amp;gt; The element &apos;channel&apos; has invalid child element &apos;pubDate&apos;. List of possible elements expected: &apos;item&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;args.Exception?.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// XmlSchemaValidationException: The element &apos;channel&apos; has invalid child element &apos;pubDate&apos;. List of possible elements expected: &apos;item&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Validate has another overload accepting a bool parameter addSchemaInfo. When it is called with true for addSchemaInfo, if an element or attribute is validated, the validation details are saved in an IXmlSchemaInfo instance, and associated with this element or attribute as an annotation. Then, the GetSchemaInfo method can be called on each element or attribute, to query that IXmlSchemaInfo annotation, if available. IXmlSchemaInfo can have a lot of information, including a Validity property, intuitively indicating the validation status:&lt;/p&gt;
&lt;p&gt;internal static void GetSchemaInfo()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlSchemaSet schemaSet = aspNetRss.InferSchema();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;flickrRss.Validate(schemaSet, (sender, args) =&amp;gt; { }, addSchemaInfo: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;flickrRss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Root
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.DescendantsAndSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(element =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{element.XPath()} - {element.GetSchemaInfo()?.Validity}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.Attributes().WriteLines(attribute =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{attribute.XPath()} - {attribute.GetSchemaInfo()?.Validity.ToString() ?? &quot;null&quot;}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss - Invalid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/@version - Valid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/@xmlns:media - null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/@xmlns:dc - null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/@xmlns:creativeCommons - null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/@xmlns:flickr - null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel - Invalid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel/title - Valid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel/link - Valid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel/description - Valid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel/pubDate - Invalid
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// /rss/channel/lastBuildDate - NotKnown
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Transforming XML with XSL&lt;/h3&gt;
&lt;p&gt;XSL (Extensible Stylesheet Language) can transform a XML tree to another. XSL transformation can be done with the System.Xml.Xsl.XslCompiledTransform type:&lt;/p&gt;
&lt;p&gt;public static XDocument XslTransform(this XNode source, XNode xsl)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument result = new XDocument();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlReader sourceReader = source.CreateReader())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlReader xslReader = xsl.CreateReader())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlWriter resultWriter = result.CreateWriter())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XslCompiledTransform transform = new XslCompiledTransform();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;transform.Load(xslReader);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;transform.Transform(sourceReader, resultWriter);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example transforms RSS to HTML, the most recent 5 items in RSS are mapped to HTML hyperlinks in an unordered list:&lt;/p&gt;
&lt;p&gt;internal static void XslTransform()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument xsl = XDocument.Parse(@&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xsl:stylesheet version=&apos;1.0&apos; xmlns:xsl=&apos;http://www.w3.org/1999/XSL/Transform&apos;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xsl:template match=&apos;/rss/channel&apos;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xsl:for-each select=&apos;item[position() &amp;amp;lt;= 5]&apos;&amp;gt;&amp;lt;!--Position is less than or equal to 5.--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xsl:attribute name=&apos;href&apos;&amp;gt;&amp;lt;xsl:value-of select=&apos;link&apos; /&amp;gt;&amp;lt;/xsl:attribute&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xsl:value-of select=&apos;title&apos; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xsl:for-each&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xsl:template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/xsl:stylesheet&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument html = rss.XslTransform(xsl);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;html.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/c-6-0-exception-filter-and-when-keyword&quot;&amp;gt;C# 6.0 Exception Filter and when Keyword&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/use-fiddler-with-node-js&quot;&amp;gt;Use Fiddler with Node.js&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/diskpart-problem-cannot-select-partition&quot;&amp;gt;DiskPart Problem: Cannot Select Partition&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/configure-git-for-visual-studio-2015&quot;&amp;gt;Configure Git for Visual Studio 2015&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/query-operating-system-processes-in-c&quot;&amp;gt;Query Operating System Processes in C#&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above transformation can also be done with LINQ to Objects/XML query:&lt;/p&gt;
&lt;p&gt;internal static void Transform()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument html = rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;rss&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;channel&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Elements(&quot;item&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(item =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string link = (string)item.Element(&quot;link&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string title = (string)item.Element(&quot;title&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new XElement(&quot;li&quot;, new XElement(&quot;a&quot;, new XAttribute(&quot;href&quot;, link), title));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to: return XElement.Parse($&quot;&amp;lt;li&amp;gt;&amp;lt;a href=&apos;{link}&apos;&amp;gt;{title}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(new XElement(&quot;ul&quot;), (ul, li) =&amp;gt; { ul.Add(li); return ul; }, ul =&amp;gt; new XDocument(ul));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;html.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses how to use LINQ to XML APIs to work with XML data. LINQ to XML provides types to model XML following a declarative paradigm. After loading XML into memory as objects, they can be queried by LINQ to Objects. LINQ to XML provides additional queries for XML, including DOM navigation, ordering, comparison, etc. LINQ to XML also provide APIs for XPath, as well as XML manipulation, annotation, validation, and transformation, etc.&lt;/p&gt;
</content:encoded></item><item><title>Installing Android 9 Pie with Microsoft apps on Nexus 7</title><link>https://dixin.github.io/posts/installing-android-9-pie-with-microsoft-apps-on-nexus-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/installing-android-9-pie-with-microsoft-apps-on-nexus-7/</guid><description>Years ago I blogged about  on my old Nexus 7 tablet. Now Android 9 is there. This post shows how to install latest Android 9 w</description><pubDate>Tue, 20 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Years ago I blogged about &lt;a href=&quot;/posts/installing-android-6-marshmallow-on-nexus-7&quot;&gt;installing Android 6&lt;/a&gt; on my old Nexus 7 tablet. Now Android 9 is there. This post shows how to install latest Android 9 with latest Microsoft apps.&lt;/p&gt;
&lt;h2&gt;Increase the system partition size&lt;/h2&gt;
&lt;p&gt;In old android devices like Nexus 7, the system partition is very small, about 800M. After installing the Android 9 ROM, the Google app store cannot be installed. Even the smallest Open GApps version (pico) fails to install with a 70 error: insufficient space on system partition. So the first step is to increase the system partition size.&lt;/p&gt;
&lt;p&gt;TWRP has a resize partition function. However, it does not work for Nexus 7 tablet, since Nexus 7’s system partition is located in the middle of many partitions. So the way is to abandon the original system partition, delete the last partition, and create a new large system partition at the end of the storage space.&lt;/p&gt;
&lt;p&gt;First, follow the &lt;a href=&quot;https://www.xda-developers.com/install-adb-windows-macos-linux/&quot;&gt;instructions&lt;/a&gt; to download and unzip the ADB tools. For windows, it can be downloaded from &lt;a href=&quot;https://dl.google.com/android/repository/platform-tools-latest-windows.zip&quot;&gt;https://dl.google.com/android/repository/platform-tools-latest-windows.zip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then download and unzip the parted tool from &lt;a href=&quot;http://iwf1.com/iwf-repo/parted.rar&quot;&gt;http://iwf1.com/iwf-repo/parted.rar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, follow the &lt;a href=&quot;https://forum.xda-developers.com/nexus-7-2013/general/guide-repartition-nexus72013-to-t3599907&quot;&gt;instructions&lt;/a&gt; to backup the original partition table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb push parted /
adb shell
~ # chmod +x parted
~ # /parted /dev/block/mmcblk0
(parted): unit b
(parted): p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now delete rename to original system partition to something else, delete the last data partition, and recreate new system partition and new data partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(parted): name 22 unused1
(parted): rm 30
(parted): mkpart primary 2415919104B  5570068479B
(parted): mkpart primary 5637144576B 31272713727B
(parted): name 30 system
(parted): name 31 userdata
(parted): quit
~ # mke2fs -b 4096 -T ext4 /dev/block/mmcblk0p30
~ # mke2fs -b 4096 -T ext4 /dev/block/mmcblk0p31
~ # /parted /dev/block/mmcblk0 p
~ # exit
adb reboot recovery
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After reboot, it is ready to install Android OS and Google app store.&lt;/p&gt;
&lt;h2&gt;Install Android 9 and Google app store&lt;/h2&gt;
&lt;p&gt;First, download the latest Android 9 pie ROM, for example, AOSP r46 ROM: &lt;a href=&quot;https://androidfilehost.com/?fid=6006931924117931258&quot;&gt;https://androidfilehost.com/?fid=6006931924117931258&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then download the Open GApps, for example, the stock version can work with the enlarged system partition: &lt;a href=&quot;https://opengapps.org/&quot;&gt;https://opengapps.org/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now transfer these 2 zip file to the device, and use TWRP to install them both.&lt;/p&gt;
&lt;p&gt;After reboot, the device will have Android OS and Google app store.&lt;/p&gt;
&lt;h2&gt;Fix the Pixel Launcher crash&lt;/h2&gt;
&lt;p&gt;The Google’s Pixel launcher keeps crashing and many users report the same issue. To fix this, &lt;a href=&quot;https://android.stackexchange.com/questions/212860/pixel-launcher-crashing-due-to-missing-status-bar-and-manage-activity-stacks-per/212861#212861&quot;&gt;the /data/system/packages.xml file need to be edited&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, use adb to pull the file from device, and edit it with text editor, for example, Visual Studio Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb pull /data/system/packages.xml
code packages.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find the com.google.android.apps.nexuslauncher segment, add 2 permissions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;package name=&quot;com.google.android.apps.nexuslauncher&quot; codePath=&quot;/system/priv-app/NexusLauncherPrebuilt&quot; nativeLibraryPath=&quot;/system/priv-app/NexusLauncherPrebuilt/lib&quot; publicFlags=&quot;877379141&quot; privateFlags=&quot;8&quot; ft=&quot;16cabc2c4a0&quot; it=&quot;16cabc2c4a0&quot; ut=&quot;16cabc2c4a0&quot; version=&quot;604&quot; userId=&quot;10019&quot; isOrphaned=&quot;true&quot;&amp;gt;
    &amp;lt;sigs count=&quot;1&quot; schemeVersion=&quot;1&quot;&amp;gt;
        &amp;lt;cert index=&quot;19&quot; key=&quot;308203c7308202afa003020102020900ed6adca108384104300d06092a864886f70d0101050500307a310b30090603550406130255533113301106035504080c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e205669657731143012060355040a0c0b476f6f676c6520496e632e3110300e060355040b0c07416e64726f69643116301406035504030c0d6e657875736c61756e63686572301e170d3136303530323231313933325a170d3433303931383231313933325a307a310b30090603550406130255533113301106035504080c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e205669657731143012060355040a0c0b476f6f676c6520496e632e3110300e060355040b0c07416e64726f69643116301406035504030c0d6e657875736c61756e6368657230820122300d06092a864886f70d01010105000382010f003082010a0282010100a87aac2fe945313ae9afcc9815d01fa7ede40eaf5a8f280ab4da9c84346b2ca0b2da8d9532d24cb2ce950f6a627273487b7bd9c5601339823842c511926f7e177dc91d919de2e3f6750f9b03fe04f16f008724bbc90fc5e7f2f85e712d523edb93b7903fb007f11756d895d14355d0fa07c05a5773b650b7e6d50e50359884994224ed38591203898840c6b1df6a3604241e24ef9658729e25b6ada3c772a3bbb3d7d832115a2c1901b33b737a5d2a40da9d68c0ecd5e1f9f11d75437286368eab8cd527fe1465aad1da6a0d436767b8b4b53f83e10eac533f48e125b6824899721cabd80cd9749388bd096824e53fce0bcf2c367c6ab9894fa7b135a0b627510203010001a350304e301d0603551d0e041604145055852c1911bb9bd0ba4db3d6a5dfb9acbfa07b301f0603551d230418301680145055852c1911bb9bd0ba4db3d6a5dfb9acbfa07b300c0603551d13040530030101ff300d06092a864886f70d010105050003820101008e190c51ea11edba56bfddfd11ea6d13e729d8ba2a06bd8a346a5d7b7080694003bfe6e284a688f230657d9955854c4dff3fb9d07655911053468ee322314e13e4e098d46d218098d6a316bc0751f1c5b7a7f415358b008cc81ad8b43f05251eb1be5a375c44f8b9c9da46dcfb47f52a7d02dd49e5fe197e257d4946dfc0993f61fe78b4be47c9c6cba1cab164df8d513f41fb79e85f69df1a500e4f0bea4e2f912720765a0a05270f9565e29b46e42f4de5956875f93b7293e9f45ea397c5821738fc2b8bfbf48eb2794dcb7e7997f4a4952fba63605952bf50e8066048afef7fafa9f13ceb122c10759ffbb99d729d671f7c301482fd530cd48a2a9e878f86&quot; /&amp;gt;
    &amp;lt;/sigs&amp;gt;
    &amp;lt;perms&amp;gt;
        &amp;lt;item name=&quot;com.google.android.apps.nexuslauncher.permission.READ_SETTINGS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;com.google.android.providers.gsf.permission.READ_GSERVICES&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.BLUETOOTH&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.BLUETOOTH_ADMIN&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.BIND_APPWIDGET&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.PACKAGE_USAGE_STATS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.WRITE_SECURE_SETTINGS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.SET_WALLPAPER&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.REQUEST_DELETE_PACKAGES&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.SET_WALLPAPER_HINTS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;com.google.android.apps.nexuslauncher.permission.WRITE_SETTINGS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;com.google.android.apps.nexuslauncher.permission.QSB&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.VIEW_INSTANT_APPS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;com.google.android.launcher.permission.READ_SETTINGS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.STATUS_BAR&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
        &amp;lt;item name=&quot;android.permission.MANAGE_ACTIVITY_STACKS&quot; granted=&quot;true&quot; flags=&quot;0&quot; /&amp;gt;
    &amp;lt;/perms&amp;gt;
    &amp;lt;proper-signing-keyset identifier=&quot;6&quot; /&amp;gt;
&amp;lt;/package&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now push the edited file back to the device:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb push packages.xml /data/system/packages.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After reboot, the Pixel Launcher can work.&lt;/p&gt;
&lt;h2&gt;Install Microsoft Launcher and apps&lt;/h2&gt;
&lt;p&gt;Now launch Google app store, install Microsoft Launcher: &lt;a href=&quot;https://www.microsoft.com/en-us/launcher&quot;&gt;https://www.microsoft.com/en-us/launcher&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once it is installed, it places a folder on the desktop, with shortcuts to install the popular Microsoft apps, like OneNote, Skype, Outlook, Teams, etc. Just tab the icons to install them.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Installing-Android-9-Pie-on-Nexus-7_F613/Screenshot_20190819-183721_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Installing-Android-9-Pie-on-Nexus-7_F613/Screenshot_20190819-183721_thumb.png&quot; alt=&quot;Screenshot_20190819-183721&quot; title=&quot;Screenshot_20190819-183721&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (2) Query Methods (Operators)</title><link>https://dixin.github.io/posts/linq-to-xml-2-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-2-query-methods/</guid><description>As fore mentioned, LINQ to XML is just a specialized LINQ to Objects, so all the LINQ to Objects queries can be used in LINQ to XML queries. LINQ to XML provides many additional functions and queries</description><pubDate>Fri, 16 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ to XML is just a specialized LINQ to Objects, so all the LINQ to Objects queries can be used in LINQ to XML queries. LINQ to XML provides many additional functions and queries for XML tree navigation, ordering, XPath querying, etc. The following list shows these functions and their return types:&lt;/p&gt;
&lt;p&gt;· Navigation queries&lt;/p&gt;
&lt;p&gt;o Query direct parent element&lt;/p&gt;
&lt;p&gt;§ XObject.Parent -&amp;gt; XElement&lt;/p&gt;
&lt;p&gt;o Query all ancestor elements:&lt;/p&gt;
&lt;p&gt;§ XNode.Ancestors -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ XElement.AncestorsAndSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;T&amp;gt;.Ancestors* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XNode&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;XElement&amp;gt;.AncestorsAndSelf* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query direct child elements&lt;/p&gt;
&lt;p&gt;§ XDocument.Root-&amp;gt; XElement&lt;/p&gt;
&lt;p&gt;§ XContainer.Element -&amp;gt; XElement&lt;/p&gt;
&lt;p&gt;§ XContainer.Elements -&amp;gt;IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;T&amp;gt;.Elements* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;p&gt;o Query direct child nodes&lt;/p&gt;
&lt;p&gt;§ XContainer.FirstNode -&amp;gt; XNode&lt;/p&gt;
&lt;p&gt;§ XContainer.LastNode -&amp;gt; XNode&lt;/p&gt;
&lt;p&gt;§ XContainer.Nodes -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;T&amp;gt;.Nodes* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;p&gt;o Query all descendant elements&lt;/p&gt;
&lt;p&gt;§ XContainer.Descendants -&amp;gt;IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ XElement.DescendantsAndSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;T&amp;gt;.Descendants* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;XElement&amp;gt;.DescendantsAndSelf* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query all descendant nodes&lt;/p&gt;
&lt;p&gt;§ XContainer.DescendantNodes -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;§ XElement.DescendantNodesAndSelf -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;T&amp;gt;.DescendantNodes* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;XElement&amp;gt;.DescendantNodesAndSelf* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query sibling elements&lt;/p&gt;
&lt;p&gt;§ XNode.ElementsAfterSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ XNode.ElementsBeforeSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query sibling nodes&lt;/p&gt;
&lt;p&gt;§ XNode.PreviousNode -&amp;gt; XNode&lt;/p&gt;
&lt;p&gt;§ XNode.NextNode -&amp;gt; XNode&lt;/p&gt;
&lt;p&gt;§ XNode.NodesBeforeSelf -&amp;gt;IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;§ XNode.NodesAfterSelf -&amp;gt;IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query attributes&lt;/p&gt;
&lt;p&gt;§ XAttribute.PreviousAttribute –&amp;gt; XAttribute&lt;/p&gt;
&lt;p&gt;§ XAttribute.NextAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;p&gt;§ XElement.FirstAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;p&gt;§ XElement.LastAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;p&gt;§ XElement.Attribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;p&gt;§ XElement.Attributes -&amp;gt;IEnumerable&amp;lt;XAttribute&amp;gt;&lt;/p&gt;
&lt;p&gt;§ IEnumerable&amp;lt;XElement&amp;gt;.Attributes* -&amp;gt; IEnumerable&amp;lt;XAttribute&amp;gt;&lt;/p&gt;
&lt;p&gt;o Query document&lt;/p&gt;
&lt;p&gt;§ XObject.Document –&amp;gt; XDocument&lt;/p&gt;
&lt;p&gt;o Query annotations&lt;/p&gt;
&lt;p&gt;§ XObject.Annotation&amp;lt;T&amp;gt; –&amp;gt; T, where T : class&lt;/p&gt;
&lt;p&gt;§ XObject.Annotations –&amp;gt;IEnumerable&amp;lt;object&amp;gt;&lt;/p&gt;
&lt;p&gt;· Ordering queries&lt;/p&gt;
&lt;p&gt;o XNode.CompareDocumentOrder -&amp;gt; int&lt;/p&gt;
&lt;p&gt;o XNode.IsAfter -&amp;gt; bool&lt;/p&gt;
&lt;p&gt;o XNode.IsBefore -&amp;gt; bool&lt;/p&gt;
&lt;p&gt;o XNodeDocumentOrderComparer.Compare -&amp;gt; int&lt;/p&gt;
&lt;p&gt;o IEnumerable&amp;lt;T&amp;gt;.InDocumentOrder* -&amp;gt; IEnumerable&amp;lt;T&amp;gt;, where T : XNode&lt;/p&gt;
&lt;p&gt;· Comparison queries&lt;/p&gt;
&lt;p&gt;o XNode.DocumentOrderComparer –&amp;gt; XNodeDocumentOrderComparer&lt;/p&gt;
&lt;p&gt;o XNodeDocumentOrderComparer.Compare –&amp;gt; int&lt;/p&gt;
&lt;p&gt;o XNode.EqualityComparer –&amp;gt; XNodeEqualityComparer&lt;/p&gt;
&lt;p&gt;o XNodeEqualityComparer.Equals –&amp;gt; bool&lt;/p&gt;
&lt;p&gt;· XPath queries&lt;/p&gt;
&lt;p&gt;o XNode.CreateNavigator** –&amp;gt; XPathNavigator&lt;/p&gt;
&lt;p&gt;o XNode.XPathSelectElement** –&amp;gt; XElement&lt;/p&gt;
&lt;p&gt;o XNode.XPathSelectElements** –&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o XNode.XPathEvaluate** –&amp;gt; object&lt;/p&gt;
&lt;p&gt;The functions with * are extension methods provided in static type System.Xml.Linq.Extensions. The functions with ** are extension methods provided in static type System.Xml.XPath.Extensions. The other unmarked methods are instance methods or properties.&lt;/p&gt;
&lt;h3&gt;Navigation&lt;/h3&gt;
&lt;p&gt;LINQ to XML provides rich APIs for navigation. And the queries with IEnumerable&amp;lt;XObject&amp;gt; output are also called axis methods or axes. The following example queries the parent element and ancestor element, where. ancestors are parent, parent’s parent, …, recursively:&lt;/p&gt;
&lt;p&gt;internal static void ParentAndAncestors()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document = new XDocument(new XElement(&quot;grandparent&quot;, new XElement(&quot;parent&quot;, element)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.Parent.Name.WriteLine(); // parent
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Ancestors()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(ancestor =&amp;gt; ancestor.Name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(); // parent grandparent
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AncestorsAndSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(selfOrAncestor =&amp;gt; selfOrAncestor.Name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(); // element parent grandparent
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(element.Ancestors().Last(), element.Document.Root).WriteLine(); // True.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice AncestorsAndSelf first yields self, then yields ancestors recursively. It could be more intuitive if named as SelfAndAncestors.&lt;/p&gt;
&lt;p&gt;The following example queries direct child elements. In RSS feed, each &amp;lt;item&amp;gt; can have 0, 1, or multiple tags. And these tags are &amp;lt;category&amp;gt; elements under each &amp;lt;item&amp;gt; element. The following code queries a given RSS feed to get the items with a permalink, then queries the top 5 tags used by these items:&lt;/p&gt;
&lt;p&gt;internal static void ChildElements()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;categories = rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Root // &amp;lt;rss&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;channel&quot;) // Single&amp;lt; channel&amp;gt; under &amp;lt;rss&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Elements(&quot;item&quot;) // All&amp;lt; item&amp;gt;s under single &amp;lt;channel&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(item =&amp;gt; (bool)item
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;guid&quot;) // Single &amp;lt;guid&amp;gt; under each &amp;lt;item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Attribute(&quot;isPermaLink&quot;)) // isPermaLink attribute of &amp;lt;guid&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Elements(&quot;category&quot;) // All &amp;lt;category&amp;gt;s under all &amp;lt;item&amp;gt;s.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: category =&amp;gt; (string)category, // String value of each &amp;lt;category&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: category =&amp;gt; category,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (key, group) =&amp;gt; new { Name = key, Count = group.Count() },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer: StringComparer.OrdinalIgnoreCase)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(category =&amp;gt; category.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string.Join(&quot; &quot;, categories).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to ancestors, descendants are children, children’s children, …, recursively:&lt;/p&gt;
&lt;p&gt;internal static void ChildrenAndDescendants()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement root = XElement.Parse(@&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;![CDATA[cdata]]&amp;gt;0&amp;lt;!--Comment--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/root&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;root.Elements()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(element =&amp;gt; element.ToString(SaveOptions.DisableFormatting));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt; element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;root.Nodes()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(node =&amp;gt; $&quot;{node.NodeType}: {node.ToString(SaveOptions.DisableFormatting)}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// CDATA: &amp;lt;![CDATA[cdata]]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Text: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Comment: &amp;lt;!--Comment--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Element: &amp;lt; element&amp;gt;1&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Element: &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;root.Descendants()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(element =&amp;gt; element.ToString(SaveOptions.DisableFormatting));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt; element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;root.DescendantNodes()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(node =&amp;gt; $&quot;{node.NodeType}: {node.ToString(SaveOptions.DisableFormatting)}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// CDATA: &amp;lt;![CDATA[cdata]]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Text: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Comment: &amp;lt;!--Comment--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Element: &amp;lt; element&amp;gt;1&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Text: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Element: &amp;lt; element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Text: 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Element: &amp;lt; element&amp;gt;3&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Text: 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Regarding all the X* types are reference types, when querying the same XML tree, multiple queries’ results from the same source tree can reference to the same instance:&lt;/p&gt;
&lt;p&gt;internal static void ResultReferences()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss1 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement[] items1 = rss1.Descendants(&quot;item&quot;).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement[] items2 = rss1.Element(&quot;rss&quot;).Element(&quot;channel&quot;).Elements(&quot;item&quot;).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(items1.First(), items2.First()).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;items1.SequenceEqual(items2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss2 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement[] items3 = rss2.Root.Descendants(&quot;item&quot;).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(items1.First(), items3.First()).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;items1.SequenceEqual(items3).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, LINQ to XML is just a specialized LINQ to Objects. For example, the implementation of XNode.Ancestors is equivalent to:&lt;/p&gt;
&lt;p&gt;namespace System.Xml.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class XNode : XObject
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerable&amp;lt;XElement&amp;gt; Ancestors()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (XElement parent = this.Parent; parent != null; parent = parent.Parent)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return parent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the implementation of the Extensions.Ancestors query is equivalent to:&lt;/p&gt;
&lt;p&gt;namespace System.Xml.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Extensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;XElement&amp;gt; Ancestors&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source) where T : XNode =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(node =&amp;gt; node != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(node =&amp;gt; node.Ancestors())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;Besides the LINQ to Objects ordering queries, additional ordering queries are provided by LINQ to XML. The InDocumentOrder query orders nodes by their positions in the XML tree, from top node down. For example, above Ancestors yields parent, parent’s parent, …, recursively. InDocumentOrder can reorder them from top down. As a result, the query result is reversed:&lt;/p&gt;
&lt;p&gt;internal static void DocumentOrder()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element1 = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element2 = new XElement(&quot;element&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document = new XDocument(new XElement(&quot;grandparent&quot;, new XElement(&quot;parent&quot;, element1, element2)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element1.IsBefore(element2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.DocumentOrderComparer.Compare(element1, element2).WriteLine(); // -1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement[] ancestors = element1.Ancestors().ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.CompareDocumentOrder(ancestors.First(), ancestors.Last()).WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ancestors
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.InDocumentOrder()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(ancestor =&amp;gt; ancestor.Name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(); // grandparent parent
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AncestorsAndSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Reverse()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SequenceEqual(element1.AncestorsAndSelf().InDocumentOrder())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, InDocumentOrder requires the source nodes sequence to be in the same XML tree. This is determined by looking up a common ancestor of the source nodes:&lt;/p&gt;
&lt;p&gt;internal static void CommonAncestor()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement root = XElement.Parse(@&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;element value=&apos;4&apos; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;element value=&apos;2&apos; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;element value=&apos;3&apos;&amp;gt;&amp;lt;element value=&apos;1&apos; /&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/root&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement[] elements = root
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Descendants(&quot;element&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(element =&amp;gt; (int)element.Attribute(&quot;value&quot;)).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elements.WriteLines(ancestorOrSelf =&amp;gt; ancestorOrSelf.ToString(SaveOptions.DisableFormatting));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;1&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;2&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;3&quot;&amp;gt;&amp;lt;element value=&quot;1&quot; /&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;4&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement[] { elements.First(), elements.Last() }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.InDocumentOrder()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(ancestorOrSelf =&amp;gt; ancestorOrSelf.ToString(SaveOptions.DisableFormatting));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;4&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element value=&quot;1&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement[] { elements.First(), elements.Last(), new XElement(&quot;element&quot;) }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.InDocumentOrder()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// InvalidOperationException: A common ancestor is missing.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice in the inline XML string, single quotes are used for attribute values, instead of double quotes. This is for readability of C# code, otherwise &quot;&quot; or \&quot; has to be used. According to the W3C XML spec, single quote is legal.&lt;/p&gt;
&lt;h3&gt;Comparison&lt;/h3&gt;
&lt;p&gt;LINQ to Objects provides many queries accepting IComparer&amp;lt;T&amp;gt; or IEqualityComparer&amp;lt;T&amp;gt; parameter. To use those queries with XML, LINQ to XML provides 2 built-in comparers:&lt;/p&gt;
&lt;p&gt;· XNodeDocumentOrderComparer, which implements IComparer&amp;lt;XNode&amp;gt;. Its Compare method simply calls XNode.CompareDocumentOrder. Its instance is provided by XNode.DocumentOrderComparer property.&lt;/p&gt;
&lt;p&gt;· XNodeEqualityComparer, which implements IEqualityComparer&amp;lt;XNode&amp;gt;. Its Equals method simply calls XNode.DeepEquals. Its instance is provided by XNode.EqualityComparer property.&lt;/p&gt;
&lt;p&gt;For example, above InDocumentOrder query simply calls OrderBy with XNodeDocumentOrderComparer. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static partial class Extensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;T&amp;gt; InDocumentOrder&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source) where T : XNode =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.OrderBy(node =&amp;gt; node, XNode.DocumentOrderComparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;More useful custom queries&lt;/h2&gt;
&lt;p&gt;With the knowledge of LINQ to Objects and LINQ to XML APIs, more useful queries can be implemented. For example, the following DescendantObjects queries an XObject source’s all descendant XObject instances:&lt;/p&gt;
&lt;p&gt;public static partial class XExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;XObject&amp;gt; DescendantObjects(this XObject source) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Empty&amp;lt;XObject&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source is XElement element
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? element.Attributes() // T is covariant in IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: Enumerable.Empty&amp;lt;XObject&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source is XContainer container
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? container
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.DescendantNodes()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(descendant =&amp;gt; EnumerableEx
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Return(descendant)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;descendant is XElement descendantElement
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? descendantElement.Attributes() // T is covariant in IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: Enumerable.Empty&amp;lt;XObject&amp;gt;()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: Enumerable.Empty&amp;lt;XObject&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, XObject can be either node or attribute. So, in the query, If the source is element, it yields the element’s attributes; if the source is XContainer, it yields each descendant node; If a descendant node is element, it yields the attributes.&lt;/p&gt;
&lt;p&gt;The following SelfAndDescendantObjects query is intuitive by name and straightforward to implement:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;XObject&amp;gt; SelfAndDescendantObjects(this XObject source) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EnumerableEx
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Return(source)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.Concat(source.DescendantObjects());&lt;/p&gt;
&lt;p&gt;The following Names query finds a XContainer source for all elements’ and attributes’ names:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;XName&amp;gt; Names(this XContainer source) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(source is XElement element
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? element.DescendantsAndSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: source.Descendants())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(descendantElement =&amp;gt; EnumerableEx
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Return(descendantElement.Name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(descendantElement
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Attributes()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(attribute =&amp;gt; attribute.Name)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.Distinct();&lt;/p&gt;
&lt;p&gt;As fore mentioned, XName instances are cached, so Distinct is called to remove the duplicated references.&lt;/p&gt;
&lt;p&gt;Above built-in Attributes query finds an element’s attributes. The following AllAttributes queries an XContainer source’s attributes (if it is an element) and all its descendant elements’ attributes:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;XAttribute&amp;gt; AllAttributes(this XContainer source) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(source is XElement element
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? element.DescendantsAndSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: source.Descendants())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.SelectMany(elementOrDescendant =&amp;gt; elementOrDescendant.Attributes());&lt;/p&gt;
&lt;p&gt;The following Namespaces query finds all namespaces defined in a XContainer source:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;(string, XNamespace)&amp;gt; Namespaces(this XContainer source) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source // Namespaces are defined as xmlns:prefix=&quot;namespace&quot; attributes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AllAttributes()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(attribute =&amp;gt; attribute.IsNamespaceDeclaration)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.Select(attribute =&amp;gt; (attribute.Name.LocalName, (XNamespace)attribute.Value));&lt;/p&gt;
&lt;p&gt;It outputs a sequence of (prefix, namespace) tuples, which is very handy. With its help, the following function can be defined to create XmlNamespaceManager from any XContainer source:&lt;/p&gt;
&lt;p&gt;public static XmlNamespaceManager CreateNamespaceManager(this XContainer source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Namespaces()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(@namespace =&amp;gt; namespaceManager.AddNamespace(@namespace.Item1, @namespace.Item2.ToString()));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return namespaceManager;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This function is used later when working with XPath.&lt;/p&gt;
&lt;h2&gt;XPath&lt;/h2&gt;
&lt;p&gt;XPath is a simple query language to select or evaluate objects from an XML tree. It consists of 3 parts:&lt;/p&gt;
&lt;p&gt;· axis, e.g.:&lt;/p&gt;
&lt;p&gt;o / is to select root node (either a document node, or an element node on the fly)&lt;/p&gt;
&lt;p&gt;o /rss/channel/item is to select root node, then select root node’s all &amp;lt;rss&amp;gt; direct child elements, then select each &amp;lt; rss&amp;gt; element’s all &amp;lt;channel&amp;gt; child elements, then select each &amp;lt; channel&amp;gt; element’s all &amp;lt;item&amp;gt; child elements&lt;/p&gt;
&lt;p&gt;o /rss/@version is to select root node, then select root node’s all &amp;lt;rss&amp;gt; direct child elements, then select each&amp;lt; rss&amp;gt; element’s version attribute&lt;/p&gt;
&lt;p&gt;· node test&lt;/p&gt;
&lt;p&gt;o text() is to select all text nodes, comment() is to select all comment nodes, etc.&lt;/p&gt;
&lt;p&gt;o /element/text() is to select root node, then select all &amp;lt;element&amp;gt; child elements, then select each &amp;lt;element&amp;gt; element’s all child text nodes.&lt;/p&gt;
&lt;p&gt;· predicate:&lt;/p&gt;
&lt;p&gt;o [1] means select the first node, etc.&lt;/p&gt;
&lt;p&gt;o /rss[1]/text()[2] means to select root node, then select the first &amp;lt;rss&amp;gt; child element, then select that &amp;lt;rss&amp;gt; element’s second child text node.&lt;/p&gt;
&lt;p&gt;LINQ to XML also provides a few extension methods to work with XPath. The latest XPath version is 3.0, .NET Standard and LINQ to XML implements XPath 1.0.&lt;/p&gt;
&lt;p&gt;The CreateNavigator method creates a XmlXPathNavigator, which can be used for navigation and querying:&lt;/p&gt;
&lt;p&gt;internal static void XPathNavigator()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathNavigator rssNavigator = rss.CreateNavigator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rssNavigator.NodeType.WriteLine(); // Root
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rssNavigator.MoveToFirstChild().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rssNavigator.Name.WriteLine(); // rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((XPathNodeIterator)rssNavigator
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Evaluate(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;XPathNavigator&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(categoryNavigator =&amp;gt; categoryNavigator.UnderlyingObject)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;XElement&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category =&amp;gt; category.Value, // Current text node&apos;s value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category =&amp;gt; category,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(key, group) =&amp;gt; new { Name = key, Count = group.Count() },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;StringComparer.OrdinalIgnoreCase)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(category =&amp;gt; category.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It implements the same query as previous RSS tags example.&lt;/p&gt;
&lt;p&gt;The XPathSelectElements method is a shortcut of calling CreateNavigator to get an XPathNavigator and then call Evaluate. The above query can be shortened as:&lt;/p&gt;
&lt;p&gt;internal static void XPathQuery()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.XPathSelectElements(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category =&amp;gt; category.Value, // Current text node&apos;s value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category =&amp;gt; category,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(key, group) =&amp;gt; new { Name = key, Count = group.Count() },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;StringComparer.OrdinalIgnoreCase)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(category =&amp;gt; category.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And XPathSelectElement is simply a shortcut of calling XPathSelectElements to get a sequence, then call FirstOrDefault.&lt;/p&gt;
&lt;p&gt;XPathEvaluate also calls CreateNavigator and then Evaluate, but it is more flexible. When the XPath is evaluated to a single value, it just returns that value. The following example queries the RSS feed for the average tags count of each &amp;lt;item&amp;gt; element, and also the equivalent LINQ query:&lt;/p&gt;
&lt;p&gt;internal static void XPathEvaluateValue()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double average1 = (double)rss.XPathEvaluate(&quot;count(/rss/channel/item/category) div count(/rss/channel/item)&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;average1.WriteLine(); // 4.65
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double average2 = rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;rss&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;channel&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Elements(&quot;item&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Average(item =&amp;gt; item.Elements(&quot;category&quot;).Count());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;average2.WriteLine(); // 4.65
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the XPath is evaluated to a sequence of values, XPathEvaluate outputs IEnumerable&amp;lt;object&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal static void XPathEvaluateSequence()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((IEnumerable&amp;lt;object&amp;gt;)rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.XPathEvaluate(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category/text()&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;XText&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;categoryTextNode =&amp;gt; categoryTextNode.Value, // Current text node&apos;s value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;categoryTextNode =&amp;gt; categoryTextNode,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(key, group) =&amp;gt; new { Name = key, Count = group.Count() },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;StringComparer.OrdinalIgnoreCase)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(category =&amp;gt; category.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;LINQ to XML also provides overloads for these XPath methods to accept an IXmlNamespaceResolver parameter. When the XPath expression involves namespace, an IXmlNamespaceResolver instance must be provided. Taking another RSS feed from Flickr as an example:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;rss version=&quot;2.0&quot; xmlns:media=&quot;http://search.yahoo.com/mrss/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:flickr=&quot;urn:flickr:user&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;title&amp;gt;Microsoft Way, Microsoft Campus&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dc:date.Taken&amp;gt;2011-11-02T16:45:54-08:00&amp;lt;/dc:date.Taken&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;author flickr:profile=&quot;https://www.flickr.com/people/dixin/&quot;&amp;gt;nobody@flickr.com (Dixin Yan)&amp;lt;/author&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:content url=&quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_b.jpg&quot; type=&quot;image/jpeg&quot; height=&quot;681&quot; width=&quot;1024&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:title&amp;gt;Microsoft Way, Microsoft Campus&amp;lt;/media:title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:description type=&quot;html&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;Microsoft Campus is the informal name of Microsoft&apos;s corporate headquarters, located at One Microsoft Way in Redmond, Washington. Microsoft initially moved onto the grounds of the campus on February 26, 1986. &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Redmond_Campus&quot; rel=&quot;nofollow&quot;&amp;gt;en.wikipedia.org/wiki/Microsoft_Redmond_Campus&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/media:description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:thumbnail url=&quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_s.jpg&quot; height=&quot;75&quot; width=&quot;75&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:credit role=&quot;photographer&quot;&amp;gt;Dixin Yan&amp;lt;/media:credit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;media:category scheme=&quot;urn:flickr:tags&quot;&amp;gt;microsoft&amp;lt;/media:category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- Other elements. --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- Other items. --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/rss&amp;gt;&lt;/p&gt;
&lt;p&gt;It contains additional information than the standard RSS format, and these additional elements/attributes are managed by namespaces. The following example calls the overload of XPathSelectElements to query the &lt;a&gt;media:category&lt;/a&gt; elements:&lt;/p&gt;
&lt;p&gt;internal static void XPathQueryWithNamespace()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlNamespaceManager namespaceManager = rss.CreateNamespaceManager();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;XElement&amp;gt;query1 = rss.XPathSelectElements(&quot;/rss/channel/item/media:category&quot;, namespaceManager);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query1.Count().WriteLine(); // 20
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;XElement&amp;gt; query2 = rss.XPathSelectElements(&quot;/rss/channel/item/media:category&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since prefix “media” is in XPath expression, An IXmlNamespaceResolver instance is required. XmlNamespaceManager implements IXmlNamespaceResolver, so simply call the previously defined CreateNamespaceManager method to create it. In contrast, querying the same XPath expression without IXmlNamespaceResolver instance throws XPathException.&lt;/p&gt;
&lt;p&gt;The last example calls the overload of XPathEvaluate to query the items’ titles, which has the tag “microsoft” in the&amp;lt; media:category&amp;gt; element:&lt;/p&gt;
&lt;p&gt;internal static void XPathEvaluateSequenceWithNamespace()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument rss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((IEnumerable&amp;lt;object&amp;gt;)rss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.XPathEvaluate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;/rss/channel/item[contains(media:category/text(), &apos;microsoft&apos;)]/media:title/text()&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss.CreateNamespaceManager()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;XText&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(mediaTitle =&amp;gt; mediaTitle.Value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chinese President visits Microsoft
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Satya Nadella, CEO of Microsoft
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Generate XPath expression&lt;/h3&gt;
&lt;p&gt;To leverage LINQ to XML, one example is to generate XPath expression for a specified XObject instance, which can be either XAttribute or XNode. The XPath expression can be calculated with the following 3 segments are needed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;the XPath of current object’s parent Element, which can be either calculated recursively, or be provided by caller.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the XPath of current object, which can be&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o @attributeName if it is an attribute&lt;/p&gt;
&lt;p&gt;o elementName if it is an element&lt;/p&gt;
&lt;p&gt;o node test like text(), comment(), etc., if it is any other type of node.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a predicate for current object, which can simply be the position:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o For example, [2] can be used to identify a comment node, if there is another sibling comment node before itself&lt;/p&gt;
&lt;p&gt;o also, the position predicate can be omitted if current object has no ambiguous sibling objects, so that XPath of parent object combining XPath of current object selects one single object. For example, if current node is a comment node with no sibling comment node, then parentElement/comment() without position predicate is good enough&lt;/p&gt;
&lt;p&gt;First of all, a helper function is needed to calculate the current element or attribute’s name, which should be in simple localName format if the XName instance is not under any namespace, and should be in prefix:localName format if the XName instance is under a namespace. XName.ToString does not work for this requirement, because it returns the {namespaceUri}localName format, as already demonstrated. So, the following XPath extension method can be defined for name:&lt;/p&gt;
&lt;p&gt;public static string XPath(this XName source, XElement container)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string prefix = source.Namespace == XNamespace.None
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: container.GetPrefixOfNamespace(source.Namespace); // GetPrefixOfNamespace returns null if not found.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return string.IsNullOrEmpty(prefix) ? source.ToString() : $&quot;{prefix}:{source.LocalName}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Regarding the above segment 1 and segment 2 has to be combined, another helper function is needed to combine 2 XPath expressions, which is similar to .NET built-in Combine method provided by System.IO.Path:&lt;/p&gt;
&lt;p&gt;private static string CombineXPath(string xPath1, string xPath2, string predicate = null) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string.Equals(xPath1, &quot;/&quot;, StringComparison.Ordinal) || string.IsNullOrEmpty(xPath2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? $&quot;{xPath1}{xPath2}{predicate}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;: $&quot;{xPath1}/{xPath2}{predicate}&quot;;&lt;/p&gt;
&lt;p&gt;Regarding XObject can be either one type of attribute, or several types of nodes, apparently attribute does not need the position predicate, while the different types of nodes all share similar logic to identify the position and the ambiguous siblings. So, the following helper function can be defined for XNode:&lt;/p&gt;
&lt;p&gt;private static string XPath&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this TSource source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string parentXPath,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string selfXPath = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, bool&amp;gt; siblingPredicate = null) where TSource : XNode
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.NodesBeforeSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;TSource&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(siblingPredicate ?? (_ =&amp;gt; true))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string predicate = index == 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp; !source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.NodesAfterSelf()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;TSource&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(siblingPredicate ?? (_ =&amp;gt; true))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Any()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: $&quot;[{index + 1}]&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return CombineXPath(parentXPath, selfXPath, predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now, the following XPath extension method can be defined to generate XPath expression for an element:&lt;/p&gt;
&lt;p&gt;public static string XPath(this XElement source, string parentXPath = null) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string.IsNullOrEmpty(parentXPath) &amp;amp;&amp;amp; source.Parent == null &amp;amp;&amp;amp; source.Document == null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? &quot;/&quot; // source is an element on the fly, not attached to any parent node.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: source.XPath(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parentXPath ?? source.Parent?.XPath(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Name.XPath(source),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sibling =&amp;gt; sibling.Name == source.Name);&lt;/p&gt;
&lt;p&gt;There is a special case for element. As fore mentioned, an element can be constructed on the fly, and it is the root node of its XML tree. In this case, just outputs XPath root expression /. For other cases, just call above XPath extension method for XNode, with:&lt;/p&gt;
&lt;p&gt;· XPath of parent element, if not provided then calculate recursively&lt;/p&gt;
&lt;p&gt;· XPath of element name, which can be generated by calling above XPath extension method for XName&lt;/p&gt;
&lt;p&gt;· A lambda expression to identify ambiguous sibling elements with the same element name, so that the proper XPath predicate can be generated&lt;/p&gt;
&lt;p&gt;The XPath overloads for comment/text/processing instruction nodes are straightforward:&lt;/p&gt;
&lt;p&gt;public static string XPath(this XComment source, string parentXPath = null) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source.XPath(parentXPath ?? source.Parent?.XPath(), &quot;comment()&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XText source, string parentXPath = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.XPath(parentXPath ?? source.Parent?.XPath(), &quot;text()&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XProcessingInstruction source, string parentXPath = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.XPath(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parentXPath ?? source.Parent?.XPath(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;processing-instruction(&apos;{source.Target}&apos;)&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sibling =&amp;gt; string.Equals(sibling.Target, source.Target, StringComparison.Ordinal));&lt;/p&gt;
&lt;p&gt;And the XPath overload for attribute just combine parent element’s XPath with the format of @attributeName:&lt;/p&gt;
&lt;p&gt;public static string XPath(this XAttribute source, string parentXPath = null) =&amp;gt;&lt;/p&gt;
&lt;p&gt;CombineXPath(parentXPath ?? source.Parent?.XPath(), $&quot;@{source.Name.XPath(source.Parent)}&quot;);&lt;/p&gt;
&lt;p&gt;Here are some examples of using these extension methods:&lt;/p&gt;
&lt;p&gt;internal static void GenerateXPath()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element1 = aspNetRss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Root
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Element(&quot;channel&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Elements(&quot;item&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Last();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element1.XPath().WriteLine(); // /rss/channel/item[20]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element2 = aspNetRss.XPathSelectElement(element1.XPath());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(element1, element2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XAttribute attribute1 = flickrRss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Root
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Descendants(&quot;author&quot;) // &amp;lt;author flickr:profile=&quot;https://www.flickr.com/people/dixin/&quot;&amp;gt;...&amp;lt;/author&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.First()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Attribute(XName.Get(&quot;profile&quot;, &quot;urn:flickr:user&quot;)); // &amp;lt;rss xmlns:flickr=&quot;urn:flickr:user&quot;&amp;gt;...&amp;lt;/rss&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;attribute1.XPath().WriteLine(); // /rss/channel/item[1]/author/@flickr:profile
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XAttribute attribute2 = ((IEnumerable&amp;lt;object&amp;gt;)flickrRss
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.XPathEvaluate(attribute1.XPath(), flickrRss.CreateNamespaceManager()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Cast&amp;lt;XAttribute&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(attribute1, attribute2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (1) Modeling XML</title><link>https://dixin.github.io/posts/linq-to-xml-1-modeling-xml/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-1-modeling-xml/</guid><description>XML (eXtensible Markup Language) is widely used to represent, store, and transfer data. .NET Standard provides LINQ to XML APIs to query XML data source. LINQ to XML APIs are located in System.Xml.XDo</description><pubDate>Sat, 10 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;XML (eXtensible Markup Language) is widely used to represent, store, and transfer data. .NET Standard provides LINQ to XML APIs to query XML data source. LINQ to XML APIs are located in System.Xml.XDocument NuGet package for .NET Core, and System.Xml.Linq.dll assembly for .NET Framework. LINQ to XML can be viewed as specialized LINQ to Objects, where the queried objects represent XML structures.&lt;/p&gt;
&lt;h2&gt;Modeling XML&lt;/h2&gt;
&lt;p&gt;.NET Standard provides a set provides types to represent the XML structures, including XML document, namespace, element, attribute, comment, text, etc., so that XML can be loaded to memory as instances of those types, and then be queried with LINQ as objects.&lt;/p&gt;
&lt;h3&gt;Imperative paradigm vs. declarative paradigm&lt;/h3&gt;
&lt;p&gt;The XML DOM APIs are provided since .NET Framework 1.0. There a set of Xml* types in System.Xml namespace representing XML structures. The following list shows their inheritance hierarchy:&lt;/p&gt;
&lt;p&gt;· XmlNamedNodeMap&lt;/p&gt;
&lt;p&gt;o XmlAttributeCollection&lt;/p&gt;
&lt;p&gt;· XmlNode&lt;/p&gt;
&lt;p&gt;o XmlAttribute&lt;/p&gt;
&lt;p&gt;o XmlDocument&lt;/p&gt;
&lt;p&gt;o XmlDocumentFragment&lt;/p&gt;
&lt;p&gt;o XmlEntity&lt;/p&gt;
&lt;p&gt;o XmlLinkedNode&lt;/p&gt;
&lt;p&gt;§ XmlCharacterData&lt;/p&gt;
&lt;p&gt;§ XmlCDataSection&lt;/p&gt;
&lt;p&gt;§ XmlComment&lt;/p&gt;
&lt;p&gt;§ XmlSignificantWhitespace&lt;/p&gt;
&lt;p&gt;§ XmlText&lt;/p&gt;
&lt;p&gt;§ XmlWhitespace&lt;/p&gt;
&lt;p&gt;§ XmlDeclaration&lt;/p&gt;
&lt;p&gt;§ XmlDocumentType&lt;/p&gt;
&lt;p&gt;§ XmlElement&lt;/p&gt;
&lt;p&gt;§ XmlEntityReference&lt;/p&gt;
&lt;p&gt;§ XmlProcessingInstruction&lt;/p&gt;
&lt;p&gt;o XmlNotation&lt;/p&gt;
&lt;p&gt;· XmlNodeList&lt;/p&gt;
&lt;p&gt;· XmlQualifiedName&lt;/p&gt;
&lt;p&gt;These DOM APIs for XML can be used to model and manipulate XML structures in imperative paradigm. Take the following XML fragment as example:&lt;/p&gt;
&lt;p&gt;&amp;lt;rss version=&quot;2.0&quot; xmlns:dixin=&quot;https://weblogs.asp.net/dixin&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;title&amp;gt;LINQ via C#&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link&amp;gt;https://weblogs.asp.net/dixin/linq-via-csharp&amp;lt;/link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;pubDate&amp;gt;Mon, 07 Sep 2009 00:00:00 GMT&amp;lt;/pubDate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;guid isPermaLink=&quot;true&quot;&amp;gt;https://weblogs.asp.net/dixin/linq-via-csharp&amp;lt;/guid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;C#&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;LINQ&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--Comment.--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dixin:source&amp;gt;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq&amp;lt;/dixin:source&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/rss&amp;gt;&lt;/p&gt;
&lt;p&gt;It is a small RSS feed sample with one single item. The following example calls XML DOM APIs to build such a XML tree, and serialize the XML tree to string:&lt;/p&gt;
&lt;p&gt;internal static void CreateAndSerializeWithDom()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string NamespacePrefix = &quot;dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;namespaceManager.AddNamespace(NamespacePrefix, &quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlDocument document = new XmlDocument(namespaceManager.NameTable);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement rss = document.CreateElement(&quot;rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss.SetAttribute(&quot;version&quot;, &quot;2.0&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlAttribute attribute = document.CreateAttribute(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;xmlns&quot;, NamespacePrefix, namespaceManager.LookupNamespace(&quot;xmlns&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;attribute.Value = namespaceManager.LookupNamespace(NamespacePrefix);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss.SetAttributeNode(attribute);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.AppendChild(rss);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement channel = document.CreateElement(&quot;channel&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss.AppendChild(channel);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement item = document.CreateElement(&quot;item&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;channel.AppendChild(item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement title = document.CreateElement(&quot;title&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title.InnerText = &quot;LINQ via C#&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(title);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement link = document.CreateElement(&quot;link&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;link.InnerText = &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(link);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement description = document.CreateElement(&quot;description&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;description.InnerXml = &quot;&amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(description);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement pubDate = document.CreateElement(&quot;pubDate&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;pubDate.InnerText = new DateTime(2009, 9, 7).ToString(&quot;r&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(pubDate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement guid = document.CreateElement(&quot;guid&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;guid.InnerText = &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;guid.SetAttribute(&quot;isPermaLink&quot;, &quot;true&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(guid);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement category1 = document.CreateElement(&quot;category&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category1.InnerText = &quot;C#&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(category1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlNode category2 = category1.CloneNode(false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category2.InnerText = &quot;LINQ&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(category2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlComment comment = document.CreateComment(&quot;Comment.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(comment);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlElement source = document.CreateElement(NamespacePrefix, &quot;source&quot;, namespaceManager.LookupNamespace(NamespacePrefix));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.InnerText = &quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;item.AppendChild(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Serialize XmlDocument to string.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// rssItem.ToString() outputs &quot;System.Xml.XmlElement&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// rssItem.OuterXml outputs a single line of XML text.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;StringBuilder xmlString = new StringBuilder();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XmlWriterSettings settings = new XmlWriterSettings
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Indent = true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IndentChars = &quot; &quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OmitXmlDeclaration = true
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlWriter writer = XmlWriter.Create(xmlString, settings))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.Save(writer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;xmlString.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These APIs have a few disadvantages:&lt;/p&gt;
&lt;p&gt;· Any XML structure has to be created with a XmlDocument instance.&lt;/p&gt;
&lt;p&gt;· XML tree has to be built imperatively, node by node.&lt;/p&gt;
&lt;p&gt;· Additional work is needed to manage namespaces and prefixes.&lt;/p&gt;
&lt;p&gt;· Some operations, like serialization, is not straightforward.&lt;/p&gt;
&lt;p&gt;Fortunately, LINQ to XML does not work with these Xml* types. It redesigns a bunch of X* types under System.Xml.Linq namespace, and enables LINQ queries for these objects. The following list shows the inheritance hierarchy of all the X* types, as well as each type’s conversion from/to other types, and their overloaded operators:&lt;/p&gt;
&lt;p&gt;· XDeclaration&lt;/p&gt;
&lt;p&gt;· XName: implicit convertible from string, ==, !=&lt;/p&gt;
&lt;p&gt;· XNamespace: implicit convertible from string, + string, ==, !=&lt;/p&gt;
&lt;p&gt;· XObject&lt;/p&gt;
&lt;p&gt;o XAttribute: explicit convertible to string/bool/bool?/int/int?/uint/uint?/long/long?/ulong/ulong?/float/float?/double/double?/decimal/decimal?/DateTime/DateTime?/TimeSpan/TimeSpan?/Guid/Guid?&lt;/p&gt;
&lt;p&gt;o XNode: DeepEquals&lt;/p&gt;
&lt;p&gt;§ XComment&lt;/p&gt;
&lt;p&gt;§ XContainer&lt;/p&gt;
&lt;p&gt;§ XDocument&lt;/p&gt;
&lt;p&gt;§ XElement: explicit convertible to string/bool/bool?/int/int?/uint/uint?/long/long?/ulong/ulong?/float/float?/double/double?/decimal/decimal?/DateTime/DateTime?/TimeSpan/TimeSpan?/Guid/Guid?&lt;/p&gt;
&lt;p&gt;§ XDocumentType&lt;/p&gt;
&lt;p&gt;§ XProcessingInstruction&lt;/p&gt;
&lt;p&gt;§ XText&lt;/p&gt;
&lt;p&gt;§ XCData&lt;/p&gt;
&lt;p&gt;· XStreamingElement&lt;/p&gt;
&lt;p&gt;As the names suggest, e.g., XNode represents a XML node, XDocument represents a XML document, XName represents XML element name or XML attribute name, etc. And apparently, An XML element/attribute name is essentially a string, so XName implements implicit conversion from string, which provides great convenience. The following example builds the same XML tree with the new LINQ to XML types:&lt;/p&gt;
&lt;p&gt;internal static void CreateAndSerializeWithLinq()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNamespace @namespace = &quot;https://weblogs.asp.net/dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement rss = new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;rss&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XAttribute(&quot;version&quot;, &quot;2.0&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XAttribute(XNamespace.Xmlns + &quot;dixin&quot;, @namespace),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;channel&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;item&quot;, // Implicitly converted to XName.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(&quot;title&quot;, &quot;LINQ via C#&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(&quot;link&quot;, &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;description&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement.Parse(&quot;&amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;&quot;)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(&quot;pubDate&quot;, new DateTime(2009, 9, 7).ToString(&quot;r&quot;)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;guid&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XAttribute(&quot;isPermaLink&quot;, &quot;true&quot;), // &quot;isPermaLink&quot; is implicitly converted to XName.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(&quot;category&quot;, &quot;C#&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(&quot;category&quot;, &quot;LINQ&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XComment(&quot;Comment.&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new XElement(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@namespace + &quot;source&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq&quot;))));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rss.ToString().WriteLine(); // Serialize XDocument to string.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The new APIs is shorter and more intuitive:&lt;/p&gt;
&lt;p&gt;· XML structure can be created on the fly, XDocument is not involved in the entire example.&lt;/p&gt;
&lt;p&gt;· XML tree can be built declaratively.&lt;/p&gt;
&lt;p&gt;· Easier namespace management, with prefix automatically taken care of.&lt;/p&gt;
&lt;p&gt;· To serialize an XML tree, simply call ToString.&lt;/p&gt;
&lt;h3&gt;Types, conversions and operators&lt;/h3&gt;
&lt;p&gt;Besides XDocument, XElement, XAttribute, and XComment in above example, some other XML structures can also can declaratively constructed too:&lt;/p&gt;
&lt;p&gt;internal static void Construction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDeclaration declaration = new XDeclaration(&quot;1.0&quot;, null, &quot;no&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;declaration.WriteLine(); // &amp;lt;?xml version=&quot;1.0&quot; standalone=&quot;no&quot;?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocumentType documentType = new XDocumentType(&quot;html&quot;, null, null, null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;documentType.WriteLine(); // &amp;lt;!DOCTYPE html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XText text = new XText(&quot;&amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;text.WriteLine(); // &amp;amp; lt;p&amp;amp;gt;text&amp;amp;lt;/p&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XCData cData = new XCData(&quot;cdata&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cData.WriteLine(); // &amp;lt;![CDATA[cdata]]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XProcessingInstruction processingInstruction = new XProcessingInstruction(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;xml-stylesheet&quot;, @&quot;type=&quot;&quot;text/xsl&quot;&quot; href=&quot;&quot;Style.xsl&quot;&quot;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;processingInstruction.WriteLine(); //&amp;lt; ?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;Style.xsl&quot;?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;XName is different. LINQ to XML provides 2 equivalent ways to instantiate XName:&lt;/p&gt;
&lt;p&gt;· calling XName.Get&lt;/p&gt;
&lt;p&gt;· implicitly converting from string (which is implemented with XName.Get as well).&lt;/p&gt;
&lt;p&gt;The constructor is not exposed, because LINQ to XML caches all the constructed XName instances at runtime, so a XName instance is constructed only once for a specific name. LINQ to XML also implements the == and != operator by checking the reference equality:&lt;/p&gt;
&lt;p&gt;internal static void Name()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName attributeName1 = &quot;isPermaLink&quot;; // Implicitly convert string to XName.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName attributeName2 = XName.Get(&quot;isPermaLink&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName attributeName3 = &quot;IsPermaLink&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(attributeName1, attributeName2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(attributeName1 == attributeName2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(attributeName1 != attributeName3).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;XNamespace has the same behaviour as XName. additionally, it implements the + operator to combine the namespace and local name:&lt;/p&gt;
&lt;p&gt;internal static void Namespace()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNamespace namespace1 = &quot;http://www.w3.org/XML/1998/namespace&quot;; // Implicitly convert string to XNamespace.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNamespace namespace2 = XNamespace.Xml;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNamespace namespace3 = XNamespace.Get(&quot;http://www.w3.org/2000/xmlns/&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(namespace1 == namespace2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(namespace1 != namespace3).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNamespace @namespace = &quot;https://weblogs.asp.net/dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName name = @namespace + &quot;localName&quot;; // + operator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name.WriteLine(); // {https://weblogs.asp.net/dixin}localName
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element = new XElement(name, new XAttribute(XNamespace.Xmlns + &quot;dixin&quot;, @namespace)); // + operator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element.WriteLine(); // &amp;lt;dixin:localName xmlns:dixin=&quot;https://weblogs.asp.net/dixin&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;XElement can be explicitly converted to .NET primitive types, e.g.:&lt;/p&gt;
&lt;p&gt;internal static void Element()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement pubDateElement = XElement.Parse(&quot;&amp;lt;pubDate&amp;gt;Mon, 07 Sep 2009 00:00:00 GMT&amp;lt;/pubDate&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime pubDate = (DateTime)pubDateElement;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;pubDate.WriteLine(); // 9/7/2009 12:00:00 AM
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above conversion is implemented by calling DateTime.Parse with the string value returned by XElement.Value.&lt;/p&gt;
&lt;p&gt;XAttribute can be converted to primitive types too:&lt;/p&gt;
&lt;p&gt;internal static void Attribute()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XName name = &quot;isPermaLink&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XAttribute isPermanentLinkAttribute = new XAttribute(name, &quot;true&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool isPermaLink = (bool)isPermanentLinkAttribute;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isPermanentLink.WriteLine() // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the conversion is implemented by calling System.Xml.XmlConvert’s ToBoolean method with the string value returned by XElement.Value.&lt;/p&gt;
&lt;p&gt;XComment, XDocument, XElement, XDocumentType, XProcessingInstruction, XText, and XCData types inherit XNode. XNode provides a DeepEquals method to compare any 2 nodes:&lt;/p&gt;
&lt;p&gt;internal static void DeepEquals()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element1 = XElement.Parse(&quot;&amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element2 = new XElement(&quot;parent&quot;, new XElement(&quot;child&quot;)); // &amp;lt; parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(element1, element2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.DeepEquals(element1, element2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element3 = new XElement(&quot;parent&quot;, new XElement(&quot;child&quot;, string.Empty)); // &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(element1, element2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode.DeepEquals(element1, element3).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here element2’s child element is constructed with null content, so it is an empty element node &amp;lt;child /&amp;gt; (where XElement.IsEmpty returns true). element3’s child element is constructed with an empty string as content, so it is a non-empty element&amp;lt; child&amp;gt;&amp;lt;/child&amp;gt; ((where XElement.IsEmpty returns false). As a result, element1 has the same node structures and node values as element2, and they are different from element3.&lt;/p&gt;
&lt;h3&gt;Read and deserialize XML&lt;/h3&gt;
&lt;p&gt;In LINQ to XML, XML can be easily read or deserialized to XNode/XElement/XDocument instances in memory. with the following APIs:&lt;/p&gt;
&lt;p&gt;· XmlReader (under System.Xml namespace)&lt;/p&gt;
&lt;p&gt;· XNode.CreateReader, XNode.ReadFrom&lt;/p&gt;
&lt;p&gt;· XDocument.Load, XDocument.Parse&lt;/p&gt;
&lt;p&gt;· XElement.Load, XElement.Parse&lt;/p&gt;
&lt;p&gt;The APIs accepting URI, for example:&lt;/p&gt;
&lt;p&gt;internal static void Read()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlReader reader = XmlReader.Create(&quot;https://weblogs.asp.net/dixin/rss&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reader.MoveToContent();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XNode node = XNode.ReadFrom(reader);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element1 = XElement.Parse(&quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element2 = XElement.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document1 = XDocument.Parse(&quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document2 = XDocument.Load(&quot;https://microsoft.com&quot;); // Succeed.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document3 = XDocument.Load(&quot;https://asp.net&quot;); // Fail.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Xml.XmlException: The &apos;ul&apos; start tag on line 68 position 116 does not match the end tag of &apos;div&apos;. Line 154, position 109.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Reading an RSS feed to construct an XML tree usually work smoothly, since RSS is just XML. Reading a web page usually has bigger chance to fail, because in the real world, a HTML document may be not strictly structured.&lt;/p&gt;
&lt;p&gt;The above example reads entire XML document and deserialize the string to XML tree in the memory. Regarding the specified XML can have arbitrary size, XmlReader and XNode.ReadFrom can also read XML fragment by fragment:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;XElement&amp;gt; RssItems(string rssUri)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlReader reader = XmlReader.Create(rssUri))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reader.MoveToContent();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (reader.Read())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (reader.NodeType == XmlNodeType.Element &amp;amp;&amp;amp; reader.Name.Equals(&quot;item&quot;, StringComparison.Ordinal))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (XElement)XNode.ReadFrom(reader);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As discussed in the LINQ to Objects chapter, function with yield return statement is compiled to generator construction, and all the API calls in above function body is deferred, so each &amp;lt;item&amp;gt; in the RSS feed is read and deserialized on demand.&lt;/p&gt;
&lt;h3&gt;Serialize and write XML&lt;/h3&gt;
&lt;p&gt;The following APIs are provided to serialize XML to string, or write XML to somewhere (file system, memory, etc.):&lt;/p&gt;
&lt;p&gt;· XmlWriter&lt;/p&gt;
&lt;p&gt;· XObject.ToString&lt;/p&gt;
&lt;p&gt;· XNode.ToString, XNode.WriteTo&lt;/p&gt;
&lt;p&gt;· XContainer.CreateWriter&lt;/p&gt;
&lt;p&gt;· XDocument.Save&lt;/p&gt;
&lt;p&gt;· XElement.Save&lt;/p&gt;
&lt;p&gt;· XStramingElement.Save, XStramingElement.ToString, XStreamingElement.WriteTo&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Write()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document1 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (FileStream stream = File.OpenWrite(Path.GetTempFileName()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document1.Save(stream);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element1 = new XElement(&quot;element&quot;, string.Empty);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document2 = new XDocument();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlWriter writer = document2.CreateWriter())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element1.WriteTo(writer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document2.WriteLine(); //&amp;lt; element&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement element2 = new XElement(&quot;element&quot;, string.Empty);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (XmlWriter writer = element2.CreateWriter())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;writer.WriteStartElement(&quot;child&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;writer.WriteAttributeString(&quot;attribute&quot;, &quot;value&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;writer.WriteString(&quot;text&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;writer.WriteEndElement();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;element2.ToString(SaveOptions.DisableFormatting).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;text&amp;lt;/child&amp;gt;&amp;lt;/element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;XNode also provides a ToString overload to accept a SaveOptions flag:&lt;/p&gt;
&lt;p&gt;internal static void XNodeToString()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument document = XDocument.Parse(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;&amp;lt;root xmlns:prefix=&apos;namespace&apos;&amp;gt;&amp;lt;element xmlns:prefix=&apos;namespace&apos; /&amp;gt;&amp;lt;/root&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.ToString(SaveOptions.None).WriteLine(); // Equivalent to document.ToString().
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element xmlns:prefix=&quot;namespace&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.ToString(SaveOptions.DisableFormatting).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;&amp;lt;element xmlns:prefix=&quot;namespace&quot; /&amp;gt;&amp;lt;/root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.ToString(SaveOptions.OmitDuplicateNamespaces).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;element /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt;/root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To serialize XML with even more custom settings, the XmlWriter with XmlWriterSettings approach in the DOM API example can be used.&lt;/p&gt;
&lt;h3&gt;Deferred construction&lt;/h3&gt;
&lt;p&gt;The XStreamingElement is a special type. It is used to defer the build of element. For example:&lt;/p&gt;
&lt;p&gt;internal static void StreamingElementWithChildElements()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;XElement&amp;gt; ChildElementsFactory() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5).Do(value =&amp;gt; value.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(value =&amp;gt; new XElement(&quot;child&quot;, value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement immediateParent = new XElement(&quot;parent&quot;, ChildElementsFactory()); // 0 1 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immediateParent.ToString(SaveOptions.DisableFormatting).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;0&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;1&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;2&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;3&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;4&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XStreamingElement deferredParent = new XStreamingElement(&quot;parent&quot;, ChildElementsFactory()); // Deferred.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;deferredParent.ToString(SaveOptions.DisableFormatting).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;0&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;1&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;2&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;3&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;4&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here a factory function is defined to generate a sequence of child elements. It calls the Do query from Interactive Extension (Ix) to prints each value when that pulled from the sequence. Next, the XElement constructor is called, which immediately pulls all child elements from the sequence returned by the factory function, so that the parent element is immediately built with those child elements. Therefore, the Do query is executed right away, and prints the values of the generated child elements. In contrast, XStreamingElement constructor does not pull the child elements from the sequence, the values are not printed yet by Do. The pulling is deferred until the parent element needs to be built, for example, when XStreamingElement.Save/XStreamingElement.ToString/XStreamingElement.WriteTo is called.&lt;/p&gt;
&lt;p&gt;This feature can also be demonstrated by modifying the child elements. For XElement, once constructed, the element is built immediately, and is not impacted by modifying the original child elements. In contrast, XStreamingElement can be impacted by the modification:&lt;/p&gt;
&lt;p&gt;internal static void StreamingElementWithChildElementModification()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement source = new XElement(&quot;source&quot;, new XElement(&quot;child&quot;, &quot;a&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement child = source.Elements().Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XElement immediateParent = new XElement(&quot;parent&quot;, child);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XStreamingElement deferredParent = new XStreamingElement(&quot;parent&quot;, child); // Deferred.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;child.Value = &quot;b&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immediateParent.ToString(SaveOptions.DisableFormatting).WriteLine(); // &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;a&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;deferredParent.ToString(SaveOptions.DisableFormatting).WriteLine(); // &amp;lt; parent&amp;gt;&amp;lt;child&amp;gt;b&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>Setup Open Live Writer and sync with Windows Live Writer cross computers</title><link>https://dixin.github.io/posts/setup-open-live-writer-and-sync-with-windows-live-writer-cross-computers/</link><guid isPermaLink="true">https://dixin.github.io/posts/setup-open-live-writer-and-sync-with-windows-live-writer-cross-computers/</guid><description>Today I am setting up a new PC. I use Windows Live Writer to write for this blog for years, and found the new installation can no longer work for my blog. I tried Open Live Writer. Fortunately Open Li</description><pubDate>Mon, 22 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I am setting up a new PC. I use Windows Live Writer to write for this blog for years, and found the new installation can no longer work for my blog. I tried Open Live Writer. Fortunately Open Live Writer works.&lt;/p&gt;
&lt;p&gt;The next step is to synchronize the new Open Live Writer installation with my other computer’s Windows Live Writer.&lt;/p&gt;
&lt;h2&gt;Plugins&lt;/h2&gt;
&lt;p&gt;The plugins for Windows Live Writer does not work for Open Live Writer. Take the the VSPaste plugin as example, it can paste code copied from Visual Studio into Windows Live Writer and keep the style and color. It is built for Windows Live Writer and does not work for Open Live Writer.&lt;/p&gt;
&lt;p&gt;To rebuild it for Open Live Writer, first decompile the plugin dll file. Then replace the reference assembly WindowsLive.Writer.Api.dll with OpenLiveWriter.Api.dll, which can be found at %UserProfile%\AppData\Local\OpenLiveWriter\app-0.6.2.&lt;/p&gt;
&lt;p&gt;The rebuilt plugin VSPaste.OpenLiveWriter.dll should be placed in the %UserProfile%\AppData\Local\OpenLiveWriter\app-0.6.2\Plugins directory.&lt;/p&gt;
&lt;p&gt;To debug the rebuilt plugin, clone the source of Open Live Writer from &lt;a href=&quot;https://github.com/OpenLiveWriter/OpenLiveWriter.git&quot;&gt;https://github.com/OpenLiveWriter/OpenLiveWriter.git&lt;/a&gt; and open in Visual Studio. Then launch Open Live Writer, and use Visual Studio to attach to the Open Live Writer process.&lt;/p&gt;
&lt;p&gt;I have uploaded the plugin source to GitHub for demonstration purpose: &lt;a href=&quot;https://github.com/Dixin/LiveWriter.VSPaste&quot;&gt;https://github.com/Dixin/LiveWriter.VSPaste&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To synchronize the plugin cross multiple PCs, I put the plugins (VSPaste.WindowsLiveWriter.dll and VSPaste.OpenLiveWriter.dll) into a OneDrive directory, for example, D:\OneDrive\LiveWriter\Plugins. Then create a junction point for Windows Live Writer and Open Live Writer:&lt;/p&gt;
&lt;p&gt;mklink /J C:\Users\dixin\AppData\Local\OpenLiveWriter\app-0.6.2\Plugins D:\OneDrive\LiveWriter\Plugins&lt;/p&gt;
&lt;h2&gt;Synchronize blog id&lt;/h2&gt;
&lt;p&gt;As mentioned in &lt;a href=&quot;/posts/sync-windows-live-writer-drafts-and-posts-across-pcs&quot;&gt;an earlier post&lt;/a&gt;, the blog account is associated with a GUID, and the GUID is written to blog post file (which is not a good design). For Windows Live Writer, the blog id is located under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows Live\Writer\Weblog\. For Open Live Writer, it is located under Computer\HKEY_CURRENT_USER\Software\OpenLiveWriter\Weblogs. For the same blog, just make sure the same blog account has the same GUID.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Open-Live-Writer_1701/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Setup-Open-Live-Writer_1701/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C:\Users\dixinyan\AppData\Roaming\Windows Live Writer\blogtemplates&lt;/p&gt;
&lt;h2&gt;Synchronize configurations&lt;/h2&gt;
&lt;p&gt;The configurations for Windows Live Writer is located under %UserProfile%\AppData\Roaming\Windows Live Writer, and the configuratiuons for Open Live Writer is located under %UserProfile%\AppData\Roaming\OpenLiveWriter. The configurations includes blog template, user dictionary for spell check, etc. These can also be synchronized cross multiple PCs using OneDrive:&lt;/p&gt;
&lt;p&gt;mklink /J C:\Users\dixin\AppData\Roaming\OpenLiveWriter D:\OneDrive\LiveWriter\Configurations&lt;/p&gt;
&lt;h2&gt;Synchronize blog posts&lt;/h2&gt;
&lt;p&gt;Once blog id is synchronized, it is safe to synchronize blog posts cross multiple PCs, again, using OneDrive:&lt;/p&gt;
&lt;p&gt;mklink /J “C:\Users\dixin\Documents\My Weblog Posts” “D:\OneDrive\LiveWriter\My Weblog Posts”&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (7) Building Custom Query Methods</title><link>https://dixin.github.io/posts/linq-to-objects-custom-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-custom-query-methods/</guid><description>With the understanding of standard queries in .NET Standard and the additional queries provided by Microsoft, it is easy to define custom LINQ queries for objects. This chapter demonstrates how to def</description><pubDate>Sun, 07 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;With the understanding of standard queries in .NET Standard and the additional queries provided by Microsoft, it is easy to define custom LINQ queries for objects. This chapter demonstrates how to define the following useful LINQ to Object queries:&lt;/p&gt;
&lt;p&gt;· Sequence queries: output a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution)&lt;/p&gt;
&lt;p&gt;o Generation: Create, Guid, RandomInt32, RandomDouble, FromValue, EmptyIfNull&lt;/p&gt;
&lt;p&gt;o Concatenation: ConcatJoin&lt;/p&gt;
&lt;p&gt;o Partitioning: Subsequence, Pagination&lt;/p&gt;
&lt;p&gt;o Ordering: OrderBy*, OrderByDescending*, ThenBy*, ThenByDescending*&lt;/p&gt;
&lt;p&gt;o Grouping, Join, Set: GroupBy*, Join*, GroupJoin*, Distinct, Union, Intersect*, Except*&lt;/p&gt;
&lt;p&gt;o List: Insert, Remove, RemoveAll, RemoveAt&lt;/p&gt;
&lt;p&gt;· Collection queries: output a new collection (immediate execution)&lt;/p&gt;
&lt;p&gt;o Conversion: ToDictionary, ToLookup&lt;/p&gt;
&lt;p&gt;· Value queries: output a single value (immediate execution)&lt;/p&gt;
&lt;p&gt;o Aggregation: PercentileExclusive, PercentileInclusive, Percentile&lt;/p&gt;
&lt;p&gt;o Quantifiers: IsNullOrEmpty, Contains&lt;/p&gt;
&lt;p&gt;o Equality: SequenceEqual&lt;/p&gt;
&lt;p&gt;o List: IndexOf, LastIndexOf&lt;/p&gt;
&lt;p&gt;· Void queries: no output (immediate execution)&lt;/p&gt;
&lt;p&gt;o Iteration: ForEach&lt;/p&gt;
&lt;p&gt;Just like the standard and Ix queries, all the above sequence queries implement deferred execution, where the sequence queries marked with * implements eager evaluation, and other unmarked sequence queries implements lazy evaluation. All the other collection queries, value queries, and void queries implement immediate execution.&lt;/p&gt;
&lt;p&gt;These queries can be defined in the following static class EnumerableX:&lt;/p&gt;
&lt;p&gt;public static partial class EnumerableX { }&lt;/p&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Ix provides a Create query to execute sequence factory function once. In contrast, the following Create overload is defined to generate a sequence of values by repeatedly calling a value factory:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Create&amp;lt;TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TResult&amp;gt;valueFactory, int? count = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt;CreateGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return valueFactory(); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return valueFactory(); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return CreateGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When count is not provided, an infinite sequence is generated. For example, the following Guid query uses Create to repeatedly call Guid.NewGuid, so that it generates a sequence of new GUIDs:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;Guid&amp;gt; NewGuid(int? count) =&amp;gt; Create(Guid.NewGuid, count);&lt;/p&gt;
&lt;p&gt;The following queries generate a sequence of random numbers:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;int&amp;gt; RandomInt32(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int min, int max, int? count = null, int? seed = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerableEx.Defer(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Random random = new Random(seed ?? Environment.TickCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Create(() =&amp;gt; random.Next(min, max), count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;double&amp;gt; RandomDouble(int? count = null, int ? seed = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerableEx.Defer(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Random random = new Random(seed ?? Environment.TickCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Create(random.NextDouble, count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;Here Defer is called to defer the instantiation of Random.&lt;/p&gt;
&lt;p&gt;The following EmptyIfNull can be used to omit null checks:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; EmptyIfNull&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;&lt;/p&gt;
&lt;p&gt;source ?? Enumerable.Empty&amp;lt;TSource&amp;gt;();&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void EmptyIfNull(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable&amp;lt;int&amp;gt; source2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;positive = source1.EmptyIfNull()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Union(source2.EmptyIfNull())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(int32 =&amp;gt; int32 &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;string has a useful method Join:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class String
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string Join(string separator, IEnumerable&amp;lt;string&amp;gt; values);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It concatenates the string values with a single separator between each 2 adjacent string values. Similarly, a general ConcatJoin query can be defined as:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; ConcatJoin&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TSource separator)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator.Current; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return separator; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator.Current; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The built-in Append/Prepend can append/prepend 1 value to the source sequence. So the following overloads can be defined to support multiple values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Append&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, params TSource[] values) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Concat(values);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Prepend&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, params TSource[] values) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;values.Concat(source);&lt;/p&gt;
&lt;p&gt;The following AppendTo/PrependTo extension method are defined for single value, which canto make code more fluent:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AppendTo&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this TSource value, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Append(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; PrependTo&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this TSource value, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Prepend(value);&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Similar to string.Substring, a general Subsequence query can be defined as:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Subsequence&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int startIndex, int count) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Skip(startIndex).Take(count);&lt;/p&gt;
&lt;p&gt;The following Pagination query is useful to paginate a sequence of values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Pagination&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int pageIndex, int countPerPage) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Skip(pageIndex * countPerPage).Take(countPerPage);&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;In LINQ to Objects, the ordering queries must compare objects to determine their order, so they all have overload to accept IComparer&amp;lt;T&amp;gt; parameter. This interface can be viewed as a wrapper of a simple comparison functions:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IComparer&amp;lt;in T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int Compare(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEqualityComparer&amp;lt;in T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool Equals(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int GetHashCode(T obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In C#, interfaces are less convenient then functions. C# supports lambda expression to define anonymous functions inline, but does not support anonymous class to enable inline interface. For the LINQ queries accepting interface parameter, they are easier to be called if they can accept function parameter instead. To Implement this, the following ToComparer function can be defined to convert a compare functions to an IComparer&amp;lt;T&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;private static IComparer&amp;lt;T&amp;gt; ToComparer&amp;lt;T&amp;gt;(Func&amp;lt;T, T, int&amp;gt; compare) =&amp;gt;&lt;/p&gt;
&lt;p&gt;Comparer&amp;lt;T&amp;gt;.Create(new Comparison&amp;lt;T&amp;gt;(compare));&lt;/p&gt;
&lt;p&gt;It simply calls a .NET Standard built-in API Comparer&amp;lt;T&amp;gt;.Create for the IComparer&amp;lt;T&amp;gt; instantiation. Now the ordering queries’ overloads can be defined as a higher-order functions to accept a (T, T) –&amp;gt; int function instead of IComparer&amp;lt;T&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, int&amp;gt;compare) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.OrderBy(keySelector, ToComparer(compare));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, int&amp;gt;compare) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.OrderByDescending(keySelector, ToComparer(compare));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, int&amp;gt;compare) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.ThenBy(keySelector, ToComparer(compare));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, int&amp;gt;compare) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.ThenByDescending(keySelector, ToComparer(compare));&lt;/p&gt;
&lt;h3&gt;Grouping, join, and set&lt;/h3&gt;
&lt;p&gt;In LINQ to Objects, there are also queries need to compare objects’ equality to determine the grouping, join, and set operation, so they all have overload to accept IEqualityComparer&amp;lt;T&amp;gt; parameter. .NET Standard does not provide a built-in API for IEqualityComparer&amp;lt;T&amp;gt; instantiation from functions (F# core library provides a Microsoft.FSharp.Collections.HashIdentity type to wrap functions for IEqualityComparer&amp;lt;T&amp;gt;, but it is not easy to use in C#). So first, a EqualityComparerWrapper&amp;lt;T&amp;gt; type can be defined to implement IEqualityComparer&amp;lt;T&amp;gt;, then a higher-order function ToEqualityComparer can be defined to convert a equals functions and a getHashCode function to an IEqualityComparer&amp;lt;T&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;internal class EqualityComparerWrapper&amp;lt;T&amp;gt; : IEqualityComparer&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Func&amp;lt;T, T, bool&amp;gt; equals;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Func&amp;lt;T, int&amp;gt; getHashCode;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public EqualityComparerWrapper(Func&amp;lt;T, T, bool&amp;gt; equals, Func&amp;lt;T, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.equals, this.getHashCode) = (@equals, getHashCode ?? (value =&amp;gt; value.GetHashCode()));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Equals(T x, T y) =&amp;gt; this.equals(x, y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int GetHashCode(T obj) =&amp;gt; this.getHashCode(obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static IEqualityComparer&amp;lt;T&amp;gt; ToEqualityComparer&amp;lt;T&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, T, bool&amp;gt; equals, Func&amp;lt;T, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;new EqualityComparerWrapper&amp;lt;T&amp;gt;(equals, getHashCode);&lt;/p&gt;
&lt;p&gt;The getHashCode function is optional, because any type already inherits a GetHashCode method from object. Similar to ordering queries, the following functional overloads can be defined for GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.GroupBy(keySelector, elementSelector, resultSelector, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outer.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outer.GroupJoin(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Distinct(ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;first.Union(second, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;first.Intersect(second, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;first.Except(second, ToEqualityComparer(equals, getHashCode));&lt;/p&gt;
&lt;h3&gt;List&lt;/h3&gt;
&lt;p&gt;The List&amp;lt;T&amp;gt; type provides handy methods, which can be implemented for sequence too. The following Insert query is similar to List&amp;lt;T&amp;gt;.Insert, it outputs a new sequence with the specified value is inserted at the specified index:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Insert&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int index, TSource value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index&amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(index));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; InsertGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int currentIndex = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (currentIndex == index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sourceValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentIndex = checked(currentIndex + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index == currentIndex)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else if (index&amp;gt; currentIndex)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nameof(index),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{nameof(index)} must be within the bounds of {nameof(source)}.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return InsertGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above Insert query is more functional than List&amp;lt;T&amp;gt;.Insert. List&amp;lt;T&amp;gt;.Insert has no output, so it is not fluent and it implements immediate execution. It is also impure by mutating the list in place. The above Insert query follows the iterator pattern, and uses yield statement to implement deferred execution. It outputs a new sequence, so it is fluent, and it is a pure function since it does not mutate the source sequence.&lt;/p&gt;
&lt;p&gt;RemoveAt outputs a new sequence with a value removed at the specified index:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; RemoveAt&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index&amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(index));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; RemoveAtGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int currentIndex = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (currentIndex != index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentIndex = checked(currentIndex + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index&amp;gt; = currentIndex)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(index));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return RemoveAtGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Remove outputs a new sequence with the first occurrence of the specified value removed. Besides being deferred and lazy, it also accepts an optional equality comparer:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Remove&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool isRemoved = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!isRemoved&amp;amp;&amp;amp; comparer.Equals(sourceValue, value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isRemoved = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sourceValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;RemoveAll outputs a new sequence with all occurrences of the specified value removed:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; RemoveAll&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!comparer.Equals(sourceValue, value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sourceValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since Remove and RemoveAll tests the equality of objects to determine which objects to remove, the following higher-order function overloads can be defined for convenience:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Remove&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Remove(value, ToEqualityComparer(@equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; RemoveAll&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.RemoveAll(value, ToEqualityComparer(@equals, getHashCode));&lt;/p&gt;
&lt;h2&gt;Collection queries&lt;/h2&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;ToDictionary and ToLookup accept IEqualityComparer&amp;lt;T&amp;gt; parameter to test the equality of keys. Their functional overloads can be defined:&lt;/p&gt;
&lt;p&gt;public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.ToDictionary(keySelector, elementSelector, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, TKey, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.ToLookup(keySelector, elementSelector, ToEqualityComparer(equals, getHashCode));&lt;/p&gt;
&lt;h2&gt;Value queries&lt;/h2&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;.NET provides basic aggregation queries, including Sum/Average/Max/Min queries. In reality, it is also common to calculate the variance, standard deviation, and percentile. The following VariancePopulation/VarianceSample/Variance queries are equivalent to Excel VAR.P/VAR.S/VAR functions:&lt;/p&gt;
&lt;p&gt;public static double VariancePopulation&amp;lt;TSource, TKey&amp;gt;( // Excel VAR.P function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double[] keys = source.Select(key =&amp;gt; keySelector(key).ToDouble(formatProvider)).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double mean = keys.Average();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keys.Sum(key =&amp;gt; (key - mean) * (key - mean)) / keys.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double VarianceSample&amp;lt;TSource, TKey&amp;gt;( // Excel VAR.S function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double[] keys = source.Select(key =&amp;gt; keySelector(key).ToDouble(formatProvider)).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double mean = keys.Average();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keys.Sum(key =&amp;gt; (key - mean) * (key - mean)) / (keys.Length - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double Variance&amp;lt;TSource, TKey&amp;gt;( // Excel VAR function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.VarianceSample(keySelector, formatProvider);&lt;/p&gt;
&lt;p&gt;And the following StandardDeviationPopulation/StabdardDeviationSample/StabdardDeviation queries implements Excel STDEV.P/STDEV.S/STDEV functions:&lt;/p&gt;
&lt;p&gt;public static double StandardDeviationPopulation&amp;lt;TSource, TKey&amp;gt;( // Excel STDEV.P function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Math.Sqrt(source.VariancePopulation(keySelector, formatProvider));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double StandardDeviationSample&amp;lt;TSource, TKey&amp;gt;( // Excel STDEV.S function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Math.Sqrt(source.VarianceSample(keySelector, formatProvider));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double StandardDeviation&amp;lt;TSource, TKey&amp;gt;( // Excel STDEV function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Math.Sqrt(source.Variance(keySelector, formatProvider));&lt;/p&gt;
&lt;p&gt;And the following PercentileExclusive/PercentileInclusive/Percentile implement Excel PERCENTILE.EXC/PERCENTILE.INC/PERCENTILE functions:&lt;/p&gt;
&lt;p&gt;public static double PercentileExclusive&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE.EXC function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double percentile,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt; comparer = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey[] orderedKeys = source.Select(keySelector).OrderBy(key =&amp;gt; key, comparer).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int length = orderedKeys.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (percentile &amp;lt; (double)1 / length || percentile &amp;gt; 1 - (double)1 / (length + 1))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nameof(percentile),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{nameof(percentile)} must be in the range between (1 / source.Count()) and (1 - 1 / source.Count()).&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double index = percentile * (length + 1) - 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int integerComponentOfIndex = (int)index;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double decimalComponentOfIndex = index - integerComponentOfIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double keyAtIndex = orderedKeys[integerComponentOfIndex].ToDouble(formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double keyAtNextIndex = orderedKeys[integerComponentOfIndex + 1].ToDouble(formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double PercentileInclusive&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE.INC function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double percentile,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt; comparer = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey[] orderedKeys = source.Select(keySelector).OrderBy(key =&amp;gt; key, comparer).ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int length = orderedKeys.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double index = percentile * (length - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int integerComponentOfIndex = (int)index;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double decimalComponentOfIndex = index - integerComponentOfIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double keyAtIndex = orderedKeys[integerComponentOfIndex].ToDouble(formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (integerComponentOfIndex &amp;gt;= length - 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keyAtIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double keyAtNextIndex = orderedKeys[integerComponentOfIndex + 1].ToDouble(formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double Percentile&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double percentile,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt; comparer = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IFormatProvider formatProvider = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TKey : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return PercentileInclusive(source, keySelector, percentile, comparer, formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Quantifiers&lt;/h3&gt;
&lt;p&gt;string has a very useful IsNullOrEmpty method, and here is the LINQ version:&lt;/p&gt;
&lt;p&gt;public static bool IsNullOrEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;&lt;/p&gt;
&lt;p&gt;source == null || !source.Any();&lt;/p&gt;
&lt;p&gt;Contains compares the objects to determine the existance, so it can accept IEqualityComparer&amp;lt;T&amp;gt; parameter. It can be overloaded with functions for convenience:&lt;/p&gt;
&lt;p&gt;public static bool Contains&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Contains(value, ToEqualityComparer(equals, getHashCode));&lt;/p&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;SequentialEqual compares the objects as well, so it also accepts IEqualityComparer&amp;lt;T&amp;gt;. It can be overloaded with functions:&lt;/p&gt;
&lt;p&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt;equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;first.SequenceEqual(second, ToEqualityComparer(equals, getHashCode));&lt;/p&gt;
&lt;h3&gt;List&lt;/h3&gt;
&lt;p&gt;IndexOf is similar to List&amp;lt;T&amp;gt;.IndexOf. It finds the index of first occurrence of the specified value. –1 is returned if the specified value is not found:&lt;/p&gt;
&lt;p&gt;public static int IndexOf&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (comparer.Equals(sourceValue, value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return index;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;LastIndexOf is similar to List&amp;lt;T&amp;gt;.LastIndexOf. It finds the index of last occurrence of the specified value:&lt;/p&gt;
&lt;p&gt;public static int LastIndexOf&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastIndex = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (comparer.Equals(sourceValue, value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastIndex = index;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return lastIndex;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, here are the functional overloads of IndexOf and LastIndexOf:&lt;/p&gt;
&lt;p&gt;public static int IndexOf&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.IndexOf(value, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int LastIndexOf&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.LastIndexOf(value, ToEqualityComparer(equals, getHashCode));&lt;/p&gt;
&lt;h2&gt;Void queries&lt;/h2&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;EnumerableEx.ForEach from Ix is very handy. It can fluently execute the query and process the results. It works like foreach statement, but it does not support breaking the iterations like the break statement in foreach statement. So here is an improved EnumerableX.ForEach, with a slightly different callback function:&lt;/p&gt;
&lt;p&gt;public static void ForEach&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; onNext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!onNext(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The callback function is of type TSource -&amp;gt; bool. When its output is true, the iteration continues; when its output is false, ForEach stops execution. And the indexed overload is:&lt;/p&gt;
&lt;p&gt;public static void ForEach&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; onNext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!onNext(value, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The last overload does not accept the callback function. It just iterates the source sequence:&lt;/p&gt;
&lt;p&gt;public static void ForEach(this IEnumerable source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator iterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext()) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(iterator as IDisposable)?.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It can be used to just execute a LINQ query and ignore all query results.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter demonstrates how to implement custom LINQ to Objects queries, including generation queries, list-API-like queries, aggregation queries to compute variance, standard deviation, and percentile, and also functional overloads for the standard ordering, grouping, join, set, conversion, quantifier, and equality queries that compares objects, and many more.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (6) Advanced Queries in Interactive Extensions (Ix)</title><link>https://dixin.github.io/posts/linq-to-objects-interactive-extensions-ix/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-interactive-extensions-ix/</guid><description>The previous 2 chapters discussed the LINQ to Objects standard queries. Besides these built-in queries provided by System.Linq.Enumerable type in .NET Standard, Microsoft also provides additional LINQ</description><pubDate>Sat, 06 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous 2 chapters discussed the LINQ to Objects standard queries. Besides these built-in queries provided by System.Linq.Enumerable type in .NET Standard, Microsoft also provides additional LINQ to Objects queries through the System.Interactive NuGet package (aka Interactive Extensions library, or Ix). Ix has a System.Linq.EnumerableEx type with the following queries:&lt;/p&gt;
&lt;p&gt;· Sequence queries: output a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution)&lt;/p&gt;
&lt;p&gt;o Generation: Defer, Create, Return, Repeat&lt;/p&gt;
&lt;p&gt;o Filtering: IgnoreElements*, DistinctUntilChanged&lt;/p&gt;
&lt;p&gt;o Mapping: SelectMany, Scan, Expand&lt;/p&gt;
&lt;p&gt;o Concatenation: Concat, StartWith&lt;/p&gt;
&lt;p&gt;o Set: Distinct&lt;/p&gt;
&lt;p&gt;o Partitioning: TakeLast*, SkipLast**&lt;/p&gt;
&lt;p&gt;o Conversion: Hide&lt;/p&gt;
&lt;p&gt;o Buffering: Buffer*, Share, Publish, Memoize&lt;/p&gt;
&lt;p&gt;o Exception handling: Throw, Catch, Finally, OnErrorResumeNext, Retry&lt;/p&gt;
&lt;p&gt;o Control flow: If, Case, Using, While, DoWhile, Generate, For&lt;/p&gt;
&lt;p&gt;o Iteration: Do&lt;/p&gt;
&lt;p&gt;· Value queries: output a single value (immediate execution)&lt;/p&gt;
&lt;p&gt;o Aggregation: Min, Max, MinBy, MaxBy&lt;/p&gt;
&lt;p&gt;o Quantifiers: isEmpty&lt;/p&gt;
&lt;p&gt;· Void queries: no output (immediate execution)&lt;/p&gt;
&lt;p&gt;o Iteration: ForEach&lt;/p&gt;
&lt;p&gt;Many of these queries are handy and useful. However, there is not much documentation provided from Microsoft, except the APIs’ XML comments. This chapter discusses these queries by either providing examples and/or demonstrating their internal implementation, whichever is more intuitive.&lt;/p&gt;
&lt;p&gt;Similar to Enumerable queries, the EnumerableEx queries with a sequence output implements deferred execution, and the other queries implements immediate execution. For the sequence queries, the ones marked with * implement eager evaluation, and the unmarked queries implements lazy evaluation. The SkipLast query marked with ** is slightly different, it can be fully eager evaluation or partially eager evaluation, which is discussed later.&lt;/p&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;p&gt;Similar to the standard sequence queries, the Ix sequence queries follow iterator pattern to implement deferred execution. Many of them uses yield statement for generator, and some queries are implemented by the composition of other standard and Ix queries.&lt;/p&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Defer accepts a sequence factory function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Defer&amp;lt;TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; enumerableFactory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TResult value in enumerableFactory())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And it defers the execution of the factory function:&lt;/p&gt;
&lt;p&gt;internal static void Defer(IEnumerable&amp;lt;string&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; Distinct()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Instantiate hash set.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;string&amp;gt; hashSet = new HashSet&amp;lt;string&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source.Where(hashSet.Add); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; distinct1 = Distinct() // Hash set is instantiated.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(@string =&amp;gt; @string.Length &amp;gt; 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; distinct2 = EnumerableEx.Defer(Distinct) // Hash set is not instantiated.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(@string =&amp;gt; @string.Length &amp;gt; 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, Create accepts an iterator factory function, and delays its execution:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Create&amp;lt;TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IEnumerator&amp;lt;TResult&amp;gt;&amp;gt; getEnumerator)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TResult&amp;gt; iterator = getEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator.Current; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload of Create is not so intuitive:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(Action&amp;lt;IYielder&amp;lt;T&amp;gt;&amp;gt; create);&lt;/p&gt;
&lt;p&gt;It accepts a callback function of type System.Linq.IYielder&amp;lt;T&amp;gt; –&amp;gt; void. IYielder&amp;lt;T&amp;gt; has 2 methods, Return and Break, representing the 2 forms of yield statement.&lt;/p&gt;
&lt;p&gt;public interface IYielder&amp;lt;in T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IAwaitable Return(T value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IAwaitable Break();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In C#, lambda expression does not support yield statements, compiling the following code causes error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression.&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Create()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; sequenceFactory = () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; sequence = sequenceFactory();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequence.WriteLines(); // 0 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here Create provides a way to virtually use the yield statements in lambda expression:&lt;/p&gt;
&lt;p&gt;internal static void Create()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;IYielder&amp;lt;int&amp;gt;&amp;gt; sequenceFactory = async yield =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;await yield.Return(0); // yield return 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;await yield.Return(1); // yield return 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;await yield.Break(); // yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;await yield.Return(2); // yield return 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;sequence = EnumerableEx.Create(sequenceFactory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequence.WriteLines(); // 0 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;IYielder&amp;lt;T&amp;gt; is a good invention before C# 7.0 introduces local function, but at runtime, it can have unexpected iterator behaviour when used with more complex control flow, like try-catch statement. Please avoid using this query. In the above examples, define local function to use yield return statement:&lt;/p&gt;
&lt;p&gt;internal static void Create()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;SequenceFactory()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 0; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;sequence = SequenceFactory();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sequence.WriteLines(); // 0 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Return just wraps value in a singleton sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Return&amp;lt;TResult&amp;gt;(TResult value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is called Return, because “return” is a term used in functional languages like Haskell, which means to wrap something in a monad (Monad is discussed in detail in the Category Theory chapters). However, in C# “return” means the current function member gives control to its caller with an optional output. It could be more consistent with .NET naming convention if this function is named as FromValue, similar to Task.FromResult, Task.FromException, DateTime.FromBinary, DateTimeOffset.FromFileTime, TimeSpan.FromSeconds, RegistryKey.FromHandle, etc.&lt;/p&gt;
&lt;p&gt;Repeat generates an infinite sequence by repeating a value forever:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Another overload repeats values in the specified sequence. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Repeat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int? count = null)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i&amp;lt; count; i++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When count is not provided, it repeats the values of the source sequence forever.&lt;/p&gt;
&lt;h3&gt;Filtering&lt;/h3&gt;
&lt;p&gt;IgnoreElements filters out all values from the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; IgnoreElements&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source) { } // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DistinctUntilChanged removes the continuous duplication:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void DistinctUntilChanged()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = new int[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;0, 0, 0, /* Change. */ 1, 1, /* Change. */ 0, 0, /* Change. */ 2, /* Change. */ 1, 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.DistinctUntilChanged().WriteLines(); // 0 1 0 2 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Mapping&lt;/h3&gt;
&lt;p&gt;A SelectMany overload is provided to map source sequence’s each value to the other sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TOther&amp;gt; SelectMany&amp;lt;TSource, TOther&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IEnumerable&amp;lt;TOther&amp;gt; other) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.SelectMany(value =&amp;gt; other);&lt;/p&gt;
&lt;p&gt;Scan accepts the same parameters as Aggregate. The difference is, Aggregate outputs one final accumulation step’s result, Scan returns a sequence of all accumulation steps’ results. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Scan&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource accumulate = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return accumulate = func(accumulate, iterator.Current); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TAccumulate&amp;gt; Scan&amp;lt;TSource, TAccumulate&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Select(value =&amp;gt; seed = func(seed, value));&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Scan()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int finalProduct = Int32Source().Aggregate((product, int32) =&amp;gt; product * int32).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ((((-1 * 1) * 2) * 3) * -4) =&amp;gt; 24.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; allProducts = Int32Source().Scan((product, int32) =&amp;gt; product * int32).WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ((((-1 * 1) * 2) * 3) * -4) =&amp;gt; { -1, -2, -6, 24 }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Expand maps source values with the selector, then maps the result values with the selector, and keeps going on.&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Expand&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;In the following example, selector maps each value to a singleton sequence:&lt;/p&gt;
&lt;p&gt;internal static void ExpandSingle()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Expand(int32 =&amp;gt; EnumerableEx.Return(int32 * int32))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(25)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 2 3 4, map each int32 to { int32 * int32 } =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 4 9 16, map each int32 to { int32 * int32 }: =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 16 81 256, map each int32 to { int32 * int32 } =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 256 6561 65536, map each int32 to { int32 * int32 } =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 65536 43046721 4294967296, ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The mapping can go on forever and results an infinite sequence. If selector maps each value to a sequence with more than one values, then the result sequences grows rapidly:&lt;/p&gt;
&lt;p&gt;internal static void ExpandMuliple()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Expand(int32 =&amp;gt; Enumerable.Repeat(int32, 2))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(75)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 2 3 4 =&amp;gt; map each int32 to { int32, int32 }:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 0 1 1 2 2 3 3 4 4 =&amp;gt; map each int32 to { int32, int32 }:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 =&amp;gt; map each int32 to { int32, int32 }:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 =&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If selector maps each value to empty sequence, the expanding ends after all source values are iterated:&lt;/p&gt;
&lt;p&gt;internal static void ExpandNone()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Expand(int32 =&amp;gt; Enumerable.Empty&amp;lt;int&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(100)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 2 3 4 =&amp;gt; map each int32 to { }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;2 more overloads of Concat is provided to concatenate any number of sequences:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sources.SelectMany(source =&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.Concat();&lt;/p&gt;
&lt;p&gt;By concatenating the sequences one after another, Concat flattens a hierarchical 2-level-sequence into a flat 1-level-sequence, which works the same as SelectMany.&lt;/p&gt;
&lt;p&gt;StartWith prepend the specified values to the source sequence. It is similar to Prepend. Prepend accepts a single prefix value, but StartWith supports multiple prefix values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; StartWith&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, params TSource[] values) =&amp;gt; values.Concat(source);&lt;/p&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;An overload of Distinct is provided to accept a key selector function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TKey&amp;gt;hashSet = new HashSet&amp;lt;TKey&amp;gt;(comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (hashSet.Add(keySelector(value)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Skip/Take skips/takes the specified number of values at the beginning of the source sequence. In contrast, SkipLast/TakeLast skips/takes the specified number of values at the end of the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void SkipLastTakeLast()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] skipFirst2 = Enumerable.Range(0, 5).Skip(2).ToArray(); // 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] skipLast2 = Enumerable.Range(0, 5).SkipLast(2).ToArray(); // 0 1 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] takeFirst2 = Enumerable.Range(0, 5).Take(2).ToArray(); // 0 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] takeLast2 = Enumerable.Range(0, 5).TakeLast(2).ToArray(); // 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The implementation of SkipLast/TakeLast is very interesting. As already discussed, Take implements lazy evaluation. However, TakeLast has to pull all values to know which are the tail values of the source sequence. So TakeLast implements eager evaluation, and uses a queue to store the tail values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; TakeLastGGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Queue&amp;lt;TSource&amp;gt;lastValues = new Queue&amp;lt;TSource&amp;gt;(count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (lastValues.Count &amp;gt;= count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastValues.Dequeue();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastValues.Enqueue(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (lastValues.Count&amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return lastValues.Dequeue(); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return TakeLastGGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SkipLast also uses a queue to store the tail values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; SkipLastGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Queue&amp;lt;TSource&amp;gt;lastValues = new Queue&amp;lt;TSource&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastValues.Enqueue(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (lastValues.Count &amp;gt; count) // Can be lazy, eager, or between.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return lastValues.Dequeue(); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return SkipLastGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It uses count as the max length of the queue. When SkipLast starts to execute, it evaluates values to fill the queue. When the queue is full, each new value is enqueued, and the head value of the queue is dequeued and yielded. So, at the end of query execution, the values still stored in the queue are exactly the last values to skip. If count is equal to or greater than the source sequence’s value count, when executing query, all values are pulled from the source sequence and stored in the queue, and nothing is yielded to the caller, which is fully eager evaluation similar to IgnoreElements. If count is less than the source’s value count, when executing query, some values are pulled from the source sequence to fill the queue, then values are yielded, which can be viewed as partially eager evaluation. When count is 0, it does not skip anything, just simply yield each source value, which is like lazy evaluation. So SkipLast’s eagerness/laziness depends on the count of values to skip.&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Hide has the same signature as AsEnumerable. As previously demonstrated, AsEnumerable simply outputs the source sequence itself to caller. Hide returns a new generator to hide the source sequence from the caller:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Hide&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The difference is, the output sequence of AsEnumerable can be converted back to the original type, which the output sequence of Hide cannot, since it is a newly constructed generator:&lt;/p&gt;
&lt;p&gt;internal static void Hide()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt;source = new List&amp;lt;int&amp;gt;() { 1, 2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;readWrite = source.AsEnumerable();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(source, readWrite).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((List&amp;lt;int&amp;gt;)readWrite).Reverse(); // List&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((List&amp;lt;int&amp;gt;)readWrite).Add(3); // List&amp;lt;T&amp;gt;.Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; readOnly = source.Hide();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(source, readOnly).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Buffering&lt;/h3&gt;
&lt;p&gt;Buffer segments the source sequence into smaller lists:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IList&amp;lt;TSource&amp;gt;&amp;gt; Buffer&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count, int skip);&lt;/p&gt;
&lt;p&gt;Here count is the length of each smaller list, and skip is the offset to start the next list. For example:&lt;/p&gt;
&lt;p&gt;internal static void Buffer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers1 = Enumerable.Range(0, 5).Buffer(2, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers2 = Enumerable.Range(0, 5).Buffer(2, 2); // Equivalent to Buffer(2).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// { 0, 1 }, { 2, 3 }, { 4 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers3 = Enumerable.Range(0, 5).Buffer(2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// { 0, 1 }, { 3, 4 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Buffer implements eager evaluation. it creates all the smaller lists when the first list is pulled.&lt;/p&gt;
&lt;p&gt;The other overload without skip uses count as skip:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IList&amp;lt;TSource&amp;gt;&amp;gt; Buffer&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);&lt;/p&gt;
&lt;p&gt;In above example, calling Buffer(2, 2) is equivalent to Buffer(2).&lt;/p&gt;
&lt;p&gt;Share buffers the values of a sequence and share them with several iterators:&lt;/p&gt;
&lt;p&gt;public static IBuffer&amp;lt;TSource&amp;gt; Share&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;The output type System.Linq.IBuffer&amp;lt;T&amp;gt; is a composition of IEnumerable&amp;lt;T&amp;gt; and IDisposable:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IBuffer&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IDisposable { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;By default, an IEnumerable&amp;lt;T&amp;gt; sequence’s multiple iterators are independent from each other. When these iterators are called, callers pull independent values from each iterator. In contrast, multiple shared iterators work as if they are the same single iterator:&lt;/p&gt;
&lt;p&gt;internal static void Share()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;sequence = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;independentIteratorA = sequence.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;independentIteratorB = sequence.GetEnumerator(); // A|B|C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 0| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorB.MoveNext(); independentIteratorB.Current.WriteLine(); // |0|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 1| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; independentIteratorC = sequence.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorC.MoveNext(); independentIteratorC.Current.WriteLine(); // | |0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 2| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorB.MoveNext(); independentIteratorB.Current.WriteLine(); // |1|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 3| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IBuffer&amp;lt;int&amp;gt; share = Enumerable.Range(0, 5).Share();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;sharedIterator1 = share.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;sharedIterator2 = share.GetEnumerator(); // A|B|C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator1.MoveNext(); sharedIterator1.Current.WriteLine(); // 0| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator2.MoveNext(); sharedIterator2.Current.WriteLine(); // |1|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator1.MoveNext(); sharedIterator1.Current.WriteLine(); // 2| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; sharedIterator3 = share.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator3.MoveNext(); sharedIterator3.Current.WriteLine(); // | |3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;share.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator1.MoveNext(); // ObjectDisposedException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator2.MoveNext(); // ObjectDisposedException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sharedIterator3.MoveNext(); // ObjectDisposedException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When pulling values with multiple independent iterators, each value can be pulled multiple times. When pulling values with multiple shared iterators, each value can only be pulled once. And IBuffer&amp;lt;T&amp;gt;.Dispose terminates the sharing. After calling Dispose, all shared iterators’ MoveNext throws ObjectDisposedException.&lt;/p&gt;
&lt;p&gt;The other overload accepts a selector function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Share&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create(() =&amp;gt; selector(source.Share()).GetEnumerator());&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void ConcatShared()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source1 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source1.Concat(source1).WriteLines(); // 0 1 2 3 4 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source2.Concat(source2).WriteLines(); // 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source3.Share(source =&amp;gt; source.Concat(source)).WriteLines(); // 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above 2 kinds of Share usage are equivalent. As already discussed, Concat can be desugared as:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;first, IEnumerable&amp;lt;TSource&amp;gt; second)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator1 = first.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator1.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator1.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator2 = second.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator2.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So that the above 3 Concat calls can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;internal static void DesugaredConcatShared()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source1 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;Concat1() // source1.Concat(source1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; independentIterator1 = source1.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (independentIterator1.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return independentIterator1.Current; // Yield 0 1 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; independentIterator2 = source1.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (independentIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return independentIterator2.Current; // Yield 0 1 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Concat1().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;Concat2() // source2.Concat(source2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source2.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator1.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sharedIterator1.Current; // Yield 0 1 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source2.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sharedIterator2.Current; // Yield nothing.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Concat2().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source3 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;Concat3() // source3.Share(source =&amp;gt; source.Concat(source))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source = source3.Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator1.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sharedIterator1.Current; // Yield 0 1 2 3 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sharedIterator2.Current; // Yield nothing.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Concat3().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When Concat is executed, if values are pulled from 2 independent iterators, both iterators yield all source values; if values are pulled from 2 shared iterators. only the first iterator yields all source values, and the second iterator yields nothing. Another example is Zip:&lt;/p&gt;
&lt;p&gt;internal static void ZipShared()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source1 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source1.Zip(source1, ValueTuple.Create).WriteLines(); // (0, 0) (1, 1) (2, 2) (3, 3) (4, 4)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source2.Zip(source2, ValueTuple.Create).WriteLines(); // (0, 1) (2, 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source3.Share(source =&amp;gt; source.Zip(source, ValueTuple.Create)).WriteLines(); // (0, 1) (2, 3).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, the above 3 Zip calls can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;internal static void DesugaredZipShared()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source1 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;(int, int)&amp;gt; Zip1()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; independentIterator1 = source1.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; independentIterator2 = source1.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (independentIterator1.MoveNext() &amp;amp;&amp;amp; independentIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (independentIterator1.Current, independentIterator2.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Yield (0, 0) (1, 1) (2, 2) (3, 3) (4, 4).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Zip1().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;(int, int)&amp;gt; Zip2()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source2.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source2.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator1.MoveNext() &amp;amp;&amp;amp; sharedIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (sharedIterator1.Current, sharedIterator2.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Yield (0, 1) (2, 3).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Zip2().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source3 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;(int, int)&amp;gt; Zip3()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source = source3.Share())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sharedIterator1.MoveNext() &amp;amp;&amp;amp; sharedIterator2.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (sharedIterator1.Current, sharedIterator2.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// yields (0, 1) (2, 3).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Zip3().WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Publish has the same signatures as Share:&lt;/p&gt;
&lt;p&gt;public static IBuffer&amp;lt;TSource&amp;gt; Publish&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Publish&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;selector);&lt;/p&gt;
&lt;p&gt;It also buffers the values in a different way, so each iterator yields all remainder values:&lt;/p&gt;
&lt;p&gt;internal static void Publish()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; publish = Enumerable.Range(0, 5).Publish())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;remainderIteratorA = publish.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// remainderIteratorA: 0 1 2 3 4. A|B|C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 0| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 1| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 2| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; remainderIteratorB = publish.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// remainderIteratorB: 3 4. | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorB.MoveNext(); remainderIteratorB.Current.WriteLine(); // |3|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 3| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; remainderIteratorC = publish.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// remainderIteratorC: 4. | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorB.MoveNext(); remainderIteratorB.Current.WriteLine(); // |4|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 4| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remainderIteratorC.MoveNext(); remainderIteratorC.Current.WriteLine(); // | |4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Memoize (not Memorize) simply buffers all values:&lt;/p&gt;
&lt;p&gt;public static IBuffer&amp;lt;TSource&amp;gt; Memoize&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Memoize&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;selector);&lt;/p&gt;
&lt;p&gt;The term memoize/memoization means buffering the function call result, so that when the same call happens again, the buffered result can be returned. Its multiple iterators work like independent, but each value is only pulled once and is buffered for reuse:&lt;/p&gt;
&lt;p&gt;internal static void Memoize()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; memoize = Enumerable.Range(0, 5).Memoize())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt;bufferIteratorA = memoize.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// bufferIteratorA: 0 1 2 3 4. A|B|C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 0| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 1| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 2| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; bufferIteratorB = memoize.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// bufferIteratorB: 0 1 2 3 4. | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); // |0|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 3| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;int&amp;gt; bufferIteratorC = memoize.GetEnumerator(); // | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// bufferIteratorC: 0 1 2 3 4. | |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); // |1|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 4| |
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorC.MoveNext(); bufferIteratorC.Current.WriteLine(); // | |0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorC.MoveNext(); bufferIteratorC.Current.WriteLine(); // | |1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); // |2|
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There 2 more overloads accept a readerCount to specify how many times can the buffered values be reused:&lt;/p&gt;
&lt;p&gt;public static IBuffer&amp;lt;TSource&amp;gt; Memoize&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int readerCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Memoize&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int readerCount, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;When exceeding the readerCount, an InvalidOperationException is thrown:&lt;/p&gt;
&lt;p&gt;internal static void MemoizeWithReaderCount()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IBuffer&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5).Memoize(2))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] reader1 = source1.ToArray(); // First full iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] reader2 = source1.ToArray(); // Second full iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] reader3 = source1.ToArray(); // Third full iteration: InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source2 = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Memoize(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readerCount: 2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;selector: source =&amp;gt; source // First full iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(source) // Second full iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(source)) // Third full iteration: InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Exception handling&lt;/h3&gt;
&lt;p&gt;The exception queries address some exception related scenarios for IEnumerable&amp;lt;T&amp;gt;. Throw query just throws the specified exception when executed:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Throw&amp;lt;TResult&amp;gt;(Exception exception)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw exception;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The yield break statement at the end is required for deferred execution. Without the yield break statement, the specified exception is thrown immediately when Throw is called. With the yield break statement, a generator is returned when Throw is called, and the specified exception is thrown when trying to pull value from the returned generator for the first time. For example:&lt;/p&gt;
&lt;p&gt;internal static void Throw()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;@throw = EnumerableEx.Throw&amp;lt;int&amp;gt;(new OperationCanceledException());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;query = Enumerable.Range(0, 5).Concat(@throw); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int value in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (OperationCanceledException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;exception.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0 1 2 3 4 System.OperationCanceledException: The operation was canceled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Catch accepts a source sequence and an exception handler function. When the query is executed, it pulls and yields each value from source sequence. If there is no exception of the specified type thrown during the evaluation, the handler is not called. If any exception of the specified type is thrown, it calls the exception handler with the exception. The handler returns a sequence, whose values are then pulled and yielded. So, Catch’s concept can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; CatchWithYield&amp;lt;TSource, TException&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TException, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; handler)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TException : Exception
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (TException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in handler(exception) ?? Empty&amp;lt;TSource&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;However, C# does not support yield statement inside try-catch statement. The above code cannot be compiled. The solution is to desugar the foreach statement to a while loop for iterator. Then the try-catch statement can go inside the loop, and only contains iterator’s MoveNext and Current calls, and the yield statement can go outside the try-catch statement.&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource, TException&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TException, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; handler)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TException : Exception
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TException firstException = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try // Only MoveNext and Current are inside try-catch.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // Stops while loop at the end of iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (TException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstException = exception;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // Stops while loop if TException is thrown.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution, outside try-catch.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (firstException != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in handler(firstException) ?? Empty&amp;lt;TSource&amp;gt;())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And here is a simple example:&lt;/p&gt;
&lt;p&gt;internal static void CatchWithHandler()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; @throw = EnumerableEx.Throw&amp;lt;string&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OperationCanceledException());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;@catch = @throw.Catch&amp;lt;string, OperationCanceledException&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;exception =&amp;gt; EnumerableEx.Return($&quot;Handled {exception.GetType().Name}: {exception.Message}&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@catch.WriteLines(); // Handled OperationCanceledException: The operation was canceled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other Catch overloads accepts multiple sequences, and outputs a single sequence. The idea is, when executed, it tries to pull and yield values of the first source sequence. if there is no exception, it stops execution; If any exception is thrown, it tries to pull and yield the values of the second source sequence, and so on; When stopping the evaluation, if there is any exception from the evaluation of the last sequence. If yes, it re-throws that exception. The concept is:&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; CatchWithYield&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Exception lastException = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastException = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // Stops if no exception from current sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (Exception exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastException = exception;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Continue with next sequence if there is exception.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (lastException != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw lastException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, the above code cannot be compiled because yield statement cannot be used with try-catch statement. So previous desugared while-try-catch-yield pattern can be used:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Exception lastException = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastException = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try // Only MoveNext and Current are inside try-catch.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // Stops while loop at the end of iteration.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (Exception exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastException = exception;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // Stops while loop if TException is thrown.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution, outside try-catch.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (lastException == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break; // If no exception, stops pulling the next source; otherwise, continue.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (lastException != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw lastException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.Catch();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }.Catch();&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Catch()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;scanWithException = Enumerable.Repeat(0, 5).Scan((a, b) =&amp;gt; a / b); // Divide by 0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; range = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;castWithException = new object[] { 5, &quot;a&quot; }.Cast&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; source1 = new IEnumerable&amp;lt;int&amp;gt;[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;scanWithException, // Executed, with DivideByZeroException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;range, // Executed, without exception.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;castWithException // Not executed.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source1.Catch().WriteLines(); // 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; source2 = new IEnumerable&amp;lt;int&amp;gt;[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;scanWithException, // Executed, with DivideByZeroException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;castWithException // Executed, with InvalidCastException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source2.Catch().WriteLines(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (InvalidCastException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;exception.WriteLine(); // System.InvalidCastException: Specified cast is not valid.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides Throw and Catch, there is also Finally query. Finally is very intuitive:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Finally&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action finalAction)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finalAction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above code can be compiled because yield statement is allowed in the try block of try-finally statement.&lt;/p&gt;
&lt;p&gt;OnErrorResumeNext is similar to Concat, but it ignores any exception when evaluating values from each sequence. The idea is:&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNextWithYield&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Once again, this can be implemented with the desugared while-try-catch-yield pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.OnErrorResumeNext();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }.OnErrorResumeNext();&lt;/p&gt;
&lt;p&gt;Retry query tries to yield the source values. If there is an exception thrown, it retries to yield the values again from the beginning of the source sequence. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Retry&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, int? retryCount = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Return(source).Repeat(retryCount).Catch();&lt;/p&gt;
&lt;p&gt;If retryCount is not provided, it retries forever.&lt;/p&gt;
&lt;h3&gt;Control flow&lt;/h3&gt;
&lt;p&gt;The If/Case/Using/While/DoWhile/Generate/For queries implements the control flows as fluent LINQ query. If represents the if-else statement. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; If&amp;lt;TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt;condition, IEnumerable&amp;lt;TResult&amp;gt; thenSource, IEnumerable&amp;lt;TResult&amp;gt; elseSource = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Defer(() =&amp;gt; condition() ? thenSource : elseSource ?? Enumerable.Empty&amp;lt;TResult&amp;gt;());&lt;/p&gt;
&lt;p&gt;Case represents the switch-case statement. It accepts a selector function as the key factory, and a dictionary of key-sequence pairs, where each key represents a case label of the switch statement. When Case query is executed, the selector function is called to get a key. If the dictionary contains that key, then the matching sequence is the query output; otherwise, a default sequence is the query output:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Case&amp;lt;TValue, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TValue&amp;gt;selector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IDictionary&amp;lt;TValue, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;sources,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt;defaultSource = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Defer(() =&amp;gt; sources.TryGetValue(selector(), out IEnumerable&amp;lt;TResult&amp;gt;result)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? result
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;: (defaultSource ?? Enumerable.Empty&amp;lt;TResult&amp;gt;()));&lt;/p&gt;
&lt;p&gt;Using represents the using statement:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Using&amp;lt;TSource, TResource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TResource&amp;gt;resourceFactory, Func&amp;lt;TResource, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; enumerableFactory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where TResource : IDisposable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (TResource resource = resourceFactory())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in enumerableFactory(resource))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;While represents the while loop:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; While&amp;lt;TResult&amp;gt;(Func&amp;lt;bool&amp;gt; condition, IEnumerable&amp;lt;TResult&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (condition())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TResult value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DoWhile represents the do-while loop:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; DoWhile&amp;lt;TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TResult&amp;gt; source, Func&amp;lt;bool&amp;gt; condition) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.Concat(While(condition, source));&lt;/p&gt;
&lt;p&gt;Generate represents the for loop:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Generate&amp;lt;TState, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TState initialState,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TState, bool&amp;gt; condition,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TState, TState&amp;gt; iterate,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TState, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (TState state = initialState; condition(state); state = iterate(state))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(state); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For also works the same as SelectMany. Its implementation is equivalent to:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; For&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;resultSelector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.SelectMany(resultSelector);&lt;/p&gt;
&lt;p&gt;It can be viewed as foreach statement – for each value in the source, call the resultSelector function and yields all results in the function’s output sequence. I am not sure why the 2 above queries are named as Generate and For.&lt;/p&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;Do does not transform the data in any way. It simply pulls source values just like Hide. It also accepts 3 callback functions, onNext, onError, and onCompleted. When each source value is pulled, onNext is called with the value. When exception is thrown for pulling source value, onError is called with the exception. After all source values are pulled successfully without exception, onCompleted is called. Its idea is:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Do&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;TSource&amp;gt; onNext, Action&amp;lt;Exception&amp;gt; onError = null, Action onCompleted = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (Exception exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onError?.Invoke(exception);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onCompleted?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Once again, the yield statement does not work with try-catch statement. The above idea can be implemented with the desugared while-try-catch-yield pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Do&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;TSource&amp;gt;onNext, Action&amp;lt;Exception&amp;gt;onError = null, Action onCompleted = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (Exception exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onError?.Invoke(exception);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution, outside try-catch.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onCompleted?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Do is very useful for logging and tracing LINQ queries, for example:&lt;/p&gt;
&lt;p&gt;internal static void Do()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(-5, 10).Do(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext: value =&amp;gt; $&quot;{nameof(Enumerable.Range)} yields {value}.&quot;.WriteLine(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onCompleted: () =&amp;gt; $&quot;{nameof(Enumerable.Range)} completes.&quot;.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(value =&amp;gt; value &amp;gt; 0).Do(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext: value =&amp;gt; $&quot;{nameof(Enumerable.Where)} yields {value}.&quot;.WriteLine(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onCompleted: () =&amp;gt; $&quot;{nameof(Enumerable.Where)} completes.&quot;.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.TakeLast(2).Do(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext: value =&amp;gt; $&quot;{nameof(EnumerableEx.TakeLast)} yields {value}.&quot;.WriteLine(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onCompleted: () =&amp;gt; $&quot;{nameof(EnumerableEx.TakeLast)} completes.&quot;.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(value =&amp;gt; $&quot;Composited query yields result {value}.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields -5.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields -4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields -3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields -2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields -1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields 0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where yields 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where yields 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where yields 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range yields 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where yields 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Range completes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where completes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TakeLast yields 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Composited query yields result 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TakeLast yields 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Composited query yields result 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TakeLast completes.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since System.IObserver&amp;lt;T&amp;gt; is the composition of above onNext, onError, onCompleted functions:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IObserver&amp;lt;in T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void OnCompleted();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void OnError(Exception error);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void OnNext(T value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Do also has an overload accepting an observer:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Do&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, IObserver&amp;lt;TSource&amp;gt; observer) =&amp;gt;&lt;/p&gt;
&lt;p&gt;Do(source, observer.OnNext, observer.OnError, observer.OnCompleted);&lt;/p&gt;
&lt;h2&gt;Value queries&lt;/h2&gt;
&lt;p&gt;Ix provides a few queries for finding the extremum as well as empty test:&lt;/p&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;The additional overloads of Max/Min accept a comparer function, and return the first maximum/minimum value:&lt;/p&gt;
&lt;p&gt;public static TSource Max&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Min&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IComparer&amp;lt;TSource&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;As fore mentioned, to use the standard Max/Min with a source sequence, exception is thrown if the source type does not implement IComparable or IComparable&amp;lt;T&amp;gt;, which is a problem when the source type cannot be modified to add IComparable or IComparable&amp;lt;T&amp;gt; implementation:&lt;/p&gt;
&lt;p&gt;internal static void MaxMinGeneric()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character maxCharacter = Characters().Max().WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character minCharacter = Characters().Min().WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The overloads with comparer does not have such requirement:&lt;/p&gt;
&lt;p&gt;internal static void MaxMin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character maxCharacter = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Max(Comparer&amp;lt;Character&amp;gt;.Create((character1, character2) =&amp;gt; string.Compare(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;character1.Name, character2.Name, StringComparison.OrdinalIgnoreCase)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character minCharacter = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Max(Comparer&amp;lt;Character&amp;gt;.Create((character1, character2) =&amp;gt; string.Compare(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;character1.Name, character2.Name, StringComparison.OrdinalIgnoreCase)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;MaxBy/MinBy accept key selector and key comparer functions, and their output is a list of all maximum/minimum values:&lt;/p&gt;
&lt;p&gt;public static IList&amp;lt;TSource&amp;gt; MaxBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IList&amp;lt;TSource&amp;gt; MaxBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IList&amp;lt;TSource&amp;gt; MinBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IList&amp;lt;TSource&amp;gt; MinBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void MaxByMinBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IList&amp;lt;Character&amp;gt;maxCharacters = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.MaxBy(character =&amp;gt; character.Name, StringComparer.OrdinalIgnoreCase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IList&amp;lt;Character&amp;gt;minCharacters = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.MinBy(character =&amp;gt; character.Name, StringComparer.OrdinalIgnoreCase);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The previous example of finding the maximum types in core library becomes easy with MaxBy:&lt;/p&gt;
&lt;p&gt;internal static void MaxBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CoreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(type =&amp;gt; (Type: type, MemberCount: type.GetDeclaredMembers().Length))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.MaxBy(typeAndMemberCount =&amp;gt; typeAndMemberCount.MemberCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines(max =&amp;gt; $&quot;{max.Type.FullName}:{max.MemberCount}&quot;); // System.Convert:311
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Quantifiers&lt;/h3&gt;
&lt;p&gt;There is an IsEmpty query for convenience. It is just the opposite of Any:&lt;/p&gt;
&lt;p&gt;public static bool IsEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; !source.Any();&lt;/p&gt;
&lt;h2&gt;Void queries&lt;/h2&gt;
&lt;p&gt;Ix provides a ForEach query to iterate the source sequence, which is similar to List&amp;lt;T&amp;gt;.ForEach method.&lt;/p&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;ForEach represents the foreach loop, with a non-indexed overload and an indexed overload, which can be fluently used at the end of LINQ query. This is probably the handiest query in LINQ programming, because it executes the LINQ query and process the query results:&lt;/p&gt;
&lt;p&gt;public static void ForEach&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; onNext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource, int&amp;gt;onNext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;onNext(value, index);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There was an issue with the indexed ForEach – the index increment was not checked. The issue was uncovered when writing this book and has been fixed.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses the additional LINQ to Objects queries provided by Microsoft through Ix, including sequence queries for generation, filtering, mapping, concatenation, set, partitioning, conversion, buffering, exception, control flow, iteration, value queries for aggregation, quantifiers, and the handiest ForEach to execute LINQ query.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (5) Query Methods Implementation</title><link>https://dixin.github.io/posts/linq-to-objects-query-methods-implementation/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-query-methods-implementation/</guid><description>Understanding of internal implementation of LINQ to Objects queries is the ultimate way to master them and use them accurately and effectively, and is also helpful for defining custom query methods, w</description><pubDate>Fri, 05 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Understanding of internal implementation of LINQ to Objects queries is the ultimate way to master them and use them accurately and effectively, and is also helpful for defining custom query methods, which is discussed later in the custom queries chapter. Just like the usage discussion part, here query methods are still categorized by output type, but in a different order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Collection queries: output a new collection (immediate execution):&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sequence queries: output a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution, underlined are eager evaluation):&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Conversion: Cast, AsEnumerable&lt;/p&gt;
&lt;p&gt;o Generation: Empty, Range, Repeat, DefaultIfEmpty&lt;/p&gt;
&lt;p&gt;o Filtering (restriction): Where, OfType&lt;/p&gt;
&lt;p&gt;o Mapping (projection): Select, SelectMany&lt;/p&gt;
&lt;p&gt;o Grouping: GroupBy*&lt;/p&gt;
&lt;p&gt;o Join: SelectMany, Join*, GroupJoin*&lt;/p&gt;
&lt;p&gt;o Concatenation: Concat&lt;/p&gt;
&lt;p&gt;o Set: Distinct, Union, Intersect*, Except*&lt;/p&gt;
&lt;p&gt;o Convolution: Zip&lt;/p&gt;
&lt;p&gt;o Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/p&gt;
&lt;p&gt;o Ordering: OrderBy*, ThenBy*, OrderByDescending*, ThenByDescending*, Reverse*&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Value queries: output a single value (immediate execution):&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/p&gt;
&lt;p&gt;o Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/p&gt;
&lt;p&gt;o Quantifier: All, Any, Contains&lt;/p&gt;
&lt;p&gt;o Equality: SequenceEqual&lt;/p&gt;
&lt;p&gt;The LINQ to Objects queries are functional as APIs, but their implementation is imperative. Again, the collection queries and value queries implement immediate execution, and the sequence queries implements deferred execution. For the sequential queries, the ones marked with * implements eager evaluation, and the other ones without mark implements lazy evaluation.&lt;/p&gt;
&lt;h3&gt;Argument check and deferred execution&lt;/h3&gt;
&lt;p&gt;As fore mentioned, all sequence queries implement deferred execution, mostly by following iterator pattern, which can be easily implemented with yield statement. For a generator function with the yield syntactic sugar, its arguments check cannot be directly added to the function body, because the execution of all code in the body is deferred. For example, assuming arguments check is added to Select query as the following:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectWithDeferredCheck&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(source));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (selector == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(selector));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(value); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its arguments are expected to be checked immediately when it is called. However, the check is deferred. When it is called, it only constructs the following generator:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CompiledSelectWithDeferredCheck&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generator&amp;lt;TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(source));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (selector == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(selector));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; sourceIterator.MoveNext(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; selector(sourceIterator.Current),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; sourceIterator?.Dispose());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The argument check is deferred to execute when starting to pull the results from the output sequence. The easiest solution is simply isolating yield statement along with its iteration control flow, which is compiled to deferred execution, with a separate method or a local function:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectWithCheck&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source == null) // Immediate execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(source));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (selector == null) // Immediate execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(selector));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(value); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return SelectGenerator(); // Immediate execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As a result, the above outer function is no longer a generator function. When it is called, it immediately checks the arguments, then immediately calls the local function to construct a generator as output. As mentioned in the introduction chapter, this tutorial omits argument null checks and only demonstrate argument checks for other purposes .&lt;/p&gt;
&lt;h3&gt;Collection queries&lt;/h3&gt;
&lt;p&gt;The collection queries are discussed first because they are relatively straightforward, and they are used to implement sequence queries:&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;ToArray is implemented by pulling all values from source sequence and store them to a new array. To create an array, its length has to be provided. However, the count of values in source is unknown when starting to pull the values. The easiest implementation is to create an empty array, when each value is pulled from source sequence, increase the array size by 1 to store that value:&lt;/p&gt;
&lt;p&gt;internal static partial class EnumerableExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] array = new TSource[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref array, array.Length + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;array[array.Length - 1] = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return array;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Actually, Microsoft’s built-in implementation has some performance improvement. First, if the source sequence implements ICollection&amp;lt;T&amp;gt;, then it already has a CopyTo method to store its values to an array:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface ICollection&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int Count { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool IsReadOnly { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Add(T item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Clear();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool Contains(T item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void CopyTo(T[] array, int arrayIndex);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool Remove(T item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Also, the array does not need to be resized for each value. The built-in implementation has the arrays grow in the same way of List&amp;lt;T&amp;gt;. First, an initial length is used to construct the array; when pulling values from source and storing to array, if array gets full, then double its length; After all values are pulled, the array resized to the actual length. The following is an equivalent implementation, optimized for readability:&lt;/p&gt;
&lt;p&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is ICollection&amp;lt;TSource&amp;gt; genericCollection)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int length = genericCollection.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (length &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] array = new TSource[length];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;genericCollection.CopyTo(array, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return array;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int InitialLength = 4; // Initial array length.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int MaxLength = 0x7FEFFFFF; // Max array length: Array.MaxArrayLength.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] array = new TSource[InitialLength];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;array[0] = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int usedLength = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (usedLength == array.Length)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int increaseToLength = usedLength * 2; // Array is full, double its size.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if ((uint)increaseToLength&amp;gt; MaxLength)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;increaseToLength = usedLength&amp;gt; = MaxLength ? usedLength + 1 : MaxLength;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref array, increaseToLength);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;array[usedLength++] = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref array, usedLength); // Consolidate array to its actual size.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return array;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Array.Empty&amp;lt;TSource&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;ToList is much easier to implement, because List&amp;lt;T&amp;gt; has a constructor accepting an IEnumerable&amp;lt;T&amp;gt; source:&lt;/p&gt;
&lt;p&gt;public static List&amp;lt;TSource&amp;gt; ToList&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;&lt;/p&gt;
&lt;p&gt;new List&amp;lt;TSource&amp;gt;(source);&lt;/p&gt;
&lt;p&gt;ToDictionary is also easy, because Dictionary&amp;lt;TKey, TValue&amp;gt; has an Add method:&lt;/p&gt;
&lt;p&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.ToDictionary(keySelector, value =&amp;gt; value, comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;TKey, TElement&amp;gt; dictionary = new Dictionary&amp;lt;TKey, TElement&amp;gt;(comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dictionary.Add(keySelector(value), elementSelector(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return dictionary;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As previously discussed, a lookup is a dictionary of key and sequence pairs, and each key and sequence pair are just a group represented by IGrouping&amp;lt;TKey, TElement&amp;gt;, which can be implemented as:&lt;/p&gt;
&lt;p&gt;public class Grouping&amp;lt;TKey, TElement&amp;gt; : IGrouping&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly List&amp;lt;TElement&amp;gt; values = new List&amp;lt;TElement&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Grouping(TKey key) =&amp;gt; this.Key = key;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TKey Key { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;TElement&amp;gt; GetEnumerator() =&amp;gt; this.values.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Add(TElement value) =&amp;gt; this.values.Add(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET provides a public lookup type, but there is no public API to instantiate it, except the ToLookup query itself. For demonstration purpose, based on the previous discussion of dictionary and lookup, a custom lookup can be quickly implemented with dictionary, where each dictionary value is a group, and each dictionary key is the hash code of group key:&lt;/p&gt;
&lt;p&gt;public partial class Lookup&amp;lt;TKey, TElement&amp;gt; : ILookup&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Dictionary&amp;lt;int, Grouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; groups =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Dictionary&amp;lt;int, Grouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly IEqualityComparer&amp;lt;TKey&amp;gt; equalityComparer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Lookup(IEqualityComparer&amp;lt;TKey&amp;gt; equalityComparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.equalityComparer = equalityComparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Count =&amp;gt; this.groups.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private int GetHashCode(TKey key) =&amp;gt; key == null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? -1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: this.equalityComparer.GetHashCode(key) &amp;amp; int.MaxValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int.MaxValue is 0b_01111111_11111111_11111111_11111111. So the hash code of non-null key is always &amp;gt; -1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Contains(TKey key) =&amp;gt; this.groups.ContainsKey(this.GetHashCode(key));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerable&amp;lt;TElement&amp;gt; this[TKey key] =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.groups.TryGetValue(this.GetHashCode(key), out Grouping&amp;lt;TKey, TElement&amp;gt; group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? (IEnumerable&amp;lt;TElement&amp;gt;)group
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: Array.Empty&amp;lt;TElement&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GetEnumerator() =&amp;gt; this.groups.Values.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The built-in API object.GetHashCode is not directly used to get each group key’s hash code, because it does not handle null value very well in some cases. System.Nullable&amp;lt;T&amp;gt;.GetHashCode is such an example. ((int?)0).GetHashCode() and ((int?)null).GetHashCode() both return 0. So, the above GetHashCode method reserves -1 for null. And any non-null value’s hash code is converted to a positive int by a bitwise and operation with int.MaxValue (0b_01111111_11111111_11111111_11111111). Also notice the indexer getter outputs an empty sequence when the specified key does not exist. Similar to Grouping&amp;lt;TKey, TElement&amp;gt;.Add, the following Lookup&amp;lt;TKey, TElement&amp;gt;.AddRange is defined to add data:&lt;/p&gt;
&lt;p&gt;public partial class Lookup&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Lookup&amp;lt;TKey, TElement&amp;gt; AddRange&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool skipNullKey = false)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey key = keySelector(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (key == null &amp;amp;&amp;amp;skipNullKey)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;continue;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int hashCode = this.GetHashCode(key);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.groups.TryGetValue(hashCode, out Grouping&amp;lt;TKey, TElement&amp;gt; group))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group.Add(elementSelector(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.groups.Add(hashCode, new Grouping&amp;lt;TKey, TElement&amp;gt;(key) { elementSelector(value) });
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now, ToLookup can be implemented by creating a lookup and adding all data:&lt;/p&gt;
&lt;p&gt;public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Lookup&amp;lt;TKey, TElement&amp;gt;(comparer).AddRange(source, keySelector, elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.ToLookup(keySelector, value =&amp;gt; value, comparer);&lt;/p&gt;
&lt;h3&gt;Sequence queries&lt;/h3&gt;
&lt;p&gt;All sequence queries implement deferred execution. Most of them use follows the iterator pattern with a generator. For these queries, some are implemented with the yield syntactic sugar, and some are implemented with custom defined generator for performance improvement. Here, to make it intuitive and readable, all those queries’ implementation is demonstrated with yield.&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;AsEnumerable does nothing:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;&lt;/p&gt;
&lt;p&gt;source; // Deferred execution.&lt;/p&gt;
&lt;p&gt;With an IEnumerable&amp;lt;T&amp;gt; output, it just makes the source’s non-sequence methods (if any) not available. It also implements deferred execution, because calling AsEnumerable does not pull any value from source sequence.&lt;/p&gt;
&lt;p&gt;Cast is very easy to implement with the generator syntactic sugar. Just yield each cast value:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (object value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (TResult)value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The built-in implementation does a little optimization. If the source is already a generic sequence of the specified result type, it can be directly returned. Logically it should be something like:&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IEnumerable&amp;lt;TResult&amp;gt; genericSource)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return genericSource;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (object value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (TResult)value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above code cannot be compiled. The yield statement indicates the entire function body should be compiled to a generator, so the return statement cannot be used with yield statement. Similar to argument check, the solution is to isolate the iteration control flow with yield statement into another method or local function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt;CastGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (object value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (TResult)value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return source is IEnumerable&amp;lt;TResult&amp;gt; genericSource
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? genericSource
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: CastGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Cast also implements deferred execution. When it is called, its output is either the source sequence itself or a generator, without pulling values from source or execute the casting.&lt;/p&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Empty can be implemented with a single yield break statement, which is compiled to an empty generator:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; EmptyGenerator&amp;lt;TResult&amp;gt;()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The built-in implementation actually uses an empty array, which has better performance than constructing a generator:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Empty&amp;lt;TResult&amp;gt;() =&amp;gt; Array.Empty&amp;lt;TResult&amp;gt;();&lt;/p&gt;
&lt;p&gt;Range can be simply implemented with a loop:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0 || (((long)start) + count - 1L) &amp;gt; int.MaxValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;RangeGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int end = start + count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int value = start; value != end; value++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return RangeGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And Repeat has been discussed. The built-in implementation also checks the count argument, and uses an empty array when count is 0:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count&amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Empty&amp;lt;TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; RepeatGenerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return element; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return RepeatGenerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DefaultIfEmpty can be implemented with a desugared foreach loop to detect and iterate the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TSource defaultValue = default)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// source is not empty.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator.Current; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// source is empty.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return defaultValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The first MoveNext call detects if the source sequence is empty. If so, just yield the default value, otherwise yield all values in the source sequence.&lt;/p&gt;
&lt;h3&gt;Filtering&lt;/h3&gt;
&lt;p&gt;Where is already discussed. The following are the non-indexed overload and index overload equivalent to the built-in implementation:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, OfType has a type test to filter the source:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; OfType&amp;lt;TResult&amp;gt;(this IEnumerable source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (object value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (value is TResult)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return (TResult)value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Mapping&lt;/h3&gt;
&lt;p&gt;Select has also been discussed. The following are the non-indexed overload and index overload equivalent to the built-in implementation:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt;selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(value); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(value, index); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The implementation of SelectMany is also straightforward:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TResult result in selector(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return result; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Above code intuitively shows its capacity to flatten a hierarchical 2-level-sequence to a flat 1-level-sequence. The following is the overload with collection selector and result selector:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TCollection, TResult&amp;gt;resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TCollection collectionValue in collectionSelector(sourceValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(sourceValue, collectionValue); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following are the indexed overloads:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TResult result in selector(value, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return result; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TCollection, TResult&amp;gt;resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TCollection collectionValue in collectionSelector(sourceValue, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(sourceValue, collectionValue); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;GroupBy’s work is similar to ToLookup, but with deferred execution. To implement deferred execution with ToLookup, the easiest way is to involve yield statement:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TSource&amp;gt; lookup = source.ToLookup(keySelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;TKey, TSource&amp;gt; group in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return group; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When starting to pull the first value from the returned generator, ToLookup is called to evaluate all source values and group them, so that the first group can be yielded. Apparently GroupBy implements eager evaluation. The overloads with element selector and resultSelector can all be implemented in the same pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TElement&amp;gt; lookup = source.ToLookup(keySelector, elementSelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;TKey, TElement&amp;gt; group in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return group; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TSource&amp;gt; lookup = source.ToLookup(keySelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;TKey, TSource&amp;gt; group in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(group.Key, group); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TElement&amp;gt; lookup = source.ToLookup(keySelector, elementSelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;TKey, TElement&amp;gt; group in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(group.Key, group); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;p&gt;Similar to GroupBy, GroupJoin for outer join can be simply implemented with the same pattern of ToLookup and yield:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoinWithLookup&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TInner&amp;gt; innerLookup = inner.ToLookup(innerKeySelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TOuter outerValue in outer)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(outerValue, innerLookup[outerKeySelector(outerValue)]); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When trying to pull the first value from the returned generator, the inner values are grouped by the keys, and stored in the inner lookup. Then, for each outer value, query the inner lookup by key. Remember when a lookup is queried with a key, it always outputs a sequence, even when the key does not exist, it returns an empty sequence. So that in GroupJoin, each outer value is always paired with a group of inner values. The above implementation is straightforward, but the inner source is always pulled, even when the outer source is empty. This can be avoided by a little optimization:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TOuter&amp;gt; outerIterator = outer.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (outerIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Lookup&amp;lt;TKey, TInner&amp;gt; innerLookup = new Lookup&amp;lt;TKey, TInner&amp;gt;(comparer).AddRange(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner, innerKeySelector, innerValue =&amp;gt; innerValue, skipNullKey: true); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOuter outerValue = outerIterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(outerValue, innerLookup[outerKeySelector(outerValue)]); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (outerIterator.MoveNext());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to DefaultIfEmpty, the first MoveNext call detects if the outer source is empty. Only if not, the inner values are pulled and converted to a lookup.&lt;/p&gt;
&lt;p&gt;Join for inner join can also be implemented with the similar pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; JoinWithToLookup&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;TKey, TInner&amp;gt; innerLookup = inner.ToLookup(innerKeySelector, comparer); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TOuter outerValue in outer)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey key = outerKeySelector(outerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (innerLookup.Contains(key))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TInner innerValue in innerLookup[key])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(outerValue, innerValue); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It calls the ILookup&amp;lt;TKey, TElement&amp;gt;.Contains filter, because in inner join each outer value has to be paired with a matching inner value. Again, the above implementation can be optimized, so that the inner values are not pulled and converted to lookup when the outer source is empty:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TOuter&amp;gt; outerIterator = outer.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (outerIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Lookup&amp;lt;TKey, TInner&amp;gt; innerLookup = new Lookup&amp;lt;TKey, TInner&amp;gt;(comparer).AddRange(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner, innerKeySelector, innerValue =&amp;gt; innerValue, skipNullKey: true); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (innerLookup.Count&amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOuter outerValue = outerIterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey key = outerKeySelector(outerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (innerLookup.Contains(key))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TInner innerValue in innerLookup[key])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(outerValue, innerValue); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (outerIterator.MoveNext());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;Concat’s implementation is equivalent to yield values from the first source sequence, then yield values from the from the second:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in first)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in second)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Append and Prepend’s implementation is equivalent to the following, with similar pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Append&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return element;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Prepend&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return element;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;All the set queries need to remove duplicate values in the result sequence. So, the following hash set is defined to represent a collection of distinct values. The duplication of values can be identified by their hash codes, so a dictionary can be used to store distinct hash code and value pairs:&lt;/p&gt;
&lt;p&gt;public partial class HashSet&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly IEqualityComparer&amp;lt;T&amp;gt; equalityComparer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Dictionary&amp;lt;int, T&amp;gt;dictionary = new Dictionary&amp;lt;int, T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public HashSet(IEqualityComparer&amp;lt;T&amp;gt; equalityComparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.equalityComparer = equalityComparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt; this.dictionary.Values.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Then, the following Add and AddRange methods can be defined:&lt;/p&gt;
&lt;p&gt;public partial class HashSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private int GetHashCode(T value) =&amp;gt; value == null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? -1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: this.equalityComparer.GetHashCode(value) &amp;amp; int.MaxValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int.MaxValue is 0b_01111111_11111111_11111111_11111111, so the result of &amp;amp; is always &amp;gt; -1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Add(T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int hashCode = this.GetHashCode(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.dictionary.ContainsKey(hashCode))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.dictionary.Add(hashCode, value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public HashSet&amp;lt;T&amp;gt; AddRange(IEnumerable&amp;lt;T&amp;gt; values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Add(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When Add is called with a specified value, if there is already a duplicate hash code in the internal dictionary, the specified value is not stored in the dictionary and false is returned; otherwise, the specified value and its hash code are added to the internal dictionary, and true is returned. With above hash set, it is very easy to implement Distinct.&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt;hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (hashSet.Add(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Union can be implemented by filtering the first source sequence with HashSet&amp;lt;T&amp;gt;.Add, then filter the second source sequence with HashSet&amp;lt;T&amp;gt;.Add:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt;hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource firstValue in first)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (hashSet.Add(firstValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return firstValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource secondValue in second)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (hashSet.Add(secondValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return secondValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Except can be implemented with the same pattern of filtering with HashSet&amp;lt;T&amp;gt;.Add:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt;secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource firstValue in first)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (secondHashSet.Add(firstValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return firstValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When trying to pull the first value from the returned generator, values in the second sequence are eagerly evaluated and stored in a hash set, which is then used to filter the first sequence.&lt;/p&gt;
&lt;p&gt;And Intersect can also be implemented with this pattern:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; IntersectWithAdd&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt;secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt; firstHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource firstValue in first)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (secondHashSet.Add(firstValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstHashSet.Add(firstValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else if (firstHashSet.Add(firstValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return firstValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To simplify above implementation, A Remove method can be defined for hash set:&lt;/p&gt;
&lt;p&gt;public partial class HashSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Remove(T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int hasCode = this.GetHashCode(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.dictionary.ContainsKey(hasCode))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.dictionary.Remove(hasCode);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to Add, here if a value is found and removed, Remove outputs true; otherwise, Remove outputs false. So, Intersect can be implemented by filtering with Remove:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;HashSet&amp;lt;TSource&amp;gt;secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource firstValue in first)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (secondHashSet.Remove(firstValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return firstValue; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Convolution&lt;/h3&gt;
&lt;p&gt;Zip is easy to implement with a desugared foreach:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TFirst&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSecond&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TFirst, TSecond, TResult&amp;gt;resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TFirst&amp;gt; firstIterator = first.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSecond&amp;gt; secondIterator = second.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (firstIterator.MoveNext() &amp;amp;&amp;amp; secondIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return resultSelector(firstIterator.Current, secondIterator.Current); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It stops yielding result when one of those 2 source sequences reaches the end.&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Skip is easy to implement:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count--;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It can be optimized a little bit by desugaring the foreach loop, so that when a value should be skipped, only the source iterator’s MoveNext method is called.&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (count &amp;gt; 0 &amp;amp;&amp;amp; iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count--; // Comparing foreach loop, iterator.Current is not called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return iterator.Current; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In contrast, SkipWhile has to pull each value from source sequence to call predicate, so there is no need to desugar foreach. The following are the non-index overload and indexed overload:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool skip = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (skip &amp;amp;&amp;amp; !predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;skip = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!skip)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool skip = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (skip &amp;amp;&amp;amp; !predicate(value, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;skip = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!skip)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Take is also straightforward:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (--count == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following are TakeWhile’s non-indexed overload and indexed overload:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = -1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = checked(index + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!predicate(value, index))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;Reverse has been discussed:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Reverse&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] array = ToArray(source); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = array.Length - 1; index &amp;gt;= 0; index--)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return array[index]; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other ordering queries are implemented very differently because they involve the IOrderedEnumerable&amp;lt;T&amp;gt; interface. Again here are the signatures:&lt;/p&gt;
&lt;p&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;And once again the following is the definition of IOrderedEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt;comparer, bool descending);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its implementation is a little complex. The following is a simplified version but equivalent to the built-in implementation:&lt;/p&gt;
&lt;p&gt;internal class OrderedSequence&amp;lt;TSource, TKey&amp;gt; : IOrderedEnumerable&amp;lt;TSource&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly IEnumerable&amp;lt;TSource&amp;gt; source;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly IComparer&amp;lt;TKey&amp;gt; comparer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly bool descending;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Func&amp;lt;TSource, TKey&amp;gt; keySelector;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Func&amp;lt;TSource[], Func&amp;lt;int, int, int&amp;gt;&amp;gt; previousGetComparison;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal OrderedSequence(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt;comparer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool descending = false,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// previousGetComparison is only specified in CreateOrderedEnumerable,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// and CreateOrderedEnumerable is only called by ThenBy/ThenByDescending.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When OrderBy/OrderByDescending is called, previousGetComparison is not specified.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource[], Func&amp;lt;int, int, int&amp;gt;&amp;gt; previousGetComparison = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.source = source;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.keySelector = keySelector;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.descending = descending;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.previousGetComparison = previousGetComparison;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;TSource&amp;gt; GetEnumerator()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] values = this.source.ToArray(); // Eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = values.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] indexMap = new int[count];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;indexMap[index] = index;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// GetComparison is only called once for each generator instance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; comparison = this.GetComparison(values);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Sort(indexMap, (index1, index2) =&amp;gt; // index1 &amp;lt; index2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Format compareResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When compareResult is 0 (equal), return index1 - index2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// so that indexMap[index1] is before indexMap[index2],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 2 equal values&apos; original order is preserved.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compareResult = comparison(index1, index2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return compareResult == 0 ? index1 - index2 : compareResult;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}); // More eager evaluation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return values[indexMap[index]];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Only called by ThenBy/ThenByDescending.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IOrderedEnumerable&amp;lt;TSource&amp;gt; CreateOrderedEnumerable&amp;lt;TNextKey&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(Func&amp;lt;TSource, TNextKey&amp;gt; nextKeySelector, IComparer&amp;lt;TNextKey&amp;gt; nextComparer, bool nextDescending) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OrderedSequence&amp;lt;TSource, TNextKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.source, nextKeySelector, nextComparer, nextDescending, this.GetComparison);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private TKey[] GetKeys(TSource[] values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = values.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey[] keys = new TKey[count];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keys[index] = this.keySelector(values[index]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return keys;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Func&amp;lt;int, int, int&amp;gt; GetComparison(TSource[] values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// GetComparison is only called once for each generator instance,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// so GetKeys is only called once during the ordering query execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey[] keys = this.GetKeys(values);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.previousGetComparison == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// In OrderBy/OrderByDescending.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (index1, index2) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// OrderBy/OrderByDescending always need to compare keys of 2 values.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.CompareKeys(keys, index1, index2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// In ThenBy/ThenByDescending.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; previousComparison = this.previousGetComparison(values);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (index1, index2) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Only when previousCompareResult is 0 (equal),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ThenBy/ThenByDescending needs to compare keys of 2 values.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int previousCompareResult = previousComparison(index1, index2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return previousCompareResult == 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? this.CompareKeys(keys, index1, index2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: previousCompareResult;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private int CompareKeys(TKey[] keys, int index1, int index2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Format compareResult to always be 0, -1, or 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compareResult = this.comparer.Compare(keys[index1], keys[index2]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return compareResult == 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: (this.descending ? (compareResult &amp;gt; 0 ? -1 : 1) : (compareResult &amp;gt; 0 ? 1 : -1));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the ordering queries can be implemented by constructing the above ordered sequence:&lt;/p&gt;
&lt;p&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OrderedSequence&amp;lt;TSource, TKey&amp;gt;(source, keySelector, comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new OrderedSequence&amp;lt;TSource, TKey&amp;gt;(source, keySelector, comparer, descending: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.CreateOrderedEnumerable(keySelector, comparer, descending: false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IComparer&amp;lt;TKey&amp;gt;comparer = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source.CreateOrderedEnumerable(keySelector, comparer, descending: true);&lt;/p&gt;
&lt;p&gt;They implement deferred execution since constructing ordered sequence does not pull any value from the source. The OrderedSequence&amp;lt;T&amp;gt; type wraps the source data and iteration algorithm of ordering, including:&lt;/p&gt;
&lt;p&gt;· the source sequence,&lt;/p&gt;
&lt;p&gt;· the keySelector function,&lt;/p&gt;
&lt;p&gt;· a bool value indicating the ordering should be descending or ascending&lt;/p&gt;
&lt;p&gt;· a previousGetComparison function, which identifies whether current OrderedSequence&amp;lt;T&amp;gt; is created by OrderBy/OrderByDescending, or by ThenBy/ThenByDescending&lt;/p&gt;
&lt;p&gt;o When OrderBy/OrderByDescending are called, they directly instantiate an OrderedSequence&amp;lt;T&amp;gt; with a null previousGetComparison function.&lt;/p&gt;
&lt;p&gt;o When ThenBy/ThenByDescending are called, they call CreateOrderedEnumerable to instantiate OrderedSequence&amp;lt;T&amp;gt;, and pass its OrderedSequence&amp;lt;T&amp;gt;’s GetComparison method as the previousGetComparison function for the new OrderedSequence&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;OrderedSequence&amp;lt;T&amp;gt;’s GetEnumerator method uses yield statement to return an iterator (not generator this time). Eager evaluation is implemented, because it has to pull all values in the source sequence and sort them, in order to know which value is the first one to yield. For performance consideration, instead of sorting the values from source sequence, here the indexes of values are sorted. For example, in the values array, if indexes { 0, 1, 2 } become { 2, 0, 1 } after sorting, then the values are yielded in the order of { values[2], values[0], values[1] }.&lt;/p&gt;
&lt;p&gt;When the eager evaluation starts, GetComparison is called. It evaluates all keys of the values, and returns a comparison function:&lt;/p&gt;
&lt;p&gt;· If previousGetComparison function is null, it returns a comparison function to represent an OrderBy/OrderByDescending query, which just compares the keys.&lt;/p&gt;
&lt;p&gt;· if previousGetComparison function is not null, it returns a comparison function to represent a ThenBy/ThenByDescending query, which first check the previous compare result, and only compare the keys when previous compare result is equal.&lt;/p&gt;
&lt;p&gt;· In both cases, comparison function calls CompareKeys to compare 2 keys. CompareKeys calls IComparer&amp;lt;TKey&amp;gt;.Compare, and format the compare result to 0, -1, or 1 to represent less then, equal to, greater than. If the descending field is true, 1 and -1 are swapped.&lt;/p&gt;
&lt;p&gt;Eventually, the returned comparison function is used during GetEnumerator’s eager evaluation, to sort the indexes of values. When comparing keys for index1 and index2, index1 is always less than index2. In another word, values[index1] is before values[index2] before the ordering query execution. If the result from comparison function is equal, index1 - index2 is used instead of 0. So that the relative positions of values at index1 and index2 are preserved, values[index1] is still before values[index2] after the ordering query execution.&lt;/p&gt;
&lt;h3&gt;Value queries&lt;/h3&gt;
&lt;p&gt;This category of queries iterate the source sequence. They apparently implement immediate execution.&lt;/p&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;First can be implemented by pulling the source sequence once. The built-in implementation has some optimization. If the source already supports index, then source[0] can be pulled directly. The index support can be identified by testing if source also implements IList&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IList&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T this[int index] { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int IndexOf(T item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Insert(int index, T item);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void RemoveAt(int index);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, IList&amp;lt;T&amp;gt; is implemented by T[] array, List&amp;lt;T&amp;gt;, and Collection&amp;lt;T&amp;gt;, etc. So, the following is an optimized implementation of First:&lt;/p&gt;
&lt;p&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (list.Count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload with predicate is also easy to implement:&lt;/p&gt;
&lt;p&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The implementation of FirstOrDefault is very similar. When source is empty, just output the default value instead of throwing exception:&lt;/p&gt;
&lt;p&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (list.Count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Last and LastOrDefault can be implemented in the similar pattern, with desugared foreach loop:&lt;/p&gt;
&lt;p&gt;public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = list.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[count - 1];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource last;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;last = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return last;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = list.Count - 1; index &amp;gt;= 0; index--)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = list[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource last = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(last))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;last = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return last;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = list.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[count - 1];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource last;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;last = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return last;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = list.Count - 1; index &amp;gt;= 0; index--)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = list[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource last = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;last = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return last;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And ElementAt and ElementAtOrDefault too:&lt;/p&gt;
&lt;p&gt;public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(index));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index-- == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(index));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, int index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index &amp;gt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index &amp;lt; list.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index-- == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Single and SingleOrDefault are stricter:&lt;/p&gt;
&lt;p&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (list.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 0:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 1:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext()) // source is empty.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource first = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return first;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains more than one element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Single&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(iterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains more than one matching element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (source is IList&amp;lt;TSource&amp;gt;list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (list.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 0:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case 1:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return list[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource first = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return first;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains more than one element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(iterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains more than one matching element.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Aggregate pulls all values from source and accumulate them:&lt;/p&gt;
&lt;p&gt;public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate seed,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;func,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate accumulate = seed;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;accumulate = func(accumulate, value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return resultSelector(accumulate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate accumulate = seed;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;accumulate = func(accumulate, value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return accumulate;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Aggregate&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource accumulate = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;accumulate = func(accumulate, iterator.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return accumulate;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Count can be implemented by iterating the source sequence. And if the source sequence is a collection, then it has a Count property:&lt;/p&gt;
&lt;p&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ICollection&amp;lt;TSource&amp;gt; genericCollection:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return genericCollection.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ICollection collection:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return collection.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;default:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count = checked(count + 1); // Comparing foreach loop, iterator.Current is never called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the overload with predicate can be implemented by filtering with the predicate function:&lt;/p&gt;
&lt;p&gt;public static int Count&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count = checked(count + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return count;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;LongCount cannot use collections’ Count property because it has int output. It simply counts the values:&lt;/p&gt;
&lt;p&gt;public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long count = 0L;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count = checked(count + 1L); // Comparing foreach loop, iterator.Current is never called.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static long LongCount&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long count = 0L;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count = checked(count + 1L);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return count;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Regarding the naming of LongCount .NET Framework Design Guidelines’ General Naming Conventions says:&lt;/p&gt;
&lt;p&gt;DO use a generic CLR type name, rather than a language-specific name.&lt;/p&gt;
&lt;p&gt;It would be more consistent if LongCount was named as Int64Count, just like Convert.ToInt64, etc.&lt;/p&gt;
&lt;p&gt;Min has 22 overloads; the following is the overload for decimal:&lt;/p&gt;
&lt;p&gt;public static decimal Min(this IEnumerable&amp;lt;decimal&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal min;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;decimal&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;min = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (value &amp;lt; min)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;min = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return min;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the decimal overload with selector can be implemented with Select:&lt;/p&gt;
&lt;p&gt;public static decimal Min&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt;selector) =&amp;gt; source.Select(selector).Min();&lt;/p&gt;
&lt;p&gt;Max also has 22 overloads. The overload for decimal without and with selector can be implemented with the same pattern:&lt;/p&gt;
&lt;p&gt;public static decimal Max(this IEnumerable&amp;lt;decimal&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal max;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;decimal&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;max = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (value &amp;gt; max)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;max = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return max;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Max&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt;selector) =&amp;gt; source.Select(selector).Max();&lt;/p&gt;
&lt;p&gt;Sum/Average has 20 overloads each. Also take the decimal overloads as example:&lt;/p&gt;
&lt;p&gt;public static decimal Sum(this IEnumerable&amp;lt;decimal&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal sum = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (decimal value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sum += value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Sum&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Select(selector).Sum();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Average&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, decimal&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;decimal sum = selector(iterator.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long count = 1L;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sum += selector(iterator.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count++;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sum / count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;All, Any, and Contains has a bool output. They can be implemented in a similar foreach-if pattern:&lt;/p&gt;
&lt;p&gt;public static bool All&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return iterator.MoveNext(); // Not needed to call iterator.Current.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Contains&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (comparer == null &amp;amp;&amp;amp;source is ICollection&amp;lt;TSource&amp;gt; collection)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return collection.Contains(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource sourceValue in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (comparer.Equals(sourceValue, value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Contains can be optimized a little bit because collection already has a Contains method.&lt;/p&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;The implementation of SequenceEqual is a little similar to Zip, where 2 source sequences are iterated at the same time. They are equal only when their counts are equal, and their values at each index are equal:&lt;/p&gt;
&lt;p&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt;second,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TSource&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (first is ICollection&amp;lt;TSource&amp;gt; firstCollection &amp;amp;&amp;amp; second is ICollection&amp;lt;TSource&amp;gt;secondCollection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp; firstCollection.Count != secondCollection.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; firstIterator = first.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; secondIterator = second.GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (firstIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!secondIterator.MoveNext() || !comparer.Equals(firstIterator.Current, secondIterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return !secondIterator.MoveNext();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses iterator pattern, and its implementation with the yield syntactic sugar. In LINQ to Objects, collection queries and value queries implements immediate execution, and sequence queries implements deferred execution following the iterator pattern, which is either lazy evaluation, or eager evaluation. Based on these concepts, this chapter demonstrates the implementation of LINQ to Objects queries in an equivalent and readable way. With the understanding of queries’ internal implementation, you should have a good understanding of LINQ to Objects standard queries, and be able to use them effectively.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (4) Deferred Execution, Lazy Evaluation and Eager Evaluation</title><link>https://dixin.github.io/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation/</guid><description>As fore mentioned, when LINQ to Objects’ collection queries and value queries are called, they start to evaluate query result. When sequence queries are called, they do not evaluate any query result,</description><pubDate>Thu, 04 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As fore mentioned, when LINQ to Objects’ collection queries and value queries are called, they start to evaluate query result. When sequence queries are called, they do not evaluate any query result, and can be viewed as defining a query.&lt;/p&gt;
&lt;h3&gt;Immediate execution vs. deferred execution&lt;/h3&gt;
&lt;p&gt;Apparently, collection queries must pull all values from source sequence, store them to a collection in the specified way, and output the collection to caller. The value queries also must pull or detect values in the source sequence to have the query result available. This is called immediate execution of LINQ queries. These queries mutate their source sequence’s iterator state, and may cause side effect, so they are impure functions. The sequence queries are pure functions, implemented by following the above iteration pattern. So, when they are called, they only construct a generator. This is called deferred execution.&lt;/p&gt;
&lt;p&gt;Generally, for LINQ query or any function with a sequence output, the yield syntactic sugar is a very handy tool to implement deferred execution. Tis can be intuitively demonstrated by the following 2 functions:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;double&amp;gt; AbsAndSqrtArray(double @double) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new double[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Math.Abs(@double),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Math.Sqrt(@double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;double&amp;gt; AbsAndSqrtGenerator(double @double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return Math.Abs(@double);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return Math.Sqrt(@double);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the first function AbsAndSqrtArray is called, Math.Abs and Math.Sqrt are called immediately to evaluate 2 values, and these 2 values are stored in an array for output. To defer the execution of the Math.Abs and Math.Sqrt, the second function AbsAndSqrtGenerator uses the yield syntactic sugar. When it is called, it constructs a generator for output. Only when pulling the 2 values from the output generator, Math.Abs and Math.Sqrt are called.&lt;/p&gt;
&lt;p&gt;The first function’s output sequence is a collection with actual values evaluated and stored, sometimes it is called a hot IEnumerable&amp;lt;T&amp;gt;, and the second function’s output sequence is called a cold IEnumerable&amp;lt;T&amp;gt;. Apparently, in LINQ to Objects, all sequence queries’ output are cold IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Lazy evaluation vs. eager evaluation&lt;/h3&gt;
&lt;p&gt;The Select and Where queries’ execution is deferred until values are pulled from the result sequence. When pulling the first result, the query executes, the selector function and predicate function are called until the first result is evaluated. At this moment the rest results are not evaluated. When pulling the second result, the query executes until the second result is evaluated, and so on. If pulling stops in the middle, the rest results are not evaluated. This behaviour is called lazy evaluation. To demonstrate the evaluation, add tracing to Select query’s iteration control flow:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Select query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query calls selector with {value}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult result = selector(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query yields {result}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Select query ends.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above foreach statement can be desugared as the following actual control flow:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; DesugaredSelectGenerator&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Select query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null; // start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator(); // start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext()) // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query calls selector with {sourceIterator.Current}.&quot;.WriteLine(); // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult result = selector(sourceIterator.Current); // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query yields {result}.&quot;.WriteLine(); // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return result; // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator?.Dispose(); // dispose.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Select query ends.&quot;.WriteLine(); // end.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is equivalent to the following generator construction:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CompiledSelectGenerator&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generator&amp;lt;TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Select query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; sourceIterator.MoveNext(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query calls selector with {sourceIterator.Current}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult result = selector(sourceIterator.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Select query yields {result}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; sourceIterator?.Dispose(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;end: () =&amp;gt; &quot;Select query ends.&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, add tracing to Where query as well:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; WhereGenerator&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Where query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Where query calls predicate with {value}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Where query yields {value}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Where query ends.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is also a generator construction, equivalent to the following:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledWhereGenerator&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Where query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Where query calls predicate with {sourceIterator.Current}.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(sourceIterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Where query yields {sourceIterator.Current}.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sourceIterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; sourceIterator?.Dispose(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;end: () =&amp;gt; &quot;Where query ends.&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following LINQ query is a composition of Where and Select:&lt;/p&gt;
&lt;p&gt;internal static void CallWhereAndSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(1, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; deferredQuery = source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WhereGenerator(int32 =&amp;gt; int32 &amp;gt; 2) // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectGenerator(int32 =&amp;gt; new string(&apos;*&apos;, int32)); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in deferredQuery)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query starts.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query starts.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query calls predicate with 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query calls predicate with 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query calls predicate with 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query yields 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields ***.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query calls predicate with 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query yields 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields ****.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query calls predicate with 5.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query yields 5.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 5.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields *****.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Where query ends.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query ends.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The tracing messages shows how exactly the lazy evaluation works in deferred execution. When WhereGenerator and SelectGenerator are called, the mapping query and filtering query are not executed. The composited query is the output sequence of SelectGenerator. When pulling the first result, Select starts execution, Select pulls the first results from its source sequence, which is the output sequence of Where, so that Where query starts execution, and pulls its source sequence. Where first retrieves 1, and calls its predicate function with 1. In this case, the output of predicate is false, so Where does not yield 1, but pulls the next value 2 from its source sequence, and calls predicate with 2. Again, the output of predicate is false, so Where does not yield 2, but pulls the next value 3 from its source sequence. This time, the output of predicate function is true, so Where query yields 3 to Select query. Select retrieves 3 and calls its selector function with 3. Eventually Select yields selector output *** as the first result of composited query. Then Select query pulls the next value from Where query, Where query pulls the next value from source. Where query retrieves 4 and calls predicate with 4. The output of predicate is true, so Where query yields 4 to Select query. Select query retrieves 4 and calls selector with 4. Eventually Select yields selector output **** as the second result of the composited query, and so on.&lt;/p&gt;
&lt;p&gt;The opposition of lazy evaluation is eager evaluation, where pulling the first result causes all results being evaluated. For example, Reverse query is a sequence query, and it implements deferred execution. When its result sequence is pulled for the first time, it starts execution. It has to evaluate and store all the values of source sequence, in order to yields the last source value as the first query result. The following is the equivalent implementation of Reverse. Again, to demonstrate the evaluation, tracing is added as well:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; ReverseGenerator&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Reverse query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] results = source.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Reverse query has all {results.Length} value(s) of source sequence.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = results.Length - 1; index &amp;gt;= 0; index--)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Reverse query yields index {index} of source sequence.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return results[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Reverse query ends.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is equivalent to the following generator construction:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledReverseGenerator&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] results = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Reverse query starts.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;results = source.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Reverse query evaluated all {results.Length} value(s) of source sequence.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;index = results.Length - 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; index &amp;gt;= 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;Reverse query yields index {index} of source source.&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return results[index--];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;end: () =&amp;gt; &quot;Reverse query ends.&quot;.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example is the composition of Select query and Reverse query:&lt;/p&gt;
&lt;p&gt;internal static void CallSelectAndReverse()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; deferredQuery = Enumerable.Range(1, 5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectGenerator(int32 =&amp;gt; new string(&apos;*&apos;, int32)) // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ReverseGenerator(); // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in deferredQuery)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query starts.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query starts.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields *.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields **.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields ***.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields ****.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query calls selector with 5.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query yields *****.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select query ends.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query has all 5 value(s) of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query yields index 4 of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query yields index 3 of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query yields index 2 of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query yields index 1 of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query yields index 0 of source sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reverse query ends.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The tracing messages shows how exactly the eager evaluation works in deferred execution. When pulling the first result, Reverse starts execution. Reverse pulls all values from its source sequence, which is the output generator of Select, so that Select query starts execution. Select pulls all values from its source sequence store them, calls selector function, and yields all results to Reverse query. Reverse retrieves and stores all values, and yields the last value as the first result. Then pulling the next query result causes Reverse direct yield the stored second last value, and so on.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (3) Generator</title><link>https://dixin.github.io/posts/linq-to-objects-generator/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-generator/</guid><description>After understanding how to use LINQ to Objects queries, this chapter starts to discuss how these queries work internally, including how they execute and how they are implemented. These insights help d</description><pubDate>Wed, 03 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;After understanding how to use LINQ to Objects queries, this chapter starts to discuss how these queries work internally, including how they execute and how they are implemented. These insights help developer mastering LINQ to Objects.&lt;/p&gt;
&lt;h2&gt;Generator&lt;/h2&gt;
&lt;p&gt;Most LINQ to Objects queries has an IEnumerable&amp;lt;T&amp;gt; output. They can be easily implemented with “brute force”. Take the simple query Repeat as example:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatArray&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource[] results = new TSource[count];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;results[index] = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return results;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The problem is, when the above Repeat query is called, it immediately generates all query results, stores them in an array, and outputs to the caller. When the count argument is large, this implementation consumes large memory. This can be resolved by properly following the iterator pattern.&lt;/p&gt;
&lt;h3&gt;Implement iterator pattern&lt;/h3&gt;
&lt;p&gt;The iterator pattern is imperative and object-oriented. It has a sequence represented by IEnumerable&amp;lt;T&amp;gt;, and an iterator represented by IEnumerator&amp;lt;T&amp;gt;. According to the definition of IEnumerator&amp;lt;T&amp;gt;, apparently the iterator is stateful. The following is a general-purpose iterator implemented as a finite-state machine:&lt;/p&gt;
&lt;p&gt;public enum IteratorState&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Create = -2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Start = 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MoveNext = 1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;End = -1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Error = -3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Iterator&amp;lt;T&amp;gt; : IEnumerator&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly Action start;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly Func&amp;lt;bool&amp;gt; moveNext;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly Func&amp;lt;T&amp;gt; getCurrent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly Action dispose;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected readonly Action end;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Iterator(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action start = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt; moveNext = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T&amp;gt; getCurrent = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action dispose = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action end = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.start = start;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.moveNext = moveNext;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.getCurrent = getCurrent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.dispose = dispose;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.end = end;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T Current { get; private set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object IEnumerator.Current =&amp;gt; this.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal IteratorState State { get; private set; } = IteratorState.Create; // IteratorState: Create.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Iterator&amp;lt;T&amp;gt; Start()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.State = IteratorState.Start; // IteratorState: Create =&amp;gt; Start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool MoveNext()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (this.State)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case IteratorState.Start:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.start?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.State = IteratorState.MoveNext; // IteratorState: Start =&amp;gt; MoveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;goto case IteratorState.MoveNext;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case IteratorState.MoveNext:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.moveNext?.Invoke() ?? false)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Current = this.getCurrent != null ? this.getCurrent() : default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true; // IteratorState: MoveNext =&amp;gt; MoveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.State = IteratorState.End; // IteratorState: MoveNext =&amp;gt; End.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.dispose?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.end?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.State = IteratorState.Error; // IteratorState: Start, MoveNext, End =&amp;gt; Error.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Dispose()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.State == IteratorState.Error || this.State == IteratorState.MoveNext)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Unexecuted finally blocks are executed before the thread is aborted.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.State = IteratorState.End; // IteratorState: Error =&amp;gt; End.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.dispose?.Invoke();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Reset() =&amp;gt; throw new NotSupportedException();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The sequence can be simply viewed as an iterator factory:&lt;/p&gt;
&lt;p&gt;public class Sequence&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Func&amp;lt;Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Sequence(Func&amp;lt;Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.iteratorFactory = iteratorFactory;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.iteratorFactory().Start(); // IteratorState: Create =&amp;gt; Start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above iterator encapsulates 5 functions (start, moveNext, getCurrent, end, dispose) in the iteration control flow, and manages 5 states:&lt;/p&gt;
&lt;p&gt;· Create: if an iterator is constructed on the fly, its initial state is Create.&lt;/p&gt;
&lt;p&gt;· Start: if an iterator is created by sequence’s factory method, its state is Start. Later, if its MoveNext is called for the first time, the start function is called to do the initialization work. Then, the state changes to MoveNext&lt;/p&gt;
&lt;p&gt;· MoveNext: After its MoveNext method being called for the first time, its state is MoveNext. Each time its MoveNext method is called, the moveNext function is called to output a bool value&lt;/p&gt;
&lt;p&gt;o If the output is true, the iterator has a value available for the caller, and getCurrent function can be called through its Current property to pull that value; The state remains MoveNext.&lt;/p&gt;
&lt;p&gt;o If false, there is no value available. The state changes to End, and the dispose function is called to release resources, then end functions is called to do the cleanup work;&lt;/p&gt;
&lt;p&gt;· End: if its MoveNext method is called and the state is End, false is directly returned to indicate caller that the sequential traversal ended, there is no value available to pull.&lt;/p&gt;
&lt;p&gt;· Error: if its MoveNext method throws an exception, the state changes to Error. Then its Dispose method is called to do the cleanup work, and eventually its state is changed to End.&lt;/p&gt;
&lt;p&gt;Now Sequence&amp;lt;T&amp;gt; and Iterator&amp;lt;T&amp;gt; can be used to implement Repeat with improved performance:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatSequence&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TSource value, int count) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Sequence&amp;lt;TSource&amp;gt;(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Iterator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; index++ &amp;lt; count,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;When the above RepeatSequence is called, it does not generate and store all repeated values. It only constructs a sequence instance with an iterator factory function, which then can be consumed by caller with a foreach statement:&lt;/p&gt;
&lt;p&gt;internal static void CallRepeatSequence&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource result in RepeatSequence(value, count)) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = RepeatSequence(value, count).GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Virtual control flow inside iterator:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (index++ &amp;lt; count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The foreach statement is compiled to a call to the sequence’s GetEnumerator method to get an iterator, and a while loop to poll iterator’s MoveNext method and Current property getter. The iterator’s state is an int value to indicate current result’ index in all results. When MoveNext is called, it checks and mutates the state. If the state is valid, a result is available be pulled from Current. With iterator pattern, RepeatSequence is improved from RepeatArray. The results now are on-demand, they are not generated and stored in advance.&lt;/p&gt;
&lt;p&gt;Another example is Select query. It accepts an input source sequence and constructs a new result sequence, by mapping each source value to another result with a selector function. It can be implemented following iterator pattern:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectSequence&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Sequence&amp;lt;TResult&amp;gt;(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Iterator&amp;lt;TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; sourceIterator.MoveNext(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; selector(sourceIterator.Current),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; sourceIterator?.Dispose());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;So that, Select dos not map or store any query result. It only constructs a sequence and never calls the selector function. When caller pulls each result from the output sequence, the selector function is called and result is evaluated:&lt;/p&gt;
&lt;p&gt;internal static void CallSelectSequence&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TResult result in SelectSequence(source, selector)) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TResult&amp;gt; iterator = SelectSequence(source, selector).GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult result = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Virtual control flow inside iterator:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult result = selector(sourceIterator.Current);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator?.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, Where can be implemented with this pattern to filter the source sequence with a predicate function:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; WhereSequence&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Sequence&amp;lt;TSource&amp;gt;(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Iterator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(sourceIterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; sourceIterator.Current,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dispose: () =&amp;gt; sourceIterator?.Dispose());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;Again, Where does not filter the source or store the filtering results. It only constructs a sequence and never calls predicate function. When caller starts to pull a result from the output sequence, the predicate function is called:&lt;/p&gt;
&lt;p&gt;internal static void CallWhereSequence&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource result in WhereSequence(source, predicate)) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = WhereSequence(source, predicate).GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Virtual control flow inside iterator:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(sourceIterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = sourceIterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator?.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With sequence and iterator, the LINQ sequential queries can be correctly implemented with expected performance. However, since the iterator pattern is imperative and stateful, it is not straightforward to specify how to construct sequence and how to construct iterator, and the actual iteration workflow is not intuitive as well. Another example is to define a custom FromValue query to generate a sequence from a single value, following the iterator pattern:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; FromValueSequence&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new Sequence&amp;lt;TSource&amp;gt;(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool isValueIterated = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Iterator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!isValueIterated)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isValueIterated = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;It uses a bool value as iterator state, so that the value cam be pulled only once:&lt;/p&gt;
&lt;p&gt;internal static void CallFromValueSequence&amp;lt;TSource&amp;gt;(TSource value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource result in FromValueSequence(value)) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = FromValueSequence(value).GetEnumerator())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Virtual control flow inside iterator:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool isValueIterated = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (!isValueIterated)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isValueIterated = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To simplify the coding, C# provides yield statement.&lt;/p&gt;
&lt;h3&gt;yield statement&lt;/h3&gt;
&lt;p&gt;C# 2.0 introduces the yield statement for named functions to implement iterator pattern, without defining and constructing sequence and iterator. The following example is equivalent to above RepeatSequence:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatYield&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Virtual control flow when iterating the results:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// while (index++ &amp;lt; count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TSource result = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// finally { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (index++ &amp;lt; count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With the yield statement, the start, moveNext, getCurrent, end, dispose functions for iteration are merged into a fluent and intuitive control flow. The yield statement is a syntactic sugar. The compilation of RepeatYield is just slightly different from the previous RepeatSequence implementation with the standard iteration pattern. C# compiler generates a generator type for each named function with yield statement and IEnumerable/IEnumerable&amp;lt;T&amp;gt; output. A generator is both a sequence and an iterator, which can be virtually viewed as:&lt;/p&gt;
&lt;p&gt;public interface IGenerator&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerator&amp;lt;T&amp;gt; { }&lt;/p&gt;
&lt;p&gt;In another word, a generator is an iterator with an additional factory method GetEnumerator, which does a little more work:&lt;/p&gt;
&lt;p&gt;public class Generator&amp;lt;T&amp;gt; : Iterator&amp;lt;T&amp;gt;, IGenerator&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int initialThreadId = Environment.CurrentManagedThreadId;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Generator(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action start = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt; moveNext = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T&amp;gt; getCurrent = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action dispose = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action end = null) : base(start, moveNext, getCurrent, dispose, end)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.initialThreadId == Environment.CurrentManagedThreadId
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp; this.State == IteratorState.Create
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Called by the same initial thread and iteration is not started.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? this.Start()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// If the iteration is already started, or the iteration is requested from a different thread, create new generator with new iterator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: new Generator&amp;lt;T&amp;gt;(this.start, this.moveNext, this.getCurrent, this.dispose, this.end).Start();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When generator is constructed, it remembers the thread id. Later, if its factory method is called by the same thread and the generator’s state has not been mutated, the output is itself; if the its factory is called again by the same thread after its state is mutated, or called by another thread, the output is a new generator. So, the compilation of RepeatYield is equivalent to:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatGenerator&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;moveNext: () =&amp;gt; index++ &amp;lt; count,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;getCurrent: () =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The control flow with yield statement can be viewed as normal control flow, so the above control flows can be further simplified, with the same way of simplifying normal C# code. Here the try-finally statement is not needed, so can be removed. And the while loop is equivalent to the following for loop:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; Repeat&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, yield statement greatly simplifies the implementation of iterator pattern. Again, the above for loop is a virtual control flow. At compile time, a generator type is generated to do the real work, and Repeat is compiled to just construct and output a generator. At runtime, when Repeat is called, the for loop is not executed and no query result is evaluated or stored; only when the caller pulls result, the generator yields repeated query results with the specified count.&lt;/p&gt;
&lt;p&gt;Similarly, Select and Where standard queries can also be implemented with yield statement following their iteration control flows:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectYield&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator(); // start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext()) // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(sourceIterator.Current); // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator?.Dispose(); // dispose.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return new Generator&amp;lt;TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// moveNext: () =&amp;gt; sourceIterator.MoveNext(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// getCurrent: () =&amp;gt; selector(sourceIterator.Current),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// dispose: () =&amp;gt; sourceIterator?.Dispose());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; WhereYield&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator = source.GetEnumerator(); // start.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (sourceIterator.MoveNext()) // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(sourceIterator.Current)) // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return sourceIterator.Current; // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sourceIterator?.Dispose(); // dispose.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return new Generator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// moveNext: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// while (sourceIterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// if (predicate(sourceIterator.Current))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// getCurrent: () =&amp;gt; sourceIterator.Current,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// dispose: () =&amp;gt; sourceIterator?.Dispose());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These control flows can be simplified with a foreach statement:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return selector(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (TSource value in source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (predicate(value))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The FromValue custom query can be implemented with yield statement too:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; FromValueYield&amp;lt;TSource&amp;gt;(TSource value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool isValueIterated = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (!isValueIterated) // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isValueIterated = true; // moveNext.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value; // getCurrent.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// bool isValueIterated = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return new Generator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// moveNext: () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// while (!isValueIterated)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// isValueIterated = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// getCurrent: () =&amp;gt; value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above try-finally statement, state checking and mutation are not needed. It is the same control flow as the following:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; FromValue&amp;lt;TSource&amp;gt;(TSource value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A named function with yield statement must have an IEnumerable/IEnumerable&amp;lt;T&amp;gt; output, or an IEnumerator/IEnumerator&amp;lt;T&amp;gt; output. As demonstrated above, when it outputs a sequence, it is compiled to generator construction. When it outputs an iterator, it is compiled to iterator construction. Take Repeat as example, its output can also be IEnumerator&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal static IEnumerator&amp;lt;TSource&amp;gt; RepeatIterator&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return new Iterator&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// moveNext: () =&amp;gt; index++ &amp;lt; count,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// getCurrent: () =&amp;gt; value).Start();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallRepeatIterator&amp;lt;TSource&amp;gt;(TSource value, int count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IEnumerator&amp;lt;TSource&amp;gt; iterator = RepeatIterator(value, count))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSource result = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The yield statement has another form as yield break, which means to end the iteration. For example, the following function outputs a sequence of 0, 1, 2:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;int&amp;gt; YieldBreak()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return 4;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The Repeat query can be implemented with the following equivalent control flow and yield break:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatYieldBreak&amp;lt;TSource&amp;gt;(TSource value, int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int index = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index++ &amp;lt; count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;yield break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (2) Query Methods (Operators) and Query Expressions</title><link>https://dixin.github.io/posts/linq-to-objects-query-methods-operators-and-query-expressions/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-query-methods-operators-and-query-expressions/</guid><description>As fore mentioned, LINQ to Objects standard query methods (also called standard query operators) are provided as static methods of System.Linq.Enumerable type, most of which are IEnumerable&lt;T&gt; extensi</description><pubDate>Tue, 02 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ to Objects standard query methods (also called standard query operators) are provided as static methods of System.Linq.Enumerable type, most of which are IEnumerable&amp;lt;T&amp;gt; extension methods. They can be categorized by output type:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sequence queries: output a new IEnumerable&amp;lt;T&amp;gt; sequence:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/p&gt;
&lt;p&gt;o Filtering (restriction): Where*, OfType&lt;/p&gt;
&lt;p&gt;o Mapping (projection): Select*, SelectMany*&lt;/p&gt;
&lt;p&gt;o Grouping: GroupBy*&lt;/p&gt;
&lt;p&gt;o Join: SelectMany, Join*, GroupJoin*&lt;/p&gt;
&lt;p&gt;o Concatenation: Concat, Append, Prepend&lt;/p&gt;
&lt;p&gt;o Set: Distinct, Union, Intersect, Except&lt;/p&gt;
&lt;p&gt;o Convolution: Zip&lt;/p&gt;
&lt;p&gt;o Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/p&gt;
&lt;p&gt;o Ordering: OrderBy*, ThenBy*, OrderByDescending*, ThenByDescending*, Reverse*&lt;/p&gt;
&lt;p&gt;o Conversion: Cast*, AsEnumerable&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Collection queries: output a new collection:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Value queries: output a single value:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;o Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/p&gt;
&lt;p&gt;o Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/p&gt;
&lt;p&gt;o Quantifier: All, Any, Contains&lt;/p&gt;
&lt;p&gt;o Equality: SequenceEqual&lt;/p&gt;
&lt;p&gt;These LINQ query methods are very functional. They are functions that can be composed by fluent chaining. Many of them are higher-order functions accepting function parameters, so anonymous functions (lambda expressions) or named functions can be passed to them. The query methods with IEnumerable&amp;lt;T&amp;gt; output are pure functions. They are referential transparency and side effect free. When they are called, they only create and output a new sequence wrapping the input sequence and the query logic, with the query logic not executed, so there are no state changes, data mutation, I/O, etc. The query logic execution is deferred until the result values are pulled from the output sequence. The other query methods that output a new collection or a single value are impure functions. When they are called, they immediately execute the query and pull the results.&lt;/p&gt;
&lt;h3&gt;Sequence queries&lt;/h3&gt;
&lt;p&gt;As discussed in the Function composition and LINQ queries chapter, some query methods in this category can be written with query expressions syntax. In above query method list, these query methods are marked with *.&lt;/p&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Enumerable type’s Empty, Range, Repeat methods can generate an IEnumerable&amp;lt;T&amp;gt; sequence. They are just normal static methods instead of extension methods:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Empty&amp;lt;TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Empty just generates an IEnumerable&amp;lt;T&amp;gt; sequence, which contains no value:&lt;/p&gt;
&lt;p&gt;internal static void Empty()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; empty = Enumerable.Empty&amp;lt;string&amp;gt;(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in empty) // Execute query by pulling the results.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count++; // Not executed.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Range generates an int sequence with the specified initial value and count of values:&lt;/p&gt;
&lt;p&gt;internal static void Range()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;range = Enumerable.Range(-1, 5); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int int32 in range) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To trace all values in a sequence, the following WriteLines extension method can be defined for IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;public static partial class TraceExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void WriteLines&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; values, Func&amp;lt;T, string&amp;gt; messageFactory = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (messageFactory != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(messageFactory(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, the above example can be simplified as:&lt;/p&gt;
&lt;p&gt;internal static void Range()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; range = Enumerable.Range(-1, 5); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;range.WriteLines(); // Execute query. -1 0 1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example creates a sequence with large number of int values:&lt;/p&gt;
&lt;p&gt;internal static void LargeRange()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;range = Enumerable.Range(1, int.MaxValue); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As just mentioned, calling above LargeRange just defines a query. A large sequence is created, but each actual value in the large sequence is not generated.&lt;/p&gt;
&lt;p&gt;internal static void Repeat()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;repeat = Enumerable.Repeat(&quot;*&quot;, 5); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;repeat.WriteLines(); // Execute query. * * * * *
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DefaultIfEmpty generates a sequence based on the source sequence. If the source sequence is not empty, the returned sequence contains the same values from the source sequence. If the source sequence is empty, the returned sequence contains a single value, which is the default value of TSource type:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;The other overload of DefaultIfEmpty allows to specify what default value to use if the source sequence is empty:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TSource defaultValue);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void DefaultIfEmpty()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Empty&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;singletonIfEmpty = source.DefaultIfEmpty(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;singletonIfEmpty.WriteLines(); // Execute query: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyWithDefaultValue()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Empty&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;singletonIfEmpty = source.DefaultIfEmpty(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;singletonIfEmpty.WriteLines(); // Execute query. 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;DefaultIfEmpty is also commonly used in left outer join, which is discussed later.&lt;/p&gt;
&lt;h3&gt;Filtering (restriction)&lt;/h3&gt;
&lt;p&gt;As demonstrated earlier, Where filters the values in the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;Its predicate parameter is a callback function. When the query is executed, predicate is called with each value in the source sequence, and output a bool value. If output is true, this value is kept in the query result sequence; if output is false, this value is ignored. For example, the following query filters all types in .NET core library to get all primitive type:&lt;/p&gt;
&lt;p&gt;private static readonly Assembly CoreLibrary = typeof(object).Assembly;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Where()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt; primitives = source.Where(type =&amp;gt; type.IsPrimitive); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;primitives.WriteLines(); // Execute query. System.Boolean System.Byte System.Char System.Double ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the equivalent query expression has a where clause:&lt;/p&gt;
&lt;p&gt;internal static void Where()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt;source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt;primitives = from type in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where type.IsPrimitive
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select type;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload of Where accepts an indexed predicate function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;Here each time predicate is called with 2 parameters, a value in source sequence, and this value’s index in source sequence. For example:&lt;/p&gt;
&lt;p&gt;internal static void WhereWithIndex()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = new string[] { &quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;even = source.Where((value, index) =&amp;gt; index % 2 == 0); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;even.WriteLines(); // Execute query. zero two four
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The indexed Where overload is not supported in query expression syntax.&lt;/p&gt;
&lt;p&gt;The other filtering query method is OfType. OfType is not supported in query expression either. It simply filters values by the specified type parameter:&lt;/p&gt;
&lt;p&gt;internal static void OfType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;object&amp;gt;source = new object[] { 1, 2, &apos;a&apos;, &apos;b&apos;, &quot;aa&quot;, &quot;bb&quot;, new object() };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;strings = source.OfType&amp;lt;string&amp;gt;(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;strings.WriteLines(); // Execute query. aa bb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Mapping (projection)&lt;/h3&gt;
&lt;p&gt;Similar to Where, Select has 2 overloads, one accepts a selector function, the other one has an indexed selector function:&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, TResult&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;When the query is executed, the selector function is called with each TSource value, and map it to a TResult result in the output sequence. In the indexed overload, selector is also called with TSource value’s index. For example, the following Select query maps each integer to a formatted string that represents the integer’s square root:&lt;/p&gt;
&lt;p&gt;internal static void Select()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;squareRoots = source.Select(int32 =&amp;gt; $&quot;{Math.Sqrt(int32):0.00}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;squareRoots.WriteLines(); // Execute query. 0.00 1.00 1.41 1.73 2.00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The equivalent query expression is a select clause with a single from clause:&lt;/p&gt;
&lt;p&gt;internal static void Select()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;squareRoots = from int32 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{Math.Sqrt(int32):0.00}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Query expression must end with either a select clause, or group clause (discussed below). If there are other clauses between the starting from clause and the ending select clause, and the ending select clause simply has the value from the source sequence, then that ending select clause is ignored and is not compiled to a Select query method call. Above where query expression is such an example.&lt;/p&gt;
&lt;p&gt;The following is an example of the indexed overload:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;string&amp;gt; Words() =&amp;gt; new string[] { &quot;Zero&quot;, &quot;one&quot;, &quot;Two&quot;, &quot;three&quot;, &quot;four&quot; };&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectWithIndex()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var mapped = source.Select((value, index) =&amp;gt; new
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Index = index,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Word = value.ToLowerInvariant()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}); // Define query: IEnumerable&amp;lt;(string Word, int Index)&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mapped.WriteLines(result =&amp;gt; $&quot;{result.Index}:{result.Word}&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 0:zero 1:one 2:two 3:three 4:four
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here selector returns anonymous type. As a result, Select returns a sequence of anonymous type, and var has to be used.&lt;/p&gt;
&lt;p&gt;As discussed in the Immutability chapter, let clause is also compiled to Select query with a selector function returning anonymous type:&lt;/p&gt;
&lt;p&gt;internal static void Let()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(-2, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;absoluteValues = from int32 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let abs = Math.Abs(int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where abs &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;Math.Abs({int32}) == {abs}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The compiled Select query returns a (int int32, int abs) anonymous type:&lt;/p&gt;
&lt;p&gt;internal static void CompiledLet()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(-2, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;absoluteValues = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; new { int32 = int32, abs = Math.Abs(int32) })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(anonymous =&amp;gt; anonymous.abs &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(anonymous =&amp;gt; $&quot;Math.Abs({anonymous.int32}):{anonymous.abs}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;absoluteValues.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Math.Abs(-2):2 Math.Abs(-1):1 Math.Abs(1):1 Math.Abs(2):2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SelectMany has 4 overloads. Similar to Where and Select, the following 2 overloads accept unindexed and indexed selector:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;selector);&lt;/p&gt;
&lt;p&gt;In contrast with Select, SelectMany’s selector is a one to many mapping. If there are N values from the source sequence, then they are mapped to N sequences. And eventually, SelectMany concatenates these N sequences into one single sequence. The following example calls SelectMany to query all members of all types in .NET core library, then filter the obsolete members (members with [Obsolete]):&lt;/p&gt;
&lt;p&gt;internal static MemberInfo[] GetDeclaredMembers(this Type type) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type.GetMembers(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool IsObsolete(this MemberInfo member) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;member.IsDefined(attributeType: typeof(ObsoleteAttribute), inherit: false);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectMany()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt;source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;MemberInfo&amp;gt;oneToManyMapped = source.SelectMany(type =&amp;gt; type.GetDeclaredMembers()); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;MemberInfo&amp;gt; filtered = oneToManyMapped.Where(member =&amp;gt; member.IsObsolete()); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;filtered.WriteLines(obsoleteMember =&amp;gt; $&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// foreach (MemberInfo obsoleteMember in filtered)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Trace.WriteLine($&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Enum:System.String ToString(System.String, System.IFormatProvider)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Enum:System.String ToString(System.IFormatProvider)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, the above SelectMany, Where, and are both extension methods for IEnumerable&amp;lt;T&amp;gt;, and they both return IEnumerable&amp;lt;T&amp;gt;, so that above LINQ query can be fluent, as expected:&lt;/p&gt;
&lt;p&gt;internal static void FluentSelectMany()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;MemberInfo&amp;gt; mappedAndFiltered = CoreLibrary
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(type =&amp;gt; type.GetDeclaredMembers())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(member =&amp;gt; member.IsObsolete()); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mappedAndFiltered.WriteLines(obsoleteMember =&amp;gt; $&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the equivalent query expression has 2 from clauses:&lt;/p&gt;
&lt;p&gt;internal static void SelectMany()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;MemberInfo&amp;gt;mappedAndFiltered =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from type in CoreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from member in type.GetPublicDeclaredMembers()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where member.IsObsolete()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select member;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Generally, SelectMany can flatten a hierarchical 2-level-sequence into a flat 1-level-sequence. In these examples, the source sequence is hierarchical – it has many types, and each type can have a sequence of many members. SelectMany flattens the hierarchy, and concatenates many sequences of members into a single sequence of members.&lt;/p&gt;
&lt;p&gt;The other 2 SelectMany overloads accept 2 selector functions:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TCollection, TResult&amp;gt;resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, int, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TSource, TCollection, TResult&amp;gt;resultSelector);&lt;/p&gt;
&lt;p&gt;They accept 2 selector functions. The collection selector (non-indexed and index) maps source sequence’s each TSource value to many TCollection values (an IEnumerable&amp;lt;TCollection&amp;gt; sequence), and the result selector maps each TCollection value and its original TSource value to a TResult value. So eventually they still return a sequence of TResult values. For example, the following example use result selector to map type and member to string representation:&lt;/p&gt;
&lt;p&gt;internal static void SelectManyWithResultSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; obsoleteMembers = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;collectionSelector: type =&amp;gt; type.GetDeclaredMembers(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (type, member) =&amp;gt; new { Type = type, Member = member })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(typeAndMember =&amp;gt; typeAndMember.Member.IsObsolete())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(typeAndMember =&amp;gt; $&quot;{typeAndMember.Type}:{typeAndMember.Member}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The equivalent query expression has 2 from clauses for the SelectMany query, a where clause for Where, and 1 select query for Select:&lt;/p&gt;
&lt;p&gt;internal static void SelectManyWithResultSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt;source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;obsoleteMembers =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from type in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from member in type.GetDeclaredMembers()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where member.IsObsolete()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{type}:{member}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The collection selector function returns a sequence, which can be queried too. Here the Where query logically filters the obsolete member can be equivalently applied to the collection selector, which is called a subquery:&lt;/p&gt;
&lt;p&gt;internal static void SelectManyWithResultSelectorAndSubquery()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; obsoleteMembers = source.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;collectionSelector: type =&amp;gt; type.GetDeclaredMembers().Where(member =&amp;gt; member.IsObsolete()),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (type, obsoleteMember) =&amp;gt; $&quot;{type}:{obsoleteMember}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;obsoleteMembers.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The equivalent query expression has a sub query expression for Where:&lt;/p&gt;
&lt;p&gt;internal static void SelectManyWithResultSelectorAndSubquery()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt;source = CoreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;obsoleteMembers =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from type in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from obsoleteMember in (from member in type.GetDeclaredMembers()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where member.IsObsolete()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select member)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{type}:{obsoleteMember}&quot;; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;obsoleteMembers.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SelectMany is a very powerful query method, and the multiple from clauses is also a powerful syntax to build a functional workflow. This is discussed in the Category Theory chapters.&lt;/p&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;The GroupBy method has 8 overloads. The minimum requirement is to specified a key selector function, which is called with each value in the source sequence, and return a key:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);&lt;/p&gt;
&lt;p&gt;Each value from the source sequence is mapped to a key by calling the keys elector. If 2 keys are equal, these 2 source values are in the same group. Take the following persons as example:&lt;/p&gt;
&lt;p&gt;internal class Person&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Person(string name, string placeOfBirth)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Name = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.PlaceOfBirth = placeOfBirth;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string PlaceOfBirth { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;Person&amp;gt; Persons() =&amp;gt; new Person[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Person(name: &quot;Robert Downey Jr.&quot;, placeOfBirth: &quot;US&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Person(name: &quot;Tom Hiddleston&quot;, placeOfBirth: &quot;UK&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Person(name: &quot;Chris Hemsworth&quot;, placeOfBirth: &quot;AU&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Person(name: &quot;Chris Evans&quot;, placeOfBirth: &quot;US&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Person(name: &quot;Paul Bettany&quot;, placeOfBirth: &quot;UK&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These Person instances represent actors of Marvel Cinematic Universe. They can be simply grouped by their place of birth:&lt;/p&gt;
&lt;p&gt;internal static void GroupBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt;groups = source.GroupBy(person =&amp;gt; person.PlaceOfBirth); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;string, Person&amp;gt; group in groups) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{group.Key}: &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Person person in group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{person.Name}, &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Robert Downey Jr., Chris Evans,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Tom Hiddleston, Paul Bettany,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// AU: Chris Hemsworth,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupBy returns IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt;. The following is the definition of IGrouping&amp;lt;TKey, TElement&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IGrouping&amp;lt;out TKey, out TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey Key { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is just an IEnumerable&amp;lt;T&amp;gt; sequence with an additional Key property. So, above GroupBy returns a hierarchical sequence. It is a sequence of groups, where each group is a sequence of values. The equivalent query expression is a group clause:&lt;/p&gt;
&lt;p&gt;internal static void GroupBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt;groups = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person by person.PlaceOfBirth;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;GroupBy can also accepts a result selector function to map each group and its key to a result in the returned sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector);&lt;/p&gt;
&lt;p&gt;This overload, does not return of hierarchical sequence of groups, but flattened sequence of result values:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithResultSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;groups = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: person =&amp;gt; person.PlaceOfBirth,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (key, group) =&amp;gt; $&quot;{key}:{group.Count()}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groups.WriteLines(); // Execute query. US:2 UK:2 AU:1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This overload is directly not supported by query expression. However, its result selector can be equivalently applied with an additional Select query:&lt;/p&gt;
&lt;p&gt;internal static void GroupByAndSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt;groups = source.GroupBy(person =&amp;gt; person.PlaceOfBirth);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;mapped = groups.Select(group =&amp;gt; $&quot;{group.Key}: {group.Count()}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groups.WriteLines(); // Execute query. US:2 UK:2 AU:1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As just demonstrated, this GroupBy overload is equivalent to query expression with a group clause, and Select can be compiled from a select clause:&lt;/p&gt;
&lt;p&gt;internal static void GroupByAndSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt;groups = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person by person.PlaceOfBirth;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;mapped = from @group in groups
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{@group.Key}: {@group.Count()}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here @ is prepended to the @group identifier, because group is a query keyword. By removing the groups variable, the first query expression becomes the second query expression’s subquery:&lt;/p&gt;
&lt;p&gt;internal static void FluentGroupByAndSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;mapped = from @group in (from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person by person.PlaceOfBirth)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{@group.Key}: {@group.Count()}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above expression is nested rather than fluent. So, the into query keyword is provided for continuation like this:&lt;/p&gt;
&lt;p&gt;internal static void GroupByAndSelectWithInto()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;mapped = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person by person.PlaceOfBirth into @group
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{@group.Key}: {@group.Count()}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The compilation of the above 2 query expressions are identical.&lt;/p&gt;
&lt;p&gt;GroupBy can also accept an element selector function to map each value in the source sequence in the source sequence to a result value in the group:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithElementSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, string&amp;gt;&amp;gt;groups = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: person =&amp;gt; person.PlaceOfBirth,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: person =&amp;gt; person.Name); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;string, string&amp;gt; group in groups) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{group.Key}: &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string name in group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{name}, &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Robert Downey Jr., Chris Evans,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Tom Hiddleston, Paul Bettany,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// AU: Chris Hemsworth,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In query expression, the element selector can be specified after the group keyword:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithElementSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, string&amp;gt;&amp;gt;groups = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person.Name by person.PlaceOfBirth;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And element selector can be used with result selector:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector);&lt;/p&gt;
&lt;p&gt;Again, result selector can flatten the hierarchical sequence:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithElementAndResultSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;groups = source.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: person =&amp;gt; person.PlaceOfBirth,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: person =&amp;gt; person.Name,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (key, group) =&amp;gt; $&quot;{key}: {string.Join(&quot;, &quot;, group)}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groups.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Robert Downey Jr., Chris Evans
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Tom Hiddleston, Paul Bettany
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// AU: Chris Hemsworth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to SelectMany, GroupBy with both element selector and result selector is not directly supported in query expression. The result selector logic can be done with a select continuation:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithElementSelectorAndSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;groups = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group person.Name by person.PlaceOfBirth into @group
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{@group.Key}: {string.Join(&quot;,&quot;, @group)}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The rest 4 overloads accept an IEqualityComparer&amp;lt;TKey&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer);&lt;/p&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt; provides the methods to determine whether 2 keys are equal when grouping all keys:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEqualityComparer&amp;lt;in T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool Equals(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int GetHashCode(T obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void GroupByWithEqualityComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;groups = source.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: person =&amp;gt; person.PlaceOfBirth,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: person =&amp;gt; person.Name,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (key, group) =&amp;gt; $&quot;{key}:{string.Join(&quot;,&quot;, group)}&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer: StringComparer.OrdinalIgnoreCase); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groups.WriteLines(); // Execute query. US:2 UK: 2 AU: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These 4 overloads are not supported by query expression.&lt;/p&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;p&gt;The most common join operations are inner join, left outer join and cross join. LINQ provides Join query method for inner join, and provides GroupJoin for left outer join. Cross join can be easily done with SelectMany or Join.&lt;/p&gt;
&lt;h4&gt;Inner join&lt;/h4&gt;
&lt;p&gt;Join is designed for inner join:&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt; comparer)&lt;/p&gt;
&lt;p&gt;Each outer value from the outer source is mapped to an outer key by calling the outer key selector, and each inner value from the inner source is mapped to an inner key. When an outer key is equal to an inner key, the source outer value and the matching source inner value are paired, and mapped to a result by calling the result selector. So each outer value with a matching inner value is mapped to a result in the returned sequence, and each outer value without a matching inner value is ignored. Take the following characters as example:&lt;/p&gt;
&lt;p&gt;internal partial class Character&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Character(string name, string placeOfBirth, string starring)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Name = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.PlaceOfBirth = placeOfBirth;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Starring = starring;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string PlaceOfBirth { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Starring { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;Character&amp;gt; Characters() =&amp;gt; new Character[]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Character(name: &quot;Tony Stark&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Robert Downey Jr.&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Character(name: &quot;Thor&quot;, placeOfBirth: &quot;Asgard&quot;, starring: &quot;Chris Hemsworth&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Character(name: &quot;Steve Rogers&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Chris Evans&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Character(name: &quot;Vision&quot;, placeOfBirth: &quot;KR&quot;, starring: &quot;Paul Bettany&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Character(name: &quot;JARVIS&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Paul Bettany&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These Character instances represent characters in the movie Avengers 2, and can be joined with actors. When a character from outer sequence matches an actor from inner sequence by cast, these 2 values are paired and mapped to the result sequence:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin = outer.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: person =&amp;gt; person.Name,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: character =&amp;gt; character.Starring,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (person, character) =&amp;gt; $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerJoin.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr. (US): Tony Stark
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Hemsworth (AU): Thor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans (US): Steve Rogers
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): Vision
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): JARVIS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the inner join results, the name “Tom Hiddleston” does not exist in the results, because the person with this name cannot match with any character’s starring (Tom Hiddleston is the actor of Loki, who is in Avengers 1 but not in Avengers 2). And the name “Paul Bettany” appears twice in the results, because the person with this name matches 2 characters’ starring (Paul Bettany is the voice of JARVIS and the actor of Vision). The equivalent query expression has a join clause:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join character in inner on person.Name equals character.Starring
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the above example, the outer value and the inner value are matched with a single key - Person.Name property and Character.Starring property. To match with multiple keys, just have both outer key selector and inner key selector return the same anonymous type with multiple properties:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithMultipleKeys()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin = outer.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: person =&amp;gt; new { Starring = person.Name, PlaceOfBirth = person.PlaceOfBirth },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: character =&amp;gt; new { Starring = character.Starring, PlaceOfBirth = character.PlaceOfBirth },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (person, character) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name} ({character.PlaceOfBirth})&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerJoin.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr. (US): Tony Stark (US)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans (US): Steve Rogers (US)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Anonymous type can be also used with join clause in query expression:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithMultiKeys()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join character in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;on new { Starring = person.Name, PlaceOfBirth = person.PlaceOfBirth }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;equals new { Starring = character.Starring, PlaceOfBirth = character.PlaceOfBirth }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name} ({character.PlaceOfBirth})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h4&gt;Left outer join&lt;/h4&gt;
&lt;p&gt;GroupJoin is designed for left outer join:&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt; comparer)&lt;/p&gt;
&lt;p&gt;Each outer value from the outer source is mapped to an outer key by calling the outer key selector, and each inner value from the inner source is mapped to an inner key. When an outer key is equal to zero, one, or more inner key, the source outer value and all the matching source inner values are paired, and mapped to a result by calling the result selector. So each outer value with or without matching inner values is mapped to a result in the returned sequence. It is called GroupJoin, because each outer value is paired with a group of matching inner values. If there is no matching inner value, the outer value is paired with an empty group:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin = outer.GroupJoin(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: person =&amp;gt; person.Name,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: character =&amp;gt; character.Starring,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (person, charactersGroup) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new { Person = person, Characters = charactersGroup }); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (var result in leftOuterJoin) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{result.Person.Name} ({result.Person.PlaceOfBirth}): &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Character character in result.Characters)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{character.Name} ({character.PlaceOfBirth}), &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr. (US): Tony Stark (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Tom Hiddleston (UK):
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Hemsworth (AU): Thor (Asgard),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans (US): Steve Rogers (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): Vision (KR), JARVIS (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here result selector is called with each actor, and a group of matching characters, then it returns anonymous type consists of both the actor and the matching characters. So eventually GroupJoin returns a hierarchical sequence. In the results, the person with name “Tom Hiddleston” matches no character, so it is paired with an empty Character group, and each other person matches 1 or more characters, so is paired with a non-empty Character group. In query expression, GroupJoin is equivalent to join clause with the into keyword:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join character in inner on person.Name equals character.Starring into charactersGroup
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select new { Person = person, Characters = charactersGroup };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the join clause, into does not mean a continuation. it is a part of the join.&lt;/p&gt;
&lt;p&gt;The hierarchical sequence returned by GroupJoin can be flattened by SelectMany. In this kind of flattening scenario, DefaultIfEmpty is usually used:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithDefaultIfEmpty()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin = outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupJoin(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: person =&amp;gt; person.Name,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: character =&amp;gt; character.Starring,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (person, charactersGroup) =&amp;gt; new { Person = person, Characters = charactersGroup })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;collectionSelector: group =&amp;gt; group.Characters.DefaultIfEmpty(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (group, character) =&amp;gt; new { Person = group.Person, Character = character }); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;leftOuterJoin.WriteLines(result =&amp;gt; $&quot;{result.Person.Name}: {result.Character?.Name}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr.: Tony Stark
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Tom Hiddleston:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Hemsworth: Thor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans: Steve Rogers
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany: Vision
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany: JARVIS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Without the DefaultIfEmpty call, the second result “Tom Hiddleston” is ignored in the result sequence. The equivalent query expression has 2 from clauses for SelectMany:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithDefaultIfEmpty()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join character in inner on person.Name equals character.Starring into charactersGroup
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from character in charactersGroup.DefaultIfEmpty()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select new { Person = person, Character = character };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There is already a from clause before join clause, so, just add one more from clause after join clause.&lt;/p&gt;
&lt;p&gt;Left outer join can also implement by mapping each outer value with all filtered matching inner values:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin = outer.Select(person =&amp;gt; new
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Person = person,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Characters = inner.Where(character =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (var result in leftOuterJoin) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{result.Person.Name} ({result.Person.PlaceOfBirth}): &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Character character in result.Characters)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{character.Name} ({character.PlaceOfBirth}), &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr. (US): Tony Stark (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Tom Hiddleston (UK):
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Hemsworth (AU): Thor (Asgard),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans (US): Steve Rogers (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): Vision (KR), JARVIS (US),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice here the Where subquery filters all inner values for each outer value. Generally, left outer join can be implemented with mapping query and filtering subquery:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; LeftOuterJoinWithSelect&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return outer.Select(outerValue =&amp;gt; resultSelector(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerValue,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner.Where(innerValue =&amp;gt; comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue)))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In query expression, it just a simple query expression with a select clause containing a subquery with a where clause:&lt;/p&gt;
&lt;p&gt;internal static void LeftOuterJoinWithSelect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var leftOuterJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select new
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Person = person,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Characters = from character in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select character
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; LeftOuterJoinWithSelect&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return from outerValue in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select resultSelector(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerValue,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(from innerValue in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select innerValue));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The difference is, for N outer values, GroupJoin pull all inner values once and cache them, Select and Where does not cache anything and pull all inner values N times. The internal implementation of these query methods are discussed later in this chapter.&lt;/p&gt;
&lt;h4&gt;Cross Join&lt;/h4&gt;
&lt;p&gt;Cross join 2 sequences is to return the Cartesian product of values in those 2 sequences. The easiest way for cross join is SelectMany:&lt;/p&gt;
&lt;p&gt;private static readonly int[] Rows = { 1, 2, 3 };&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static readonly string[] Columns = { &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoin()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;cells = Rows
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(row =&amp;gt; Columns, (row, column) =&amp;gt; $&quot;{column}{row}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int cellIndex = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int columnCount = Columns.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string cell in cells) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{cell} &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (++cellIndex % columnCount == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// A1 B1 C1 D1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// A2 B2 C2 D2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// A3 B3 C3 D3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice here all inner values are pulled for each outer value. If outer sequence has N outer values, then the inner sequence are iterated N times. In query expression, as fore mentioned, 2 from clauses are compiled to SelectMany:&lt;/p&gt;
&lt;p&gt;internal static void CrossJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;cells = from row in Rows
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from column in Columns
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{column}{row}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A general CrossJoin query method can be implemented as:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outer.SelectMany(outerValue =&amp;gt; inner, resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// from outerValue in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// from innerValue in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// select resultSelector(outerValue, innerValue);&lt;/p&gt;
&lt;p&gt;Cross join can also be done with Join, with inner key always equal to outer key, so that each outer value matches all inner values:&lt;/p&gt;
&lt;p&gt;internal static void CrossJoinWithJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;cells = Rows.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: Columns,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: row =&amp;gt; true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: column =&amp;gt; true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (row, column) =&amp;gt; $&quot;{column}{row}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int cellIndex = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int columnCount = Columns.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string cell in cells) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{cell} &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (++cellIndex % columnCount == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And generally, cross join can be implemented by Join as:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoinWithJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outer.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: outerValue =&amp;gt; true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: innerValue =&amp;gt; true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: resultSelector); // Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// from outerValue in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// join innerValue in inner on true equals true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// select resultSelector(outerValue, innerValue);&lt;/p&gt;
&lt;p&gt;In query expression, again, Join is just a join clause without into:&lt;/p&gt;
&lt;p&gt;internal static void CrossJoinWithJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;cells = from row in Rows
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join column in Columns on true equals true
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{column}{row}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoinWithJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from outerValue in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join innerValue in inner on true equals true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;select resultSelector(outerValue, innerValue);&lt;/p&gt;
&lt;p&gt;The above inner join can be logically viewed as cross join with filtering the matching outer value and inner value. The above inner join of persons and characters can be implemented with SelectMany and Where as:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelectMany()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin = outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;collectionSelector: person =&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (person, character) =&amp;gt; new { Person = person, Character = character })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(crossJoinValue =&amp;gt; EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;crossJoinValue.Person.Name, crossJoinValue.Character.Starring))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(innerJoinValue =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{innerJoinValue.Person.Name} ({innerJoinValue.Person.PlaceOfBirth}): {innerJoinValue.Character.Name}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerJoin.WriteLines(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Robert Downey Jr. (US): Tony Stark
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Hemsworth (AU): Thor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Chris Evans (US): Steve Rogers
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): Vision
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Paul Bettany (UK): JARVIS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Generally, inner join and be implemented with cross join and filtering:&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; InnerJoinWithSelectMany&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;collectionSelector: outerValue =&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (outerValue, innerValue) =&amp;gt; new { OuterValue = outerValue, InnerValue = innerValue })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;crossJoinValue =&amp;gt; comparer.Equals(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector(crossJoinValue.OuterValue),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector(crossJoinValue.InnerValue)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(innerJoinValue =&amp;gt; resultSelector(innerJoinValue.OuterValue, innerJoinValue.InnerValue));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In query expression, as fore mentioned, SelectMany is 2 from clauses:&lt;/p&gt;
&lt;p&gt;internal static void InnerJoinWithSelectMany()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;outer = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Character&amp;gt;inner = Characters();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from person in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from character in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; InnerJoinWithSelectMany&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TOuter&amp;gt; outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TInner&amp;gt;inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TOuter, TInner, TResult&amp;gt;resultSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return from outerValue in outer,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from innerValue in inner
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select resultSelector(outerValue, innerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The difference is, for N outer values, Join pull all inner values once and cache them, SelectMany does not cache anything and pull all inner values N times. Again, the internal implementation of these query methods is discussed later in this chapter.&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;Concat merges 2 sequences by putting the second sequence’s values after the first sequence’s values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static int[] First() =&amp;gt; new int[] { 1, 2, 3, 4, 4 };&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int[] Second() =&amp;gt; new int[] { 3, 4, 5, 6 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Concat()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;second = Second();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;concat = first.Concat(second); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;concat.WriteLines(); // Execute query. 1 2 3 4 4 3 4 5 6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET Core provides Prepend/Append, which merge the specified value to the beginning/end of the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Prepend&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element);&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Append&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void AppendPrepend()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;prepend = Enumerable.Range(0, 5).Prepend(-1); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;prepend.WriteLines(); // Execute query. -1 0 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; append = Enumerable.Range(0, 5).Append(-1); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;append.WriteLines(); // Execute query. 0 1 2 3 4 -1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;Distinct accepts a source sequence, and returns a set, where duplicate values are removed:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Distinct()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;distinct = first.Distinct(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;distinct.WriteLines(); // Execute query. 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following query methods accepts 2 sequences and returns a set:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);&lt;/p&gt;
&lt;p&gt;In contrast to Concat, Union adds 2 sequences as if they are sets, and returns their set union, which is equivalent to concatenating 2 sequences with duplicate values removed:&lt;/p&gt;
&lt;p&gt;internal static void Union()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;second = Second();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;union = first.Union(second); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;union.WriteLines(); // Execute query. 1 2 3 4 5 6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Intersect returns 2 sequences’ set intersection, the distinct values that 2 sequences have in common:&lt;/p&gt;
&lt;p&gt;internal static void Intersect()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;second = Second();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;intersect = first.Intersect(second); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;intersect.WriteLines(); // Execute query. 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Except returns the set complement of 2 sequences, by subtracting the second sequence from the first one:&lt;/p&gt;
&lt;p&gt;internal static void Except()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;second = Second();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;except = first.Except(second); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;except.WriteLines(); // Execute query. 1 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There are other overloads that accepts a comparer:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void DistinctWithComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = new string[] { &quot;aa&quot;, &quot;AA&quot;, &quot;Aa&quot;, &quot;aA&quot;, &quot;bb&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;distinctWithComparer = source.Distinct(StringComparer.OrdinalIgnoreCase); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;distinctWithComparer.WriteLines(); // Execute query. aa bb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Convolution&lt;/h3&gt;
&lt;p&gt;Zip is provided since .NET Framework 4.0. It accepts 2 sequences and returns their convolution:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TFirst&amp;gt; first, IEnumerable&amp;lt;TSecond&amp;gt; second, Func&amp;lt;TFirst, TSecond, TResult&amp;gt; resultSelector);&lt;/p&gt;
&lt;p&gt;It calls result selector to map 2 values (each value from each sequence) to a result in the returned sequence:&lt;/p&gt;
&lt;p&gt;internal static void Zip()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;first = First();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;second = Second();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;zip = first.Zip(second, (a, b) =&amp;gt; a + b); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;zip.WriteLines(); // Execute query. 4 6 8 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When one input sequence has more values than the other, those values are ignored. Here the first sequence { 1, 2, 3, 4, 4 } and second sequence { 3, 4, 5, 6 } are zipped to a new sequence { 1 + 3, 2 + 4, 3 + 5, 4 + 6 }. The first sequence has one more value than the second, so its last value 4 is ignored.&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Partitioning query methods are straightforward. Skip/Take simply skips/takes the specified number of values in the source sequence:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void SkipTake()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; partition1 = source.Skip(2); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition1.WriteLines(); // Execute query. 2 3 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; partition2 = source.Take(2); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition2.WriteLines(); // Execute query. 0 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SkipWhile/TakeWhile accept a predicate function:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);&lt;/p&gt;
&lt;p&gt;SkipWhile/TakeWhile skips/takes values while predicate is called with each value and returns true. Once predicate is called with a value and returns false, SkipWhile/TakeWhile stop partitioning:&lt;/p&gt;
&lt;p&gt;internal static void TakeWhileSkipWhile()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = new int[] { 1, 2, 3, -1, 4, 5 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;partition1 = source.TakeWhile(int32 =&amp;gt; int32 &amp;gt; 0); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition1.WriteLines(); // Execute query. 1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; partition2 = source.SkipWhile(int32 =&amp;gt; int32 &amp;gt; 0); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition2.WriteLines(); // Execute query. -1 4 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Just like Where and Select, SkipWhile/TakeWhile also have the indexed overload:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void TakeWhileSkipWhileWithIndex()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = new int[] { 4, 3, 2, 1, 5 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;partition1 = source.TakeWhile((int32, index) =&amp;gt; int32 &amp;gt;= index); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition1.WriteLines(); // Execute query. 4 3 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; partition2 = source.SkipWhile((int32, index) =&amp;gt; int32 &amp;gt;= index); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partition2.WriteLines(); // Execute query. 1 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;The ordering methods are OrderBy and OrderByDescending:&lt;/p&gt;
&lt;p&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)&lt;/p&gt;
&lt;p&gt;The key selector specifies what should be compared to determine the order of values in the result sequence:&lt;/p&gt;
&lt;p&gt;internal static void OrderBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;ordered = source.OrderBy(word =&amp;gt; word); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ordered.WriteLines(); // Execute query. four one three Two Zero
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.WriteLines(); // Original sequence. Zero one Two three four
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByDescending()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;ordered = source.OrderByDescending(word =&amp;gt; word); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ordered.WriteLines(); // Execute query. Zero Two three one four
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.WriteLines(); // Original sequence. Zero one Two three four
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here each value from the source sequence uses itself as the key for ordering. Also, as demonstrated above, OrderBy returns a new sequence, so OrderBy/OrderByDescending does not impact the source sequence. The equivalent query expression has an orderby clause:&lt;/p&gt;
&lt;p&gt;internal static void OrderBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;ordered = from word in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby word ascending // ascending can be omitted.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select word;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByDescending()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;ordered = from word in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby word descending
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select word;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The comparer can be specified to provides the method to compare 2 keys:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IComparer&amp;lt;in T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int Compare(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Compare returns an integer to determine the 2 values’ relative position in the ordered sequence. If x is less than y, Compare returns negative int value; If x is equal to y, Compare returns 0; If x is greater than y, Compare returns positive int value. For example:&lt;/p&gt;
&lt;p&gt;internal static void OrderByWithComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;source = Words();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;ordered = source.OrderBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: word =&amp;gt; word, comparer: StringComparer.Ordinal); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ordered.WriteLines(); // Execute query. Two Zero four one three
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here StringComparer.Ordinal provides a case-sensitive comparison. “Zero” comes to the first position of the result sequence, because upper case letter is less than lower case letter. This overload with comparer is not supported in query expression. When using the other overload without comparer, OrderBy/OrderByDescending uses System.Collections.Generic.Comparer&amp;lt;TKey&amp;gt;.Default. In the first OrderBy example, Comparer&amp;lt;string&amp;gt;.Default is used, which is equivalent to StringComparer.CurrentCulture.&lt;/p&gt;
&lt;p&gt;As fore mentioned, ThenBy/ThenByDescending are extension methods of IOrderedEnumerable&amp;lt;T&amp;gt;, not IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)&lt;/p&gt;
&lt;p&gt;So they can be composed right after OrderBy/OrderByDescending:&lt;/p&gt;
&lt;p&gt;internal static void ThenBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered = source // IEnumerable&amp;lt;Person&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(person =&amp;gt; person.PlaceOfBirth) // IOrderedEnumerable&amp;lt;Person&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ThenBy(person =&amp;gt; person.Name); // IOrderedEnumerable&amp;lt;Person&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ordered.WriteLines(person =&amp;gt; $&quot;{person.PlaceOfBirth}: {person.Name}&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// AU: Chris Hemsworth
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Paul Bettany
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Tom Hiddleston
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Chris Evans
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Robert Downey Jr.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the above example, persons are ordered by place of birth. If there are Person objects with the same PlaceOfBirth, they are ordered by Name. The query expression can have multiple key selectors in the orderby clause:&lt;/p&gt;
&lt;p&gt;internal static void ThenBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.PlaceOfBirth, person.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice OrderBy can also be called after calling OrderBy:&lt;/p&gt;
&lt;p&gt;internal static void OrderByAndOrderBy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(person =&amp;gt; person.PlaceOfBirth)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(person =&amp;gt; person.Name); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ordered.WriteLines(person =&amp;gt; $&quot;{person.PlaceOfBirth}: {person.Name}&quot;); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Chris Evans
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// AU: Chris Hemsworth
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Paul Bettany
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// US: Robert Downey Jr.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// UK: Tom Hiddleston
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;OrderBy with OrderBy is totally different from OrderBy with ThenBy. Here persons are ordered by place of birth. Then, all persons are ordered again by name. The equivalent query expression is:&lt;/p&gt;
&lt;p&gt;internal static void OrderByOrderBy1()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.PlaceOfBirth
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To makes it more intuitive, it can be separated to 2 query expressions:&lt;/p&gt;
&lt;p&gt;internal static void OrderByOrderBy2()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered1 = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.PlaceOfBirth
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered2 = from person in ordered1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, both orderby clauses work on the entire input sequence. As fore mentioned, the into query keyword is for this kind scenario of continuation:&lt;/p&gt;
&lt;p&gt;internal static void OrderByOrderBy3()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;source = Persons();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;ordered = from person in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.PlaceOfBirth
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person into person
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby person.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The compilation of the above 3 queries are identical.&lt;/p&gt;
&lt;p&gt;Reverse simply reverses the positions of values:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Reverse&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Reverse()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = Enumerable.Range(0, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;reversed = source.Reverse(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reversed.WriteLines(); // Execute query. 4 3 2 1 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Cast converts each value in source sequence to the specified type:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);&lt;/p&gt;
&lt;p&gt;Unlike other query methods, Cast is an extension method of non-generic sequence, so it can work with types implementing either IEnumerable or IEnumerable&amp;lt;T&amp;gt;. So it can enable LINQ query for legacy types. The following example calls Microsoft Team Foundation Service (TFS) client APIs to query work items, where Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection is returned. WorkItemCollection is a collection of Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem, but it only implements IEnumerable, so it can be cast to a generic IEnumerable&amp;lt;WorkItem&amp;gt; safely, and further LINQ query can be applied. The following example execute a WIQL (Work Item Query Language of TFS) statement to query work items from TFS. Since WIQL does not support GROUP BY clause, the work items can be grouped locally with LINQ:&lt;/p&gt;
&lt;p&gt;#if NETFX&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastNonGeneric(VssCredentials credentials)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (TfsTeamProjectCollection projectCollection = new TfsTeamProjectCollection(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Uri(&quot;https://dixin.visualstudio.com/DefaultCollection&quot;), credentials))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WorkItemCollection implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string Wiql = &quot;SELECT * FROM WorkItems WHERE [Work Item Type] = &apos;Bug&apos; AND State != &apos;Closed&apos;&quot;; // WIQL does not support GROUP BY.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WorkItemStore workItemStore = (WorkItemStore)projectCollection.GetService(typeof(WorkItemStore));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WorkItemCollection workItems = workItemStore.Query(Wiql);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;WorkItem&amp;gt;genericWorkItems = workItems.Cast&amp;lt;WorkItem&amp;gt;(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, WorkItem&amp;gt;&amp;gt; workItemGroups = genericWorkItems
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(workItem =&amp;gt; workItem.CreatedBy); // Group work items locally.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#endif&lt;/p&gt;
&lt;p&gt;The other non-generic sequences, like System.Resources.ResourceSet, System.Resources.ResourceReader, can be cast in the same way:&lt;/p&gt;
&lt;p&gt;internal static void CastMoreNonGeneric()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ResourceSet implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ResourceSet resourceSet = new ResourceManager(typeof(Resources))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetResourceSet(CultureInfo.CurrentCulture, createIfNotExists: true, tryParents: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;DictionaryEntry&amp;gt;entries1 = resourceSet.Cast&amp;lt;DictionaryEntry&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ResourceReader implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly assembly = typeof(QueryMethods).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Stream stream = assembly.GetManifestResourceStream(assembly.GetManifestResourceNames()[0]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (ResourceReader resourceReader = new ResourceReader(stream))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;DictionaryEntry&amp;gt;entries2 = resourceReader.Cast&amp;lt;DictionaryEntry&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In query expression syntax, just specify the type in from clause before the value name:&lt;/p&gt;
&lt;p&gt;#if NETFX&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastNonGeneric(VssCredentials credentials)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// WorkItemCollection implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (TfsTeamProjectCollection projectCollection = new TfsTeamProjectCollection(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Uri(&quot;https://dixin.visualstudio.com/DefaultCollection&quot;), credentials))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string Wiql = &quot;SELECT * FROM WorkItems WHERE [Work Item Type] = &apos;Bug&apos; AND State != &apos;Closed&apos;&quot;; // WIQL does not support GROUP BY.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WorkItemStore workItemStore = (WorkItemStore)projectCollection.GetService(typeof(WorkItemStore));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WorkItemCollection workItems = workItemStore.Query(Wiql);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, WorkItem&amp;gt;&amp;gt;workItemGroups =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from WorkItem workItem in workItems // Cast.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group workItem by workItem.CreatedBy; // Group work items in local memory.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastMoreNonGenericI()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ResourceSet implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ResourceSet resourceSet = new ResourceManager(typeof(Resources))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GetResourceSet(CultureInfo.CurrentCulture, createIfNotExists: true, tryParents: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;DictionaryEntry&amp;gt;entries1 =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from DictionaryEntry entry in resourceSet // Cast.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select entry;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ResourceReader implements IEnumerable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly assembly = typeof(QueryMethods).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (Stream stream = assembly.GetManifestResourceStream(assembly.GetManifestResourceNames()[0]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (ResourceReader resourceReader = new ResourceReader(stream))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;DictionaryEntry&amp;gt;entries2 =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from DictionaryEntry entry in resourceReader // Cast.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select entry;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And of course Cast can be used to generic IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal static void CastGenericIEnumerable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt;source = new Base[] { new Derived(), new Derived() };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Derived&amp;gt;cast = source.Cast&amp;lt;Derived&amp;gt;(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cast.WriteLines(result =&amp;gt; result.GetType().Name); // Execute query. Derived Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the query expression syntax is the same:&lt;/p&gt;
&lt;p&gt;internal static void CastGenericIEnumerable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt;source = new Base[] { new Derived(), new Derived() };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Derived&amp;gt;cast = from Derived derived in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select derived;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Cast must be used with caution, because type conversion can fail at runtime, for example:&lt;/p&gt;
&lt;p&gt;internal static void CastGenericIEnumerableWithException()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt;source = new Base[] { new Derived(), new Base() };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Derived&amp;gt;cast = source.Cast&amp;lt;Derived&amp;gt;(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cast.WriteLines(result =&amp;gt; result.GetType().Name); // Execute query. Derived InvalidCastException
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;An InvalidCastException is thrown because the second value is of Base type, and cannot be cast to Derived.&lt;/p&gt;
&lt;p&gt;The same query expression cast syntax can also be used in join clause:&lt;/p&gt;
&lt;p&gt;internal static void CastWithJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable outer = new int[] { 1, 2, 3 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable inner = new string[] { &quot;a&quot;, &quot;bb&quot;, &quot;ccc&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin = from int int32 in outer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join string @string in inner on int32 equals @string.Length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{int32}: {@string}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is compiled to:&lt;/p&gt;
&lt;p&gt;internal static void CastWithJoin()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable outer = new int[] { 1, 2, 3 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable inner = new string[] { string.Empty, &quot;a&quot;, &quot;bb&quot;, &quot;ccc&quot;, &quot;dddd&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;innerJoin = outer.Cast&amp;lt;int&amp;gt;().Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inner: inner.Cast&amp;lt;string&amp;gt;(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outerKeySelector: int32 =&amp;gt; int32,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerKeySelector: @string =&amp;gt; @string.Length, // on int32 equal @string.Length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: (int32, @string) =&amp;gt; $&quot;{int32}:{@string}&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerJoin.WriteLines(); // Execute query. 1:a 2:bb 3:ccc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Cast looks similar to the fore mentioned OfType method, which also can have the result type specified. However, they are very different, OfType filters the values of the specified type. If there are values not of the specified type, they are simply ignored. There no conversion so there is no chance of InvalidCastException.&lt;/p&gt;
&lt;p&gt;AsEnumerable is a query method doing nothing. It accepts a source sequence, then return the source sequence itself:&lt;/p&gt;
&lt;p&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;Its purpose is to make more derived type be visible only as IEnumerable&amp;lt;T&amp;gt;, and hide additional members of that more derived type:&lt;/p&gt;
&lt;p&gt;internal static void AsEnumerable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt;list = new List&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.Add(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;sequence = list.AsEnumerable(); // Add method is no longer available.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If the more derived source has method with the same signature as IEnumerable&amp;lt;T&amp;gt;’s extension method, after calling AsEnumerable, that IEnumerable&amp;lt;T&amp;gt; extension method is called:&lt;/p&gt;
&lt;p&gt;internal static void AsEnumerableReverse()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt;list = new List&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.Reverse(); // List&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.AsEnumerable() // IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SortedSet&amp;lt;int&amp;gt; sortedSet = new SortedSet&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sortedSet.Reverse(); // SortedSet&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sortedSet.AsEnumerable().Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ReadOnlyCollectionBuilder&amp;lt;int&amp;gt; readOnlyCollection = new ReadOnlyCollectionBuilder&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readOnlyCollection.Reverse(); // ReadOnlyCollectionBuilder&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readOnlyCollection.AsEnumerable().Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;int&amp;gt; queryable = new EnumerableQuery&amp;lt;int&amp;gt;(Enumerable.Empty&amp;lt;int&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;queryable.Reverse(); // Queryable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;queryable.AsEnumerable().Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableList&amp;lt;int&amp;gt; immutableList = ImmutableList.Create(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableList.Reverse(); // ImmutableSortedSet&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableList.AsEnumerable().Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableSortedSet&amp;lt;int&amp;gt; immutableSortedSet = ImmutableSortedSet.Create(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableSortedSet.Reverse(); // ImmutableSortedSet&amp;lt;T&amp;gt;.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableSortedSet.AsEnumerable().Reverse(); // Enumerable.Reverse.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, local parallel LINQ queries are represented by ParallelQuery&amp;lt;T&amp;gt; and remote LINQ queries are represented by IQueryable&amp;lt;T&amp;gt;. They both implement IEnumerable&amp;lt;T&amp;gt;, so they both have AsEnumerable available. Since AsEnumerable returns IEnumerable&amp;lt;T&amp;gt;, it opt-out local parallel query and remote query back to local sequential query. These scenarios are discussed in Parallel LINQ chapter and LINQ to Entities chapter.&lt;/p&gt;
&lt;h3&gt;Collection queries&lt;/h3&gt;
&lt;p&gt;The collection query methods all convert source sequence to a collection by pulling all the values from the source sequence and store them in array, list, dictionary, or lookup.&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;ToArray and ToList are straightforward:&lt;/p&gt;
&lt;p&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static List&amp;lt;TSource&amp;gt; ToList&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;They pull all values from the source sequence, and simply store them into a new array/list:&lt;/p&gt;
&lt;p&gt;internal static void ToArrayToList()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] array = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5) // Define query, return IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; list = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5) // Define query, return IEnumerable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToList(); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, when collection query methods are called for an IEnumerable&amp;lt;T&amp;gt; sequence representing LINQ query, that LINQ query is executed immediately. Similarly, ToDictionary/ToLookup also pulls all values from source sequence, and store those values into a new dictionary/lookup:&lt;/p&gt;
&lt;p&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, Func&amp;lt;TSource, TElement&amp;gt; elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, Func&amp;lt;TSource, TElement&amp;gt; elementSelector);&lt;/p&gt;
&lt;p&gt;Here are the definition of dictionary and lookup:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Dictionary&amp;lt;TKey, TValue&amp;gt;: IEnumerable&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;, IEnumerable,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IDictionary&amp;lt;TKey, TValue&amp;gt;, IDictionary, ICollection&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;, ICollection,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;, IReadOnlyCollection&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ISerializable, IDeserializationCallback { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface ILookup&amp;lt;TKey, TElement&amp;gt;: IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TElement&amp;gt; this[TKey key] { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int Count { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool Contains(TKey key);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The difference between dictionary and lookup is, a dictionary is a flatten collection of key-value pairs, where each key is paired with one single value, and a lookup is a hierarchical collection of key-sequence pairs, where each key is a sequence of paired with one or more values.&lt;/p&gt;
&lt;p&gt;internal static void ToDictionaryToLookup()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;int, string&amp;gt; dictionary = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5) // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToDictionary(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;keySelector: int32 =&amp;gt; int32,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;elementSelector: int32 =&amp;gt; Math.Sqrt(int32).ToString(&quot;F&quot;, CultureInfo.InvariantCulture)); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (KeyValuePair&amp;lt;int, string&amp;gt; squareRoot in dictionary)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;√{squareRoot.Key}:{squareRoot.Value}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √0: 0.00
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √1: 1.00
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √2: 1.41
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √3: 1.73
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √4: 2.00
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;int, int&amp;gt; lookup = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(-2, 5) // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToLookup(int32 =&amp;gt; int32 * int32); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;int, int&amp;gt; squareRoots in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;√{squareRoots.Key}: &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int squareRoot in squareRoots)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{squareRoot}, &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √4: -2, 2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √1: -1, 1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// √0: 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Each value from source sequence is mapped to a key by calling the key selector function. If element selector is provided, each value from source sequence is mapped to a value in the result dictionary/lookup. In above example, if ToDictionary is called in the second query, an ArgumentException is thrown because dictionary cannot have multiple key and single value pairs with the same key:&lt;/p&gt;
&lt;p&gt;internal static void ToDictionaryWithException()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;int, int&amp;gt; lookup = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(-2, 5) // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToDictionary(int32 =&amp;gt; int32 * int32); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ArgumentException: An item with the same key has already been added.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Another difference between dictionary and lookup is, at runtime, if querying a dictionary with a non-existing key, dictionary throws KeyNotFoundException, but if querying a lookup with a non-existing key, lookup returns an empty sequence peacefully.&lt;/p&gt;
&lt;p&gt;internal static void LookupDictionary()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;int, int&amp;gt; lookup = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5) // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToLookup(int32 =&amp;gt; int32); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;group = lookup[10];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int value in group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count++;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;int, int&amp;gt; dictionary = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Range(0, 5) // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToDictionary(int32 =&amp;gt; int32); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = dictionary[10];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// KeyNotFoundException: The given key was not present in the dictionary.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The last difference is dictionary cannot have null key, while lookup can:&lt;/p&gt;
&lt;p&gt;internal static void LookupDictionaryNullKey()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;string, string&amp;gt; lookup = new string[] { &quot;a&quot;, &quot;b&quot;, null }.ToLookup(@string =&amp;gt; @string);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int count = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;group = lookup[null];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string value in group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count++;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;count.WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;string, string&amp;gt;dictionary = new string[] { &quot;a&quot;, &quot;b&quot;, null }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToDictionary(@string =&amp;gt; @string);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ArgumentNullException: Value cannot be null. Parameter name: key.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;ToDictionary/ToLookup has other overloads to accept a key comparer:&lt;/p&gt;
&lt;p&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt;keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TKey&amp;gt; keySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt;comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void ToLookupWithComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILookup&amp;lt;string, string&amp;gt; lookup = new string[] { &quot;aa&quot;, &quot;AA&quot;, &quot;Aa&quot;, &quot;aA&quot;, &quot;bb&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToLookup(@string =&amp;gt; @string, StringComparer.OrdinalIgnoreCase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;string, string&amp;gt; group in lookup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{group.Key}: &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string @string in group)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{@string}, &quot;.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Environment.NewLine.Write();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// aa: aa, AA, Aa, aA,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// bb: bb,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Value queries&lt;/h3&gt;
&lt;p&gt;These query methods pull single, partial, or all values of the source sequence to output a specified value or calculate a result with the pulled values.&lt;/p&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;Element query methods returns a single value from the source sequence. When they are called, they immediately execute the query, trying to pull values until the expected value is pulled. First/Last immediately pulls the first/last value of the source sequence.&lt;/p&gt;
&lt;p&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;And InvalidOperationException is thrown if the source sequence is empty.&lt;/p&gt;
&lt;p&gt;internal static IEnumerable&amp;lt;int&amp;gt; Int32Source() =&amp;gt; new int[] { -1, 1, 2, 3, -4 };&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;int&amp;gt;SingleInt32Source() =&amp;gt; Enumerable.Repeat(5, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;int&amp;gt;EmptyInt32Source() =&amp;gt; Enumerable.Empty&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void FirstLast()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstOfSource = Int32Source().First().WriteLine(); // -1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastOfSource = Int32Source().Last().WriteLine(); // -4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstOfSingleSource = SingleInt32Source().First().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastOfSingleSource = SingleInt32Source().Last().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstOfEmptySource = EmptyInt32Source().First(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastOfEmptySource = EmptyInt32Source().Last(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other First/Last overload accept a predicate function. They immediately call the predicate function immediately with the values, and return the first/last value where predicate function returns true:&lt;/p&gt;
&lt;p&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);&lt;/p&gt;
&lt;p&gt;Logically, source.First(predicate) is equivalent to source.Where(predicate).First(), and source.Last(predicate) is equivalent to source.Where(predicate).Last():&lt;/p&gt;
&lt;p&gt;internal static void FirstLastWithPredicate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstPositiveOfSource = Int32Source().First(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastNegativeOfSource = Int32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // -4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstPositiveOfSingleSource = SingleInt32Source().First(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastNegativeOfSingleSource = SingleInt32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstPositiveOfEmptySource = EmptyInt32Source().First(int32 =&amp;gt; int32 &amp;gt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastNegativeOfEmptySource = EmptyInt32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There are also FirstOrDefault/LastOrDefault methods:&lt;/p&gt;
&lt;p&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);&lt;/p&gt;
&lt;p&gt;When there is no first/last value available, these methods return a default value instead of throwing exception:&lt;/p&gt;
&lt;p&gt;internal static void FirstOrDefaultLastOrDefault()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstOrDefaultOfEmptySource = EmptyInt32Source().FirstOrDefault().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastOrDefaultOfEmptySource = EmptyInt32Source().LastOrDefault().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastNegativeOrDefaultOfSingleSource = SingleInt32Source().LastOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstPositiveOrDefaultOfEmptySource = EmptyInt32Source().FirstOrDefault(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int lastNegativeOrDefaultOfEmptySource = EmptyInt32Source().LastOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character lokiOrDefault = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.FirstOrDefault(character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(lokiOrDefault == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;ElementAt returns the value at the specified index:&lt;/p&gt;
&lt;p&gt;public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index);&lt;/p&gt;
&lt;p&gt;When the specified index is out of range, ArgumentOutOfRangeException is thrown.&lt;/p&gt;
&lt;p&gt;internal static void ElementAt()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt2OfSource = Int32Source().ElementAt(2).WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt9OfSource = Int32Source().ElementAt(9); // ArgumentOutOfRangeException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAtNegativeIndex = Int32Source().ElementAt(-5); // ArgumentOutOfRangeException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt0OfSingleSource = SingleInt32Source().ElementAt(0).WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt1OfSingleSource = SingleInt32Source().ElementAt(1); // ArgumentOutOfRangeException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt0OfEmptySource = EmptyInt32Source().ElementAt(0); // ArgumentOutOfRangeException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, there is ElementAtOrDefault:&lt;/p&gt;
&lt;p&gt;public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index);&lt;/p&gt;
&lt;p&gt;When there is no value available at the specified index, a default value is returned:&lt;/p&gt;
&lt;p&gt;internal static void ElementAtOrDefault()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt9OrDefaultOfSource = Int32Source().ElementAtOrDefault(9).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAtNegativeIndexOrDefault = Int32Source().ElementAtOrDefault(-5).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt1OrDefaultOfSingleSource = SingleInt32Source().ElementAtOrDefault(1).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int elementAt0OrDefaultOfEmptySource = EmptyInt32Source().ElementAtOrDefault(0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character characterAt5OrDefault = Characters().ElementAtOrDefault(5);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(characterAt5OrDefault == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Single is more strict. It pulls the single value from a singleton sequence.&lt;/p&gt;
&lt;p&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);&lt;/p&gt;
&lt;p&gt;If source sequence has no value or has more than one values, InvalidOperationException is thrown:&lt;/p&gt;
&lt;p&gt;internal static void Single()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleOfSource = Int32Source().Single(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleGreaterThan2OfSource = Int32Source().Single(int32 =&amp;gt; int32 &amp;gt; 2).WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleNegativeOfSource = Int32Source().Single(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleOfSingleSource = SingleInt32Source().Single().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleNegativeOfSingleSource = SingleInt32Source().Single(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleOfEmptySource = EmptyInt32Source().Single(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singlePositiveOfEmptySource = EmptyInt32Source().Single(int32 =&amp;gt; int32 == 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character singleCharacter = Characters().Single(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character fromAsgard = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Single(character =&amp;gt; &quot;Asgard&quot;.Equals(character.PlaceOfBirth, StringComparison.Ordinal))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // Thor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character loki = Characters().Single(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal)); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;SingleOrDefault is just slightly less strict than Single:&lt;/p&gt;
&lt;p&gt;public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;When source sequence has no value, it returns a default value. When source sequence has more than one values, it still throws InvalidOperationException:&lt;/p&gt;
&lt;p&gt;internal static void SingleOrDefault()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleOrDefaultOfSource = Int32Source().SingleOrDefault(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleNegativeOrDefaultOfSource = Int32Source().SingleOrDefault(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleNegativeOrDefaultOfSingleSource = SingleInt32Source().SingleOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singleOrDefaultOfEmptySource = EmptyInt32Source().SingleOrDefault().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int singlePositiveOrDefaultOfEmptySource = EmptyInt32Source().SingleOrDefault(int32 =&amp;gt; int32 == 0); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character singleCharacterOrDefault = Characters().SingleOrDefault(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character lokiOrDefault = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SingleOrDefault(character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(lokiOrDefault == null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Aggregate query methods pull all values from source sequence, and repeatedly call a function to accumulate those value. The easiest overload accepts an accumulator function:&lt;/p&gt;
&lt;p&gt;public static TSource Aggregate&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func);&lt;/p&gt;
&lt;p&gt;Aggregate requires the source sequence to be not empty. When the source sequence is empty, it throws InvalidOperationException. When there is only 1 single value in the source sequence, it returns that value. When there are more than 1 values, it calls the accumulator function to accumulate the first and second values to a result, and then call the accumulator function again to accumulate the previous result and the third value to another result, and so on, until all values are accumulated, eventually it returns the result of the last accumulator function call.&lt;/p&gt;
&lt;p&gt;internal static void Aggregate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int productOfSource = Int32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // ((((-1 * 1) * 2) * 3) * -4) = 24.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int productOfSingleSource = SingleInt32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32).WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int productOfEmptySource = EmptyInt32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There is another overload accepts a seed:&lt;/p&gt;
&lt;p&gt;public static TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func);&lt;/p&gt;
&lt;p&gt;With the seed provided, Aggregate does not require the source sequence to be not empty. When the source sequence is empty, it returns the seed. When the source sequence is not empty, it calls the accumulator function to accumulate the seed value and the first values to a result, and then call the accumulator function again to accumulate the previous result and the second to another result, and so on, until all values are accumulated, eventually it also returns the result of the last accumulator function call.&lt;/p&gt;
&lt;p&gt;internal static void AggregateWithSeed()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfSquaresOfSource = Int32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 31
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfSquaresOfSingleSource = SingleInt32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 25
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfSquaresOfEmptySource = EmptyInt32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The last overload accepts an additional result selector function, which is called with the last result of accumulate function:&lt;/p&gt;
&lt;p&gt;internal static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TAccumulate seed,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt;func, Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);&lt;/p&gt;
&lt;p&gt;So, source.Aggregate(seed, accumulation, resultSelector) is equivalent to resultSelector(source.Aggregate(seed, accumulation)):&lt;/p&gt;
&lt;p&gt;internal static void AggregateWithSeedAndResultSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string sumOfSquaresMessage = Int32Source()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;resultSelector: result =&amp;gt; $&quot;Sum of squares: {result}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // Sum of squares: 31
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Count returns the number of values in source sequence:&lt;/p&gt;
&lt;p&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;It is one of the most intuitive query methods:&lt;/p&gt;
&lt;p&gt;internal static void Count()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfSource = Int32Source().Count().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfSingleSource = SingleInt32Source().Count().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfEmptySource = EmptyInt32Source().Count().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfCharacters = Characters().Count().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfTypesInCoreLibrary = CoreLibrary.ExportedTypes.Count().WriteLine(); // 1523
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload accepts a predicate:&lt;/p&gt;
&lt;p&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;Similar to First/Last, source.Count(predicate) is equivalent to ource.Where(predicate).Count():&lt;/p&gt;
&lt;p&gt;internal static void CountWithPredicate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int positiveCountOfSource = Int32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int positiveCountOfSingleSource = SingleInt32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int positiveCountOfEmptySource = EmptyInt32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfConcat = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Repeat(0, int.MaxValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(Enumerable.Repeat(0, int.MaxValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(); // OverflowException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int countOfCharactersFromUS = Characters()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(character =&amp;gt; &quot;US&quot;.Equals(character.PlaceOfBirth, StringComparison.Ordinal))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;LongCount is similar to Count. It can be used for large sequence, and returns a long (System.Int64) value instead of int (System.Int32):&lt;/p&gt;
&lt;p&gt;public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void LongCount()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long longCountOfSource = Int32Source().LongCount().WriteLine(); // 5L
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long countOfConcat = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Repeat(0, int.MaxValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Concat(Enumerable.Repeat(0, int.MaxValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.LongCount()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // int.MaxValue + int.MaxValue = 4294967294L
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Max/Min also pulls all values from the source sequence of int values, and returns the minimum/maximum value:&lt;/p&gt;
&lt;p&gt;public static int Max(this IEnumerable&amp;lt;int&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static int Min(this IEnumerable&amp;lt;int&amp;gt; source);&lt;/p&gt;
&lt;p&gt;Max/Min throw InvalidOperationException if the source sequence is empty:&lt;/p&gt;
&lt;p&gt;internal static void MinMax()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int minOfSource = Int32Source().Min().WriteLine(); // -4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int maxOfSource = Int32Source().Max().WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int minOfSingleSource = SingleInt32Source().Min().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int maxOfSingleSource = SingleInt32Source().Max().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int minOfEmptySource = EmptyInt32Source().Min(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int maxOfEmptySource = EmptyInt32Source().Max(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload accepts a sequence of arbitrary type, and a selector function which maps each value to an int value for comparison:&lt;/p&gt;
&lt;p&gt;public static int Max&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;public static int Min&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, int&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;The following example queries the maximum type (type with the largest number of public members declared) in the .NET core library:&lt;/p&gt;
&lt;p&gt;internal static void MaxWithSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int mostDeclaredMembers = CoreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Max(type =&amp;gt; type.GetDeclaredMembers().Length).WriteLine(); // 311
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here each public type is mapped the count of its public members’ count number. The maximum type in .NET core library has 311 public members. Here Max returns the maximum count of members, but does not tell which type is that count from. To query the maximum type along with the member count, Aggregate can be used to pull all types and accumulate by the maximum member count:&lt;/p&gt;
&lt;p&gt;internal static void AggregateWithAnonymousTypeSeed()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(List&amp;lt;Type&amp;gt;Types, int MaxMemberCount) maxTypes = CoreLibrary.ExportedTypes.Aggregate(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;seed: (Types: new List&amp;lt;Type&amp;gt;(), MaxMemberCount: 0),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func: (currentMax, type) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Type&amp;gt;currentMaxTypes = currentMax.Types;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int currentMaxMemberCount = currentMax.MaxMemberCount;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int memberCount = type.GetDeclaredMembers().Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (memberCount &amp;gt; currentMaxMemberCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentMaxTypes.Clear();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentMaxTypes.Add(type);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentMaxMemberCount = memberCount;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else if (memberCount == currentMaxMemberCount)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// If multiple types have the same maximum member count, take all those types.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;currentMaxTypes.Add(type);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (Types: currentMaxTypes, MaxMemberCount: currentMaxMemberCount);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;maxTypes.Types.WriteLines(maxType =&amp;gt; $&quot;{maxType.FullName}:{maxTypes.MaxMemberCount}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Execute query. System.Convert:311
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the core library, System.Convert is the winner, with 311 public members declared.&lt;/p&gt;
&lt;p&gt;Besides int, Max/Min has overloads for int?, long, long?, double, double?, float, float?, decimal, decimal?. There are also overloads for arbitrary comparable type:&lt;/p&gt;
&lt;p&gt;public static TSource Max&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static TSource Min&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;They use Comparer&amp;lt;TSource&amp;gt;.Default to compare values in source sequence to determine the minimum/maximum value. Comparer&amp;lt;TSource&amp;gt;.Default requires TSource to implement at least one of IComparable and IComparable&amp;lt;TSource&amp;gt;; otherwise ArgumentException is thrown at runtime. Still take Character type as example:&lt;/p&gt;
&lt;p&gt;internal partial class Character : IComparable&amp;lt;Character&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int CompareTo(Character other) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string.Compare(this.Name, other.Name, StringComparison.Ordinal);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now Max/Min can be used with character sequence:&lt;/p&gt;
&lt;p&gt;internal static void MaxMinGeneric()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character maxCharacter = Characters().Max().WriteLine(); // Vision
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Character minCharacter = Characters().Min().WriteLine(); // JAVIS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Max/Min also have overload for arbitrary type, with a selector function to maps each value to a comparable result:&lt;/p&gt;
&lt;p&gt;public static TResult Max&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;public static TResult Min&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, TResult&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void MaxMinGenericWithSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string maxName = Characters().Max(character =&amp;gt; character.Name).WriteLine(); // Vision
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string minName = Characters().Min(character =&amp;gt; character.Name).WriteLine(); // JAVIS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, source.Max(selector) is equivalent to source.Select(selector),Max, and source.Min(selector) is equivalent to source.Select(selector).Min().&lt;/p&gt;
&lt;p&gt;Sum/Average pulls all int values from the source sequence, and calculate the sum/average of all the values. The signatures are similar to Max/Min:&lt;/p&gt;
&lt;p&gt;public static int Sum(this IEnumerable&amp;lt;int&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public static double Average(this IEnumerable&amp;lt;int&amp;gt; source);&lt;/p&gt;
&lt;p&gt;Here Average returns double instead of int. Also, when called with empty source sequence, Sum returns 0, while Average throws InvalidOperationException:&lt;/p&gt;
&lt;p&gt;internal static void SumAverage()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfSource = Int32Source().Sum().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double averageOfSource = Int32Source().Average().WriteLine(); // 0.2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfSingleSource = SingleInt32Source().Sum().WriteLine(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double averageOfSingleSource = SingleInt32Source().Average().WriteLine(); // 5.0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sumOfEmptySource = EmptyInt32Source().Sum().WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double averageOfEmptySource = EmptyInt32Source().Average().WriteLine(); // InvalidOperationException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Sum/Average has overload for arbitrary type, with a selector function to map each value to int value for calculation:&lt;/p&gt;
&lt;p&gt;public static int Sum&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;public static double Average&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt;source, Func&amp;lt;TSource, int&amp;gt; selector);&lt;/p&gt;
&lt;p&gt;The following example calculate the average count of public members declared on types in the core library, and the average count of all public members.&lt;/p&gt;
&lt;p&gt;internal static void AverageWithSelector()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double averageMemberCount = CoreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Average(type =&amp;gt; type.GetMembers().Length)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 22.0766378244747
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double averageDeclaredMemberCount = CoreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Average(type =&amp;gt; type.GetDeclaredMembers().Length)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLine(); // 11.7527812113721
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, Sum/Average also has overloads for int?, long, long?, double, double?, float, float?, decimal, decimal?.&lt;/p&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;Any determines whether the source sequence is not empty, by immediately trying to pull the first value from source sequence:&lt;/p&gt;
&lt;p&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);&lt;/p&gt;
&lt;p&gt;For example.&lt;/p&gt;
&lt;p&gt;internal static void Any()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool anyInSource = Int32Source().Any().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool anyInSingleSource = SingleInt32Source().Any().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool anyInEmptySource = EmptyInt32Source().Any().WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload accepts a predicate function.&lt;/p&gt;
&lt;p&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;Logically, source.Any(predicate) is equivalent to source.Where(predicate).Any().&lt;/p&gt;
&lt;p&gt;internal static void AnyWithPredicate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool anyNegative = Int32Source().Any(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool anyPositive = SingleInt32Source().Any(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool any0 = EmptyInt32Source().Any(_ =&amp;gt; true).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;All accepts a predicate. It also tries to pull values from the source sequence, and calls predicate function with each value. It returns true if predicate returns true for all values; otherwise, it returns false:&lt;/p&gt;
&lt;p&gt;public static bool All&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);&lt;/p&gt;
&lt;p&gt;All always returns true for empty source.&lt;/p&gt;
&lt;p&gt;internal static void All()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool allNegative = Int32Source().All(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool allPositive = SingleInt32Source().All(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool allGreaterThanMax = EmptyInt32Source().All(int32 =&amp;gt; int32 &amp;gt; int.MaxValue).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Contains determines whether source sequence contains the specified value:&lt;/p&gt;
&lt;p&gt;public static bool Contains&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource value);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void Contains()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool contains5InSource = Int32Source().Contains(5).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool contains5InSingleSource = SingleInt32Source().Contains(5).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool contains5InEmptySource = EmptyInt32Source().Contains(5).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload of Contains accepts a comparer:&lt;/p&gt;
&lt;p&gt;public static bool Contains&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, TSource value, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void ContainsWithComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool containsTwo = Words().Contains(&quot;two&quot;, StringComparer.Ordinal).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool containsTwoIgnoreCase = Words().Contains(&quot;two&quot;, StringComparer.OrdinalIgnoreCase).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to other query methods, the first overload without comparer uses EqualityComparer&amp;lt;TSource&amp;gt;.Default.&lt;/p&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;.NET has many ways to determine equality for objects:&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd183759.aspx&quot;&gt;Reference equality&lt;/a&gt;/identity: object.ReferenceEquals, == operator without override&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd183755.aspx&quot;&gt;Value equality&lt;/a&gt;/equivalence: static object.Equals, instance object.Equals, object.GetHashCode, overridden == operator, IEquatable&amp;lt;T&amp;gt;.Equals, IEqualityComparer.Equals, IEqualityComparer&amp;lt;T&amp;gt;.Equals, IComparable.Compare, IComparable&amp;lt;T&amp;gt;.Compare, IComparer.Compare, IComparer&amp;lt;T&amp;gt;.Compare&lt;/p&gt;
&lt;p&gt;· Sequential equality: Enumerable.SequentialEqual&lt;/p&gt;
&lt;p&gt;SequentialEqual query method is provided to compares the sequential equality of 2 IEnumerable&amp;lt;T&amp;gt; sequences:&lt;/p&gt;
&lt;p&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);&lt;/p&gt;
&lt;p&gt;2 sequences are sequentially equal if their length is equal, and for each index, 2 values from both sequences are equal (determined by EqualityComparer&amp;lt;TSource&amp;gt;.Default).&lt;/p&gt;
&lt;p&gt;internal static void SequentialEqual()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;object&amp;gt;first = new object[] { null, 1, &quot;2&quot;, CoreLibrary };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;object&amp;gt;second = new List&amp;lt;object&amp;gt;() { null, 1, $&quot;{1 + 1}&quot;, CoreLibrary };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool valueEqual = first.Equals(second).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool referenceEqual = object.ReferenceEquals(first, second).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool sequentialEqual = first.SequenceEqual(second.Concat(Enumerable.Empty&amp;lt;object&amp;gt;())).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Empty sequences with the same TSource type are sequentially equal:&lt;/p&gt;
&lt;p&gt;internal static void SequentialEqualOfEmpty()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Derived&amp;gt;emptyFirst = new ConcurrentQueue&amp;lt;Derived&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt;emptySecond = ImmutableHashSet.Create&amp;lt;Base&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool sequentialEqual = emptyFirst.SequenceEqual(emptySecond).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other overload accepts a comparer:&lt;/p&gt;
&lt;p&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(&lt;/p&gt;
&lt;p&gt;this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;internal static void SequentialEqualWithComparer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;first = new string[] { null, string.Empty, &quot;ss&quot;, };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt;second = new string[] { null, string.Empty, &quot;ß&quot;, };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CultureInfo.CurrentCulture = new CultureInfo(&quot;en-US&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool sequentialEqual1 = first.SequenceEqual(second, StringComparer.CurrentCulture).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool sequentialEqual2 = first.SequenceEqual(second, StringComparer.Ordinal).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, the first overload without comparer uses EqualityComparer&amp;lt;TSource&amp;gt;.Default.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses IEnumerable&amp;lt;T&amp;gt; interface, which represents LINQ to Objects source or query, then discusses each standard query in query method syntax and query expression syntax if applicable. With this detailed tutorial, reader should be able to master how to use LINQ to Objects to query data objects in memory.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (1) Local Sequential Query</title><link>https://dixin.github.io/posts/linq-to-objects-local-sequential-query/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-local-sequential-query/</guid><description>LINQ to Objects queries .NET objects in local memory of current application or service. Its data source and the queries are represented by IEnumerable&lt;T&gt; interface, and it is executed sequentially. Th</description><pubDate>Mon, 01 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;LINQ to Objects queries .NET objects in local memory of current application or service. Its data source and the queries are represented by IEnumerable&amp;lt;T&amp;gt; interface, and it is executed sequentially. This chapter introduces IEnumerable&amp;lt;T&amp;gt; interface, and discusses how to use LINQ to Object to query objects in query method syntax and query expression syntax.&lt;/p&gt;
&lt;h2&gt;Local sequential LINQ query&lt;/h2&gt;
&lt;p&gt;LINQ to Objects is local, sequential query. Local means it queries data is instances of .NET types available in the memory of current .NET application or service, not remote data like rows in a data table managed by a separate database. In .NET, IEnumerable&amp;lt;T&amp;gt; interface represents a sequence of instances of T type, so when LINQ is introduced to .NET, IEnumerable&amp;lt;T&amp;gt; is naturally reused to represent LINQ to Objects data source and query. Sequential means when LINQ to Objects query is executed, the instances from data source are processed one after another in a single threading manner instead of parallelism. In another word, LINQ to Objects query results can be pulled from IEnumerable&amp;lt;T&amp;gt; one by one.&lt;/p&gt;
&lt;h3&gt;Iterator pattern and foreach statement&lt;/h3&gt;
&lt;p&gt;If a sequence type is defined following the standard iterator pattern of object-oriented programming, the objects in the sequence can be pulled by C# foreach statement. Iterator pattern consists of a sequence (also called container of items, or aggregate of elements) and an iterator:&lt;/p&gt;
&lt;p&gt;internal abstract class Sequence&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract Iterator GetEnumerator(); // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class Iterator
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract bool MoveNext(); // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract object Current { get; } // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And their generic version is:&lt;/p&gt;
&lt;p&gt;internal abstract class GenericSequence&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract GenericIterator&amp;lt;T&amp;gt;GetEnumerator(); // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class GenericIterator&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract bool MoveNext(); // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract T Current { get; } // Must be public.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above types and members demonstrate the minimum requirements of iterator pattern for foreach statement. The sequence must have a GetEnumerator factory method to output an iterator (It can be virtually read as GetIterator). And iterator must have a MoveNext method to output a bool value to indicate whether there is a value that can be pulled. If the output is true, iterator’s Current property getter can be called to pull that value. Now the values in above non-generic and generic sequences can be access with C# foreach statement:&lt;/p&gt;
&lt;p&gt;internal static void ForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; process)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in sequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach&amp;lt;T&amp;gt;(GenericSequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; process)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in sequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The foreach statement is declarative syntactic sugar. It is compiled to the following imperative control flow to get iterator from sequence, and poll iterator until there is no value available:&lt;/p&gt;
&lt;p&gt;internal static void CompiledForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; process)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Iterator iterator = sequence.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value = (T)iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(iterator as IDisposable)?.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEach&amp;lt;T&amp;gt;(GenericSequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; process)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericIterator&amp;lt;T&amp;gt;iterator = sequence.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (iterator.MoveNext())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value = iterator.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(iterator as IDisposable)?.Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, the generic version of definition is preferred, because the non-generic iterator’s Current property outputs object type, which has to be explicitly cast to the expected type specified in the foreach statement and could be a chance of failure. To demonstrate the iterator pattern implementation, a sequence of values can be defined as a singly linked list, where each value is stored in a linked list node:&lt;/p&gt;
&lt;p&gt;internal class LinkedListNode&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal LinkedListNode(T value, LinkedListNode&amp;lt;T&amp;gt; next = null) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.Value, this.Next) = (value, next);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T Value { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public LinkedListNode&amp;lt;T&amp;gt; Next { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Then iterator can be implemented to traverse along the linked list nodes. When there is a next node, MoveNext outputs true, and Current can output the next value. Notice the iterator is stateful:&lt;/p&gt;
&lt;p&gt;internal class LinkedListIterator&amp;lt;T&amp;gt; : GenericIterator&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private LinkedListNode&amp;lt;T&amp;gt; node; // State.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal LinkedListIterator(LinkedListNode&amp;lt;T&amp;gt;head) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.node = new LinkedListNode&amp;lt;T&amp;gt;(default, head);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool MoveNext()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.node.Next != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.node = this.node.Next; // State change.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override T Current =&amp;gt; this.node.Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Finally, the sequence can be simply implemented as an iterator factory:&lt;/p&gt;
&lt;p&gt;internal class LinkedListSequence&amp;lt;T&amp;gt; : GenericSequence&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly LinkedListNode&amp;lt;T&amp;gt; head;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal LinkedListSequence(LinkedListNode&amp;lt;T&amp;gt; head) =&amp;gt; this.head = head;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override GenericIterator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt; new LinkedListIterator&amp;lt;T&amp;gt;(this.head);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the values in the linked list sequence can be sequentially pulled with the foreach syntactic sugar, which is declarative and there is no need to specify the control flow or handle the state:&lt;/p&gt;
&lt;p&gt;internal static void ForEach()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LinkedListNode&amp;lt;int&amp;gt; node3 = new LinkedListNode&amp;lt;int&amp;gt;(3, null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LinkedListNode&amp;lt;int&amp;gt; node2 = new LinkedListNode&amp;lt;int&amp;gt;(2, node3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LinkedListNode&amp;lt;int&amp;gt; node1 = new LinkedListNode&amp;lt;int&amp;gt;(1, node2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LinkedListSequence&amp;lt;int&amp;gt; sequence = new LinkedListSequence&amp;lt;int&amp;gt;(node1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int value in sequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A general implementation of iterator pattern is discussed later in the LINQ to Objects query implementation chapter.&lt;/p&gt;
&lt;h3&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; interfaces&lt;/h3&gt;
&lt;p&gt;Initially, .NET Framework 1.0 provides IEnumerable and IEnumerator interfaces as the contract of iterator pattern:&lt;/p&gt;
&lt;p&gt;namespace System.Collections&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable // Sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerator // Iterator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object Current { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool MoveNext();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Reset(); // For COM interoperability.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;They can be virtually read as iteratable sequence and iterator. .NET Framework’s sequence and collection types implement IEnumerable so that they can be used with foreach statement, like array, ArrayList, Queue, Stack, SortedList, etc. Then .NET Framework 2.0 was released with generics support. So IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; interfaces are provided as the generic version of iterator pattern contract.&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;T&amp;gt; : IEnumerable // Sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerator&amp;lt;T&amp;gt; : IDisposable, IEnumerator // Iterator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T Current { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since .NET Framework 2.0, sequence and collection types are usually provided as generic types, with IEnumerable&amp;lt;T&amp;gt; implemented, like array, List&amp;lt;T&amp;gt;, Queue&amp;lt;T&amp;gt;, Stack&amp;lt;T&amp;gt;, SortedList&amp;lt;T&amp;gt;, etc.&lt;/p&gt;
&lt;p&gt;Later, .NET Framework 4.0 introduces covariance and contravariance for generic interface. As discussed in the covariance and contravariance chapter, T is covariant for both IEnumerable&amp;lt;T&amp;gt; and IEnumerable&amp;lt;T&amp;gt;. So, their definitions are updated with the out modifier for type parameter:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable // Sequence.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator // Iterator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T Current { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is how they are defined in .NET Standard.&lt;/p&gt;
&lt;h3&gt;foreach statement vs. for statement&lt;/h3&gt;
&lt;p&gt;Array is a special type. A concrete array T[] inherits System.Array type, which does not implement IEnumerable&amp;lt;T&amp;gt; but IEnumerable:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Array : ICollection, IEnumerable, IList, IStructuralComparable, IStructuralEquatable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Instead, T[] directly implements IEnumerable&amp;lt;T&amp;gt;, ICollection&amp;lt;T&amp;gt;, and IList&amp;lt;T&amp;gt;, as long as T[] is single dimensional and zero–lower bound. So, array T[] can be used with foreach loop:&lt;/p&gt;
&lt;p&gt;internal static void ForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; process)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T value in array)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;foreach statement with array is compiled into a for loop, accessing each value with index, which has better performance than the above control flow of getting iterator and polling its MoveNext method and Current property:&lt;/p&gt;
&lt;p&gt;internal static void CompiledForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; process)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; array.Length; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value = array[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And so is string. Since string is a sequence of characters, it implements IEnumerable&amp;lt;char&amp;gt;. Foreach statement with string is also compiled to index access for better performance:&lt;/p&gt;
&lt;p&gt;internal static void ForEach(string @string, Action&amp;lt;char&amp;gt; process)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (char value in @string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;process(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEach(string @string, Action&amp;lt;char&amp;gt; action)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt; @string.Length; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;char value = @string[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;action(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;LINQ to Objects queryable types&lt;/h3&gt;
&lt;p&gt;As discussed, most LINQ to Objects queries are extension methods for IEnumerable&amp;lt;T&amp;gt;. Since most of.NET sequence and collection types implements IEnumerable&amp;lt;T&amp;gt;, LINQ to Object queries are available for these types, and foreach statement is also available for these type to pull results. The following list is the commonly used interfaces and types that implement IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;· System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o Microsoft.Collections.Immutable.IImmutableQueue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableQueue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o Microsoft.Collections.Immutable.IImmutableStack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableStack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o Microsoft.Collections.Immutable.IOrderedCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Concurrent.IProducerConsumerCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Concurrent.ConcurrentBag&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Concurrent.ConcurrentQueue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Concurrent.ConcurrentStack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Concurrent.BlockingCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.ICollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.IDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Concurrent.ConcurrentDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Dynamic.ExpandoObject&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.IList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.ArraySegment&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.List&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ObservableCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.KeyedCollection&amp;lt;TKey, TItem&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.ISet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.HashSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.SortedSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.IReadOnlyCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.IReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.IImmutableDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableSortedDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.IReadOnlyList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.IImmutableList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.Generic.List&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.IImmutableSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.IImmutableHashSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableHashSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.IImmutableSortedSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.Collections.Immutable.ImmutableSortedSet&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.LinkedList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.Queue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.SortedList&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Collections.Generic.Stack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Linq.IGrouping&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Linq.ILookup&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Linq.Lookup&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Linq.IOrderedEnumerable&amp;lt;TElement&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Linq.ParallelQuery&amp;lt;TSource&amp;gt;*&lt;/p&gt;
&lt;p&gt;§ System.Linq.OrderedParallelQuery&amp;lt;TSource&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.Linq.IQueryable&amp;lt;T&amp;gt;*&lt;/p&gt;
&lt;p&gt;§ System.Linq.IOrderedQueryable&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Linq.EnumerableQuery&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Data.Linq.ITable&amp;lt;TEntity&amp;gt;&lt;/p&gt;
&lt;p&gt;§ System.Data.Linq.Table&amp;lt;TEntity&amp;gt;&lt;/p&gt;
&lt;p&gt;§ Microsoft.EntityFrameworkCore.DbSet&amp;lt;TEntity&amp;gt;&lt;/p&gt;
&lt;p&gt;o System.String (implements IEnumerable&amp;lt;char&amp;gt;)&lt;/p&gt;
&lt;p&gt;o T[] (array of T)&lt;/p&gt;
&lt;p&gt;In the above list, LINQ to Objects queries cannot be directly used for ParallelQuery&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt;, and their subtypes. As fore mentioned, ParallelQuery&amp;lt;T&amp;gt; is defined for parallel LINQ, and IQueryable&amp;lt;T&amp;gt; is defined for remote LINQ, LINQ query methods are also defined for them, like Where extension method for ParallelQuery&amp;lt;T&amp;gt;, and Where extension method for IQueryable&amp;lt;T&amp;gt;, etc. When calling Where for IQueryable&amp;lt;T&amp;gt;, apparently the call is compiled to the Where extension method for IQueryable&amp;lt;T&amp;gt;, not the Enumerable.Where extension method for IEnumerable&amp;lt;T&amp;gt;. To use LINQ to Objects’ Enumerable.Where method for ParallelQuery&amp;lt;T&amp;gt; and IQueryable&amp;lt;T&amp;gt;, AsEnumerable query method can be used, which is discussed later in this chapter. ParallelQuery&amp;lt;T&amp;gt; is covered in the Parallel LINQ chapters, and IQueryable&amp;lt;T&amp;gt; is covered in the LINQ to Entities chapters.&lt;/p&gt;
&lt;p&gt;For history reason, there are some types may only implement IEnumerable, but not implement IEnumerable&amp;lt;T&amp;gt;. A Cast query method is provided to cast non-generic sequence to generic sequence for further LINQ to Objects query, which is discussed later.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (15) Pattern matching</title><link>https://dixin.github.io/posts/functional-csharp-pattern-matching/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-pattern-matching/</guid><description>Pattern matching is a common feature in functional languages. C# 7.0 introduces basic pattern matching in is expression and switch statement, including constant value as pattern and type as pattern, a</description><pubDate>Mon, 17 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Pattern matching is a common feature in functional languages. C# 7.0 introduces basic pattern matching in is expression and switch statement, including constant value as pattern and type as pattern, and C# 7.1 supports generics in pattern matching.&lt;/p&gt;
&lt;h2&gt;Pattern matching with is expression&lt;/h2&gt;
&lt;p&gt;Since C# 1.0, is expression (instance is Type) can be used to test whether the instance is compatible with the specified type. Since C# 7.0. the type can be followed by an optional pattern variable:&lt;/p&gt;
&lt;p&gt;internal static void IsTypePattern(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@object is Uri reference)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.AbsolutePath.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@object is DateTime value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.ToString(&quot;o&quot;).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For reference type pattern, is expression is compiled to type conversion with as operation, and null check for the converted reference. The as operator only works for reference type and nullable value type. So, value type pattern matching is compiled to nullable value type conversion with as operator, and HasValue check for the converted nullable value:&lt;/p&gt;
&lt;p&gt;internal static void CompiledIsTypePattern(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri reference = @object as Uri;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (reference != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.AbsolutePath.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime? nullableValue = @object as DateTime?;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime value = nullableValue.GetValueOrDefault();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (nullableValue.HasValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.ToString(&quot;o&quot;).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is also common to use pattern matching with additional test. The following example first uses pattern match to get string from input, then uses out variable to get TimeSpan value:&lt;/p&gt;
&lt;p&gt;internal static void IsWithTest(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@object is string @string&amp;amp;&amp;amp; TimeSpan.TryParse(@string, out TimeSpan timeSpan))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;timeSpan.TotalMilliseconds.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;After compilation, the additional test goes after the null check:&lt;/p&gt;
&lt;p&gt;internal static void CompiledIsWithTest(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string @string = @object as string;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@string != null &amp;amp;&amp;amp;TimeSpan.TryParse(@string, out TimeSpan timeSpan))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;timeSpan.TotalMilliseconds.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Before pattern matching is introduced to is expression, the following test-type-then-convert-type syntax is commonly used:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public readonly partial struct DateTime
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (value is DateTime)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.InternalTicks == ((DateTime)value).InternalTicks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct TimeSpan
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (value is TimeSpan)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this._ticks == ((TimeSpan)value)._ticks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the input object’s type was detected twice. Now with the new syntax, the test and conversion can be merged:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public readonly partial struct DateTime
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object value) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value is DateTime dateTime &amp;amp;&amp;amp; this.InternalTicks == dateTime.InternalTicks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct TimeSpan
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object value) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value is TimeSpan timeSpan &amp;amp;&amp;amp; this._ticks == timeSpan._ticks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 7.1 supports generics open type in pattern matching:&lt;/p&gt;
&lt;p&gt;internal static void IsWithOpenType&amp;lt;TOpen1, TOpen2, TOpen3, TOpen4&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IDisposable disposable, TOpen2 open2, TOpen3 open3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (disposable is TOpen1 open1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;open1.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (open2 is FileInfo file)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;file.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (open3 is TOpen4 open4)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;open4.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When open type is involved, the tested instance is boxed as object. When open type is the type pattern, it is unknow whether the open type is reference type or value type. Regarding as operator can only be used for reference type and nullable value type, so as operator cannot be used for the open type here. So, the pattern matching with open type is compiled to the basic is expression of type test.&lt;/p&gt;
&lt;p&gt;internal static void CompiledIsWithOpenType&amp;lt;TOpen1, TOpen2, TOpen3, TOpen4&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IDisposable disposable, TOpen2 open2, TOpen3 open3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object disposableObject = (object)disposable;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (disposableObject is TOpen1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOpen1 open1 = (TOpen1)disposableObject;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;open1.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object open2Object = (object)open2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo file = open2Object as FileInfo;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (file != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;file.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object open3Object = (object)open3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (open3Object is TOpen4)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOpen4 open4 = (TOpen4)open3Object;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;open4.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The var keyword can be used to represent the pattern of any type:&lt;/p&gt;
&lt;p&gt;internal static void IsType(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@object is var match)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(@object, match).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since the var pattern matching always works, it is compiled to constant value true in debug build:&lt;/p&gt;
&lt;p&gt;internal static void CompiledIsAnyType(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object match = @object;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (true)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(@object, match).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In release build, the above if (true) test is removed.&lt;/p&gt;
&lt;p&gt;Since C# 7.0, is expression can also test constant pattern (instance is constant), where constant value and constant expression are supported, including primitive type, enumerations, decimal, string, and null for reference type:&lt;/p&gt;
&lt;p&gt;internal static void IsConstantPattern(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test1 = @object is null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test2 = @object is default(int);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test3 = @object is DayOfWeek.Saturday - DayOfWeek.Monday;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test4 = @object is &quot;https://&quot; + &quot;flickr.com/dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test5 = @object is nameof(test5);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The is expressions for null test is simply compiled to null check. the other cases are compiled to object.Equals static method calls, where the constant value is the first argument, and the tested instance is the second argument.&lt;/p&gt;
&lt;p&gt;internal static void CompiledIsConstantPattern(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test1 = @object == null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test2 = object.Equals(0, @object);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test3 = object.Equals(5, @object);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test4 = object.Equals(&quot;https://flickr.com/dixin&quot;, @object);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test5 = object.Equals(&quot;test5&quot;, @object);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Internally, object.Equals first does a few checks, then it calls Equals instance method of first argument, which is the constant value. Its implementation can be viewed as:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Object
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Equals(object objA, object objB) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;objA == objB || (objA != null &amp;amp;&amp;amp; objB != null &amp;amp;&amp;amp; objA.Equals(objB));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The early version of C# 7.0 compiles the object.Equals static method call in different way. The tested instance is the first argument, and the constant value is the second argument. As a result, object.Equals then calls the tested instance’s Equals instance method. This is problematic, because the tested instance can be of any type, and it can override Equals instance with arbitrary implementation. In C# 7.0 GA release, this was fixed by having the constant value be the first argument of object.Equals static method call. The non-null constant value must be of primitive type, enumeration, decimal, or string, so a constant’s Equals instance method always has reliable built-in implementation. There is no arbitrary custom equality implementation involved in constant pattern matching.&lt;/p&gt;
&lt;p&gt;C# uses default(Type) expression to represent the default value of the specified type since 1.0. Then C# 7.1 introduces default literal expression, which just uses the default keyword to represent a default value, with the type omitted and inferred from context. Since then, the default literal expression is also enabled for constant pattern matching:&lt;/p&gt;
&lt;p&gt;internal static void IsConstantPatternWithDefault(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool test6 = @object is default; // Cannot be compiled. use default(Type).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Shortly, this syntax is disabled after C# 7.2 is released, because it causes confusion with the default case in switch statement, which is discussed later in this chapter. For default value pattern matching, use the traditional default(Type) syntax as demonstrated in the first example.&lt;/p&gt;
&lt;h2&gt;Pattern matching with switch statement and expression&lt;/h2&gt;
&lt;p&gt;Before C# 7.0, the switch statement only supports string, integral types (like bool, byte, char, int, long, etc.), and enumeration; and the case label only supports constant value. Since C# 7.0, switch supports any type and case label supports pattern matching for either constant value or type. The additional condition for the pattern matching can be specified with a when clause. The following example tries to convert object to DateTime:&lt;/p&gt;
&lt;p&gt;internal static DateTime ToDateTime&amp;lt;TConvertible&amp;gt;(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;where TConvertible : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (@object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match null reference.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case null:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(nameof(@object));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match value type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case DateTime dateTIme:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return dateTIme;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match value type with condition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case long ticks when ticks &amp;gt;= 0:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new DateTime(ticks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match reference type with condition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case string @string when DateTime.TryParse(@string, out DateTime dateTime):
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return dateTime;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match reference type with condition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case int[] date when date.Length == 3 &amp;amp;&amp;amp; date[0] &amp;gt; 0 &amp;amp;&amp;amp; date[1]&amp;gt; 0 &amp;amp;&amp;amp; date[2] &amp;gt; 0:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new DateTime(year: date[0], month: date[1], day: date[2]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match generics open type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case TConvertible convertible:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return convertible.ToDateTime(provider: null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Match anything else. Equivalent to default case.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case var _:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(@object));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The last pattern matches any type pattern, so it works equivalently to the default case of switch statement. The special _ identifier is used to discard the pattern variable. In switch statement, each pattern matching is compiled similarly to is expression:&lt;/p&gt;
&lt;p&gt;internal static DateTime CompiledToDateTime&amp;lt;TConvertible&amp;gt;(object @object)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;where TConvertible : IConvertible
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case null:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@object == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(&quot;object&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case DateTime dateTIme:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime? nullableDateTime = @object as DateTime?;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime dateTime = nullableDateTime.GetValueOrDefault();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (nullableDateTime.HasValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return dateTime;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case long ticks:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long? nullableInt64 = @object as long?;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long ticks = nullableInt64.GetValueOrDefault();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (nullableInt64.HasValue &amp;amp;&amp;amp; ticks &amp;gt;= 0L) // when clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new DateTime(ticks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case string text:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string @string = @object as string;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (@string != null &amp;amp;&amp;amp; DateTime.TryParse(@string, out DateTime parsedDateTime)) // when clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return parsedDateTime;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case int[] date:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] date = @object as int[];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (date != null &amp;amp;&amp;amp; date.Length == 3 &amp;amp;&amp;amp; date[0] &amp;gt;= 0 &amp;amp;&amp;amp; date[1]&amp;gt; = 0 &amp;amp;&amp;amp; date[2] &amp;gt;= 0) // when clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new DateTime(date[0], date[1], date[2]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case TConvertible convertible:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object convertibleObject = (object)@object;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (convertibleObject is TConvertible)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TConvertible convertible = (TConvertible)convertibleObject;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return convertible.ToDateTime(null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// case var _:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(&quot;object&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 8.0 introduces switch expression syntacticsal sugar to simplify the switch statement:&lt;/p&gt;
&lt;p&gt;internal static DateTime ToDateTime2(object @object) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@object switch
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;null =&amp;gt; throw new ArgumentNullException(nameof(@object)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DateTime dateTIme =&amp;gt; dateTIme,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;long ticks when ticks &amp;gt;= 0 =&amp;gt; new DateTime(ticks),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string @string when DateTime.TryParse(@string, out DateTime dateTime) =&amp;gt; dateTime,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] date when date.Length == 3 &amp;amp;&amp;amp; date[0]&amp;gt; 0 &amp;amp;&amp;amp; date[1] &amp;gt; 0 &amp;amp;&amp;amp; date[2] &amp;gt; 0 =&amp;gt; new DateTime(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;year: date[0], month: date[1], day: date[2]),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IConvertible convertible =&amp;gt; convertible.ToDateTime(provider: null),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;_ =&amp;gt; throw new ArgumentOutOfRangeException(nameof(@object))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;C# has basic pattern matching features. Type pattern (including generics open type) with pattern variable and constant pattern are supported in is expression and switch statement. The var keyword can be used as the pattern of any type, and _ can be used to discard pattern variable. switch statement also supports when clause for each pattern matching for additional condition.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (12) Immutability, Anonymous Type, and Tuple</title><link>https://dixin.github.io/posts/functional-csharp-immutability-anonymous-type-and-tuple/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-immutability-anonymous-type-and-tuple/</guid><description>Immutability is an important aspect of functional programming. As discussed in the introduction chapter, imperative/object-oriented programming is usually mutable and stateful, and functional programm</description><pubDate>Thu, 13 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Immutability is an important aspect of functional programming. As discussed in the introduction chapter, imperative/object-oriented programming is usually mutable and stateful, and functional programming encourages immutability without state change. There are many kinds of immutability. In C#, the relevant features can be categorized into 2 levels: immutability of a value, and immutability of a value’s internal state. Take local variable as example, a local variable can be immutable value, if once it is initialized to an instance, it cannot be altered it to different instance to it; a local variable can also have immutable state, if once the instance’s internal state is initialized, that instance’s internal state cannot be altered to different state.&lt;/p&gt;
&lt;p&gt;In functional programming, immutability is an important practice. It makes code easier to write, test, and maintain in many cases. Apparently, mutation makes the code unpredictable, and could be a prominent source of bugs; while apparently immutability makes the code predictable, and easier for reasoning about the correctness. Immutable value and immutable state can also make code easier to scale. There is no in-place update, and there is no update conflict. So, immutability is thread-safe by nature, and greatly simplifies concurrent/parallel/multithreading programming.&lt;/p&gt;
&lt;p&gt;With immutability, since data cannot be updated in-place, it must be transformed to new data. The disadvantage of immutability is, apparently, the transformation must create another new instance to have the updated state, which can be a performance overhead.&lt;/p&gt;
&lt;h2&gt;Immutable value&lt;/h2&gt;
&lt;p&gt;Many functional languages support immutable value. In contrast to variable, once an immutable value is initialized with an instance, it cannot be reassigned so that it can never be altered to another different instance. As a C-like language, C# has variable, which is mutable by default. C# also has a number of language features for immutable value.&lt;/p&gt;
&lt;h3&gt;Constant local&lt;/h3&gt;
&lt;p&gt;C# has a const keyword to define compile time constant local. It can be initialized from a constant value or a constant expression that can be evaluated at compiled time, then it cannot be changed at runtime. Constant local only works for primitive types, enumerations, decimal, string, and null for reference type. At compiled time, the reference to constant local is replaced by the actual constant value, and the constant local is removed. The following is a few examples:&lt;/p&gt;
&lt;p&gt;internal static void ConstantLocal()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int ImmutableInt32 = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int ImmutableInt32Sum = ImmutableInt32 + 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Constant expression ImmutableInt32 + 2 is compiled to: 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const DayOfWeek ImmutableDayOfWeek = DayOfWeek.Saturday;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const decimal ImmutableDecimal = (1M + 2M) * 3M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string ImmutableString = &quot;https://weblogs.asp.net/dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const string ImmutableStringConcat = &quot;https://&quot; + &quot;flickr.com/dixin&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const Uri ImmutableUri = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to above constant locals cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int variableInt32 = Math.Max(ImmutableInt32, ImmutableInt32Sum);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: Math.Max(1, 3).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(ImmutableString);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: Trace.WriteLine(&quot;https://weblogs.asp.net/dixin&quot;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Enumeration&lt;/h3&gt;
&lt;p&gt;Enumeration can be viewed as a group of immutable values of its underlying integral type (int by default). For example:&lt;/p&gt;
&lt;p&gt;internal enum Day&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Sun, Mon, Tue, Wed, Thu, Fri, Sat
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal enum CompiledDay : int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Sun = 0, Mon = 1, Tue = 2, Wed = 3, Thu = 4, Fri = 5, Sat = 6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As demonstrated in previous example, enumeration can be used as constant value. It can also be used in constant expression:&lt;/p&gt;
&lt;p&gt;internal static void Enumeration()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine((int)Day.Mon); // Compiled to: Trace.WriteLine(1).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(Day.Mon + 2); // Compiled to: Trace.WriteLine(Day.Wed).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine((int)Day.Mon + Day.Thu); // Compiled to: Trace.WriteLine(Day.Fri).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(Day.Sat - Day.Mon); // Compiled to: Trace.WriteLine(5).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;using statement and foreach statement&lt;/h3&gt;
&lt;p&gt;C# also supports immutable value in the fore mentioned using statement and foreach statement:&lt;/p&gt;
&lt;p&gt;internal static void Using(Func&amp;lt;IDisposable&amp;gt; disposableFactory)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (IDisposable immutableDisposable = disposableFactory())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutableDisposable cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; sequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (T immutableValue in sequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutableValue cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Immutable alias (immutable ref local variable)&lt;/h3&gt;
&lt;p&gt;As discussed in the C# basics chapter, ref modifier can define alias for local variable, and readonly modifier can be used with ref modifier to make the alias immutable. Once an immutable alias is initialized with something, it cannot be alias of anything else:&lt;/p&gt;
&lt;p&gt;internal static void ImmutableAlias()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int copyOfValue = value; // Copy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;copyOfValue = 10; // After the assignment, value does not mutate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref int aliasOfValue = ref value; // Mutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;aliasOfValue = 10; // After the reassignment, value mutates.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly int immutableAliasOfValue = ref value; // Immutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutableAliasOfValue cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri copyOfReference = reference; // Copy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;copyOfReference = new Uri(&quot;https://flickr.com/dixin&quot;); // After the assignment, reference does not mutate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref Uri aliasOfReference = ref reference; // Mutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;aliasOfReference = new Uri(&quot;https://flickr.com/dixin&quot;); // After the reassignment, reference mutates.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly Uri immutableAliasOfReference = ref reference; // Immutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutableAliasOfReference cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Function’s immutable input and immutable output&lt;/h3&gt;
&lt;p&gt;As discussed in the function input and output chapter, the in modifier enables function input by immutable alias (in parameter), and the readonly modifier can be used with ref modifier to enable output by immutable alias (ref readonly return):&lt;/p&gt;
&lt;p&gt;internal static void ParameterAndReturn&amp;lt;T&amp;gt;(Span&amp;lt;T&amp;gt; span)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly T First(in Span&amp;lt;T&amp;gt; immutableInput)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Cannot reassign to immutableInput.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ref immutableInput[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly T immutableOutput = ref First(in span);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Cannot reassign to immutableOutput.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Range variable in LINQ query expression&lt;/h3&gt;
&lt;p&gt;The function composition chapter discusses LINQ query expression where, let clause and other clauses can define range variable. LINQ range variable is not mutable variable but immutable value:&lt;/p&gt;
&lt;p&gt;internal static void QueryExpression(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable&amp;lt;int&amp;gt; source2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;int, int&amp;gt;&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from immutable1 in source1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutable1 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join immutable2 in source2 on immutable1 equals immutable2 into immutable3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutable2, immutable3 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let immutable4 = immutable1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutable4 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group immutable4 by immutable4 into immutable5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutable5 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select immutable5 into immutable6
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to immutable6 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select immutable6;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;this reference for class&lt;/h3&gt;
&lt;p&gt;In class definition, this keyword can be used in instance function members to refer to the current instance of the class, and it is immutable:&lt;/p&gt;
&lt;p&gt;internal partial class Device&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void InstanceMethod()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to this cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For structure, this reference is mutable by default, which is discussed later in this chapter.&lt;/p&gt;
&lt;h2&gt;Immutable state (immutable type)&lt;/h2&gt;
&lt;p&gt;A type is immutable type, if once its instance is initialized, the internal state cannot mutate to different state. As a typical example, string (System.String) is an immutable type. Once a string instance is constructed, there is no API to mutate the internal characters of that string instance. For example, string.Remove does not remove specified characters in the string, but constructs a new string without the characters specified to remove. In contrast, string builder (System.Text.StringBuilder) is a mutable type. For example, StringBuilder.Remove mutates the internal characters in place. In .NET Standard, most classes are mutable types, and most structures are immutable types.&lt;/p&gt;
&lt;h3&gt;Constant field&lt;/h3&gt;
&lt;p&gt;When defining type (class or structure), a field with the const modifier is static and immutable. It must be initialized by constant value or constant expression inline, and it cannot be reassigned. Similar to constant local, constant field only works for primitive types, enumerations, decimal, string, and null for reference type.&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct DateTime : IComparable, IComparable&amp;lt;DateTime&amp;gt;, IConvertible, IEquatable&amp;lt;DateTime&amp;gt;, IFormattable, ISerializable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private const int DaysPerYear = 365;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .field private static literal int32 DaysPerYear = 365
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private const int DaysPer4Years = DaysPerYear * 4 + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .field private static literal int32 DaysPer4Years = 1461
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;At compiled time, the reference to constant field is replaced by the actual constant value, and the constant field definition is not removed.&lt;/p&gt;
&lt;h3&gt;Immutable class with readonly instance field&lt;/h3&gt;
&lt;p&gt;When the readonly modifier is used for a field, the field can only be initialized by constructor, and cannot be reassigned later. So an immutable class can be immutable by defining all instance fields as readonly:&lt;/p&gt;
&lt;p&gt;internal partial class ImmutableDevice&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly string name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly decimal price;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With the fore mentioned auto property syntactic sugar, the readonly field definition can be automatically generated. The following examples are mutable type with read write fields generated from auto property, and immutable type with read only fields generated from getter only auto properties:&lt;/p&gt;
&lt;p&gt;internal partial class MutableDevice&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal decimal Price { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal partial class ImmutableDevice
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableDevice(string name, decimal price)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Name = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Price = price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal decimal Price { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, to have new internal state, a mutable instance can mutate in place, by altering its fields, while an immutable instance must be transformed to a new instance to have the new state:&lt;/p&gt;
&lt;p&gt;internal static void DevicePriceDrop()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MutableDevice mutableDevice = new MutableDevice() { Name = &quot;Surface Laptop&quot;, Price = 799M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mutableDevice.Price -= 50M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableDevice immutableDevice = new ImmutableDevice(name: &quot;Surface Book&quot;, price: 1199M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableDevice = new ImmutableDevice(name: immutableDevice.Name, price: immutableDevice.Price - 50M);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following examples defines instance method for new state with mutation and transformation:&lt;/p&gt;
&lt;p&gt;internal partial class MutableDevice&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal MutableDevice Discount()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Price = this.Price * 0.9M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal partial class ImmutableDevice
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableDevice Discount() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new ImmutableDevice(name: this.Name, price: this.Price * 0.9M);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Many .NET built-in types are immutable data structures, including most structures (primitive types, System.Nullable&amp;lt;T&amp;gt;, System.DateTime, System.TimeSpan, etc.), and a few classes (string, System.Lazy&amp;lt;T&amp;gt;, System.Linq.Expressions.Expression and its derived types, etc.). Microsoft also provides a NuGet package of immutable collections System.Collections.Immutable, with immutable array, list, dictionary, etc.&lt;/p&gt;
&lt;h3&gt;Immutable structure (readonly structure)&lt;/h3&gt;
&lt;p&gt;The following structure is defined with getter only auto property, which generates readonly fields. The structure looks immutable:&lt;/p&gt;
&lt;p&gt;internal partial struct Complex&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Complex(double real, double imaginary)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Real = real;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Imaginary = imaginary;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal double Real { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal double Imaginary { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;However, for structure, readonly fields are not enough for immutability. Unlike class, in structure’s instance function members, this reference is mutable:&lt;/p&gt;
&lt;p&gt;internal partial struct Complex&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Complex(Complex value) =&amp;gt; this = value; // Can reassign to this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Complex Value
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get =&amp;gt; this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set =&amp;gt; this = value; // Can reassign to this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Complex ReplaceBy(Complex value) =&amp;gt; this = value; // Can reassign to this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Complex Mutate(double real, double imaginary) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this = new Complex(real, imaginary); // Can reassign to this.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With mutable this, the above structure still can be mutable:&lt;/p&gt;
&lt;p&gt;internal static void Structure()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Complex complex = new Complex(1, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;complex.Real.WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;complex.ReplaceBy(new Complex(2, 2));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;complex.Real.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;complex.Mutate(3, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;complex.Real.WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To address this, C# 7.2 enables the readonly modifier for structure definition to makes sure the structure is immutable. It enforces all the instance fields to be readonly, and makes this reference immutable in instance function members except constructor:&lt;/p&gt;
&lt;p&gt;internal readonly partial struct ImmutableComplex&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableComplex(double real, double imaginary)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Real = real;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Imaginary = imaginary;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableComplex(in ImmutableComplex value) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this = value; // Can reassign to this only in constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal double Real { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal double Imaginary { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void InstanceMethod()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Cannot reassign to this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The readonly modifier is compiled to [IsReadOnly] attribute for the structure:&lt;/p&gt;
&lt;p&gt;[IsReadOnly]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal struct CompiledImmutableComplex
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Members.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Immutable anonymous type&lt;/h3&gt;
&lt;p&gt;C# 3.0 introduces anonymous type to represent temporary data in an immutable form, without providing the type definition at design time:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var immutableDevice = new { Name = &quot;Surface Book&quot;, Price = 1199M };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since the type name is unknown at design time, the above instance is of an anonymous type, and the type name is represented by the var keyword. At compile time, the following immutable class is generated:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerDisplay(@&quot;\{ Name = {Name}, Price = {Price} }&quot;, Type = &quot;&amp;lt;Anonymous Type&amp;gt;&quot;)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal sealed class AnonymousType0&amp;lt;TName, TPrice&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerBrowsable(DebuggerBrowsableState.Never)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly TName name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerBrowsable(DebuggerBrowsableState.Never)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly TPrice price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerHidden]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public AnonymousType0(TName name, TPrice price)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.name = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.price = price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TName Name =&amp;gt; this.name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TPrice Price =&amp;gt; this.price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerHidden]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerHidden]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object obj)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;AnonymousType0&amp;lt;TName, TPrice&amp;gt; other = obj as AnonymousType0&amp;lt;TName, TPrice&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return other != null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp;EqualityComparer&amp;lt;TName&amp;gt;.Default.Equals(this.name, other.name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;&amp;amp;EqualityComparer&amp;lt;TPrice&amp;gt;.Default.Equals(this.price, other.price);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The [DebuggerDisplay] attribute is generated for debug build, so that debugger can display the values in the specified friendly format.&lt;/p&gt;
&lt;p&gt;And the above setting-property-like syntax is compiled to normal constructor call:&lt;/p&gt;
&lt;p&gt;internal static void CompiledAnonymousType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;AnonymousType0&amp;lt;string, decimal&amp;gt;immutableDevice =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new AnonymousType0&amp;lt;string, decimal&amp;gt;(name: &quot;Surface Book&quot;, price: 1199M);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If there are other different anonymous type used in the code, C# compiler generates more type definitions AnonymousType1, AnonymousType2, etc. Anonymous type is reused by different instantiation if their properties have same number, the same names, the same types, and the same order:&lt;/p&gt;
&lt;p&gt;internal static void ReuseAnonymousType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var device1 = new { Name = &quot;Surface Book&quot;, Price = 1199M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var device2 = new { Name = &quot;Surface Pro&quot;, Price = 899M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var device3 = new { Name = &quot;Xbox One&quot;, Price = 399.00 }; // Price is of type double.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var device4 = new { Price = 174.99M, Name = &quot;Surface Laptop&quot; }; // Price is before Name.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(device1.GetType() == device2.GetType()).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(device1.GetType() == device3.GetType()).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(device1.GetType() == device4.GetType()).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Anonymous type’s property name can be inferred from the identifier used to initialize the property. The following 2 anonymous type instantiations are equivalent:&lt;/p&gt;
&lt;p&gt;internal static void PropertyInference(Uri uri, int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var anonymous1 = new { value, uri.Host };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var anonymous2 = new { value = value, Host = uri.Host };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Anonymous type can also be part of other types, like array, and type parameter for generic type, etc:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousTypeParameter()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var source = // Compiled to: AnonymousType0&amp;lt;string, decimal&amp;gt;[] source =.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new []
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new { Name = &quot;Surface Book&quot;, Price = 1199M },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new { Name = &quot;Surface Pro&quot;, Price = 899M }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var query = // Compiled to: IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt; query = .
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source.Where(device =&amp;gt; device.Price &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the source array is inferred to be of AnonymousType0&amp;lt;string, decimal&amp;gt;[] type, because each array value is of type AnonymousType0. Array T[] implements IEnumerable&amp;lt;T&amp;gt; interface, so the source array implements IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt; interface. Its Where query method accepts an AnonymousType0&amp;lt;string, decimal&amp;gt; –&amp;gt; bool predicate function, and outputs IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;C# compiler utilizes anonymous type for let clause in LINQ query expression. The let clause is compiled to Select query method call with a selector function. The selector function outputs anonymous type, where each property is a range variable in the context. For example:&lt;/p&gt;
&lt;p&gt;internal static void Let(IEnumerable&amp;lt;int&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;double&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from immutable1 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let immutable2 = Math.Sqrt(immutable1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select immutable1 + immutable2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLet(IEnumerable&amp;lt;int&amp;gt;source)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;double&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(immutable1 =&amp;gt; new { immutable1, immutable2 = Math.Sqrt(immutable1) }) // let clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(context =&amp;gt; context.immutable1 + context.immutable2); // select clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The full details of query expression compilation are discussed in the LINQ to Objects chapters.&lt;/p&gt;
&lt;h3&gt;Local variable type inference&lt;/h3&gt;
&lt;p&gt;Besides local variable of anonymous type, the var keyword can be also used to initialize local variable of existing type:&lt;/p&gt;
&lt;p&gt;internal static void LocalVariable(IEnumerable&amp;lt;int&amp;gt; source, string path)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var a = default(int); // int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var b = 1M; // decimal.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var c = typeof(void); // Type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var d = from int32 in source where int32 &amp;gt; 0 select Math.Sqrt(int32); // IEnumerable&amp;lt;double&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var e = File.ReadAllLines(path); // string[].
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is just a syntactic sugar. The local variable’s type is inferred from the initial value’s type. The compilation of implicit typed local variable has no difference from explicitly typed local variable. When the initial value’s type is ambiguous, the var keyword cannot be directly used:&lt;/p&gt;
&lt;p&gt;internal static void LocalVariableWithType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var f = (Uri)null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var g = (Func&amp;lt;int, int&amp;gt;)(int32 =&amp;gt; int32 + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var h = (Expression&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;)(int32 =&amp;gt; int32 + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For consistency and readability, this book uses explicit typing when possible, uses implicit typing (var) when needed.&lt;/p&gt;
&lt;h3&gt;Immutable tuple and mutable tuple&lt;/h3&gt;
&lt;p&gt;Tuple is a data structure commonly used in functional programming. It is a finite and ordered list of values, usually immutable in most functional languages. To represent tuple, a series of generic tuple classes with 1 - 8 type parameters are provided in .NET Standard. All tuple classes are immutable. For example, the following is the definition of Tuple&amp;lt;T1, T2&amp;gt;, which represents a 2-tuple (tuple of 2 values):&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Tuple&amp;lt;T1, T2&amp;gt; : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly T1 m_Item1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly T2 m_Item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Tuple(T1 item1, T2 item2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.m_Item1 = item1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.m_Item2 = item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T1 Item1 =&amp;gt; this.m_Item1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T2 Item2 =&amp;gt; this.m_Item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Years after introducing tuple classes, C# 7.0 finally introduces tuple syntax. However, the tuple syntax does not work with above immutable tuple classes, but works with a new series of generic tuple structures with 1 ~ 8 type parameters. For example, 2-tuple is now represented by the following ValueTuple&amp;lt;T1, T2&amp;gt; structure:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[StructLayout(LayoutKind.Auto)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct ValueTuple&amp;lt;T1, T2&amp;gt; : IEquatable&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;, IStructuralEquatable, IStructuralComparable, IComparable, IComparable&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;, IValueTupleInternal, ITuple
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T1 Item1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T2 Item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public ValueTuple(T1 item1, T2 item2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Item1 = item1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Item2 = item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override string ToString() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;(&quot; + this.Item1?.ToString() + &quot;, &quot; + this.Item2?.ToString() + &quot;)&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The tuple structures with fields are provided for better performance than tuple classes with properties, since structure can be allocated and deallocated on stack, and field access does not involve getter function member call. Unfortunately, all tuple structures are designed to be mutable types with non-readonly public fields. To be functional and consistent, this book does not use tuple classes, but only uses tuple structures and never mutate their value fields, as if tuple structures are immutable.&lt;/p&gt;
&lt;p&gt;As above tuple definition shows, in contrast of list of values or array of values, tuple’s values can be of different types:&lt;/p&gt;
&lt;p&gt;internal static void TypesOfValues()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValueTuple&amp;lt;string, decimal&amp;gt; tuple = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Book&quot;, 1199M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string[] array = { &quot;Surface Book&quot;, &quot;1199M&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;string&amp;gt;list = new List&amp;lt;string&amp;gt;() { &quot;Surface Book&quot;, &quot;1199M&quot; };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Tuple type and anonymous type are conceptually similar to each other, they are both a list of values of arbitrary types. At design time, tuple type is defined, and anonymous type is not defined yet. Therefore, anonymous type (var keyword) can only be used for local variable with immediate instantiation to infer the types of the values, and cannot be used as function input type, function output type, type argument, etc.:&lt;/p&gt;
&lt;p&gt;internal static ValueTuple&amp;lt;string, decimal&amp;gt; Function(ValueTuple&amp;lt;string, decimal&amp;gt; values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValueTuple&amp;lt;string, decimal&amp;gt; variable1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValueTuple&amp;lt;string, decimal&amp;gt; variable2 = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt;variable3;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return values;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static var Function(var values) // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var variable1; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var variable2 = default; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;var&amp;gt; variable3; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return values;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Construction, element and element inference&lt;/h3&gt;
&lt;p&gt;C# 7.0 introduces tuple syntactic sugar, which brings great convenience. The tuple type ValueTuple&amp;lt;T1, T2, T3, …&amp;gt; can be simplified to (T1, T2, T3, …), and the tuple construction new ValueTuple&amp;lt;T1, T2, T3, …&amp;gt;(value1, value2, value3, …) can be simplified to (value1, value2, value3, …):&lt;/p&gt;
&lt;p&gt;internal static void TupleLiteral()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string, decimal) tuple1 = (&quot;Surface Pro&quot;, 899M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ValueTuple&amp;lt;string, decimal&amp;gt; tuple1 = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Pro&quot;, 899M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int, bool, (string, decimal)) tuple2 = (1, true, (&quot;Surface Studio&quot;, 2999M));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ValueTuple&amp;lt;int, bool, ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt; tuple2 =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// new ValueTuple&amp;lt;int, bool, ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt;(1, true, new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Studio&quot;, 2999M));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When using tuple as the function output type, the tuple syntax virtually enables function to return multiple values:&lt;/p&gt;
&lt;p&gt;internal static (string, decimal) OutputMultipleValues()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: internal static ValueTuple&amp;lt;string, decimal&amp;gt; OutputMultipleValues()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string value1 = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value2 = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string, decimal) Function() =&amp;gt; (value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: ValueTuple&amp;lt;string, decimal&amp;gt; Function() =&amp;gt; new ValueTuple&amp;lt;string, decimal&amp;gt;(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;(string, decimal)&amp;gt; function = () =&amp;gt; (value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: Func&amp;lt;ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt; function = () =&amp;gt; new ValueTuple&amp;lt;string, decimal&amp;gt;(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to : new ValueTuple&amp;lt;string, decimal&amp;gt;(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 7.0 also introduces element name, so that each value of the tuple type definition can be given a property-like name, with the syntax (T1 Name1, T2 Name2, T3 Name3, …), and each value of the tuple instance construction can be given a name too, with syntax (Name1: value1, Name2, value2, Name3 value3, …). So that the values in the tuple can be accessed with a meaningful name, instead of the actual Item1, Item2, Item3, … field names. This is also a syntactic sugar, at compile time, all element names are all replaced by the underlying fields.&lt;/p&gt;
&lt;p&gt;internal static void ElementName()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string Name, decimal Price) tuple1 = (&quot;Surface Pro&quot;, 899M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple1.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple1.Price.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ValueTuple&amp;lt;string, decimal&amp;gt; tuple1 = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Pro&quot;, 899M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TraceExtensions.WriteLine(tuple1.Item1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TraceExtensions.WriteLine(tuple1.Item2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string Name, decimal Price) tuple2 = (ProductNanme: &quot;Surface Book&quot;, ProductPrice: 1199M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple2.Name.WriteLine(); // Element names on the right side are ignored when there are element names on the left side.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var tuple3 = (Name: &quot;Surface Studio&quot;, Price: 2999M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple3.Name.WriteLine(); // Element names are available through var.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValueTuple&amp;lt;string, decimal&amp;gt; tuple4 = (Name: &quot;Xbox One&quot;, Price: 179M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple4.Item1.WriteLine(); // Element names are not available on ValueTuple&amp;lt;T1, T2&amp;gt; type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple4.Item2.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string Name, decimal Price) Function((string Name, decimal Price) tuple)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple.Name.WriteLine(); // Input tuple’s element names are available in function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (tuple.Name, tuple.Price - 10M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var tuple5 = Function((&quot;Xbox One S&quot;, 299M));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple5.Name.WriteLine(); // Output tuple’s element names are available through var.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple5.Price.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;(string Name, decimal Price), (string Name, decimal Price)&amp;gt; function = tuple =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple.Name.WriteLine(); // Input tuple’s element names are available in function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (tuple.Name, tuple.Price - 100M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string ProductName, decimal ProductPrice) tuple6 = function((&quot;HoloLens&quot;, 3000M));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple6.ProductName.WriteLine(); // Element names on the right side are ignored when there are element names on the left side.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tuple6.ProductPrice.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to anonymous type’s property name inference, C# 7.1 can infer tuple’s element name from the identifier used to initialize the element. The following 2 tuple are equivalent:&lt;/p&gt;
&lt;p&gt;internal static void ElementInference(Uri uri, int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var tuple1 = (value, uri.Host);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var tuple2 = (value: value, Host: uri.Host);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Deconstruction&lt;/h3&gt;
&lt;p&gt;Since C# 7.0, the var keyword can also be used to deconstruct tuple to a list of values. This syntax is very useful when used with functions that outputs multiple values represented by tuple:&lt;/p&gt;
&lt;p&gt;internal static void DeconstructTuple()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(string, decimal) GetProduct() =&amp;gt; (&quot;HoloLens&quot;, 3000M);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var (name, price) = GetProduct();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This deconstruction syntactic sugar can be used with any type, as long as that type has a Deconstruct instance or extension method defined, where the values as the out parameters. Take the fore mentioned Device type as example, it has 3 properties Name, Description, and Price, so its Deconstruct method can be either of the following 2 forms:&lt;/p&gt;
&lt;p&gt;internal partial class Device&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Deconstruct(out string name, out string description, out decimal price)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name = this.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;description = this.Description;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price = this.Price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static class DeviceExtensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Deconstruct(this Device device, out string name, out string description, out decimal price)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name = device.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;description = device.Description;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price = device.Price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the var keyword can destruct Device too, which is just compiled to Destruct method call:&lt;/p&gt;
&lt;p&gt;internal static void DeconstructDevice()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Device GetDevice() =&amp;gt; new Device() { Name = &quot;Surface studio&quot;, Description = &quot;All-in-one PC.&quot;, Price = 2999M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var (name, description, price) = GetDevice();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string name; string description; decimal price;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// surfaceStudio.Deconstruct(out name, out description, out price);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;description.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Discard&lt;/h3&gt;
&lt;p&gt;In tuple destruction, since the elements are compiled to out variables of the Destruct method, any element can be discarded with underscore just like discarding out variable:&lt;/p&gt;
&lt;p&gt;internal static void Discard()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Device GetDevice() =&amp;gt; new Device() { Name = &quot;Surface studio&quot;, Description = &quot;All-in-one PC.&quot;, Price = 2999M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var (_, _, price1) = GetDevice();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price1.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(_, _, decimal price2) = GetDevice();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;price2.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Tuple assignment&lt;/h3&gt;
&lt;p&gt;With the tuple syntax, now C# can also support fancy tuple assignment, just like in Python and other languages. The following example assigns 2 values to 2 variables with a single line of code, then swap the values of 2 variables with a single line of code:&lt;/p&gt;
&lt;p&gt;internal static void TupleAssignment(int value1, int value2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2) = (1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// value1 = 1; value2 = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2) = (value2, value1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int temp1 = value1; int temp2 = value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// value1 = temp2; value2 = temp1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is easy to calculate Fibonacci number with loop and tuple assignment:&lt;/p&gt;
&lt;p&gt;internal static int Fibonacci(int n)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int a, int b) = (0, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i&amp;lt; n; i++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b) = (b, a + b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return a;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides variables, tuple assignment works for other scenarios too, like type member. The following example assigns 2 values to 2 properties with a single line of code:&lt;/p&gt;
&lt;p&gt;internal class ImmutableDevice&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableDevice(string name, decimal price) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.Name, this.Price) = (name, price);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal decimal Price { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Immutable collection vs. readonly collection&lt;/h3&gt;
&lt;p&gt;Microsoft provides immutable collections through the System.Collections.Immutable NuGet Package, including ImmutableArray&amp;lt;T&amp;gt;, ImmutableDictionary&amp;lt;TKey, TValue&amp;gt;, ImmutableHashSet&amp;lt;T&amp;gt;, ImmutableList&amp;lt;T&amp;gt;, ImmutableQueue&amp;lt;T&amp;gt;, ImmutableSet&amp;lt;T&amp;gt;, ImmutableStack&amp;lt;T&amp;gt;, etc. As fore mentioned, trying to mutate an immutable collection creates a new immutable collection:&lt;/p&gt;
&lt;p&gt;internal static void ImmutableCollection()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableList&amp;lt;int&amp;gt; immutableList1 = ImmutableList.Create(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableList&amp;lt;int&amp;gt; immutableList2 = immutableList1.Add(4); // Create a new collection.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(immutableList1, immutableList2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET Standard also provides readonly collections, like ReadOnlyCollection&amp;lt;T&amp;gt;, ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;, etc. These readonly collections are actually a simple wrapper of the specified collections. They just do not implement or expose mutation methods like Add, Remove, etc. They are not immutable or thread safe. The following example initializes an immutable collection and a readonly collection from a mutable source. When the source is mutated, the immutable collection apparently is not impacted, but the readonly collection mutates too:&lt;/p&gt;
&lt;p&gt;internal static void ReadOnlyCollection()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; mutableList = new List&amp;lt;int&amp;gt;() { 1, 2, 3 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ImmutableList&amp;lt;int&amp;gt; immutableList = ImmutableList.CreateRange(mutableList);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ReadOnlyCollection&amp;lt;int&amp;gt;readOnlyCollection = new ReadOnlyCollection&amp;lt;int&amp;gt;(mutableList);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mutableList.Add(4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;immutableList.Count.WriteLine(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;readOnlyCollection.Count.WriteLine(); // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Shallow immutability vs. deep immutability&lt;/h3&gt;
&lt;p&gt;When working with immutable types, it is noteworthy that how immutable this type is. Take the following type as example, it represents a bundle of 2 devices:&lt;/p&gt;
&lt;p&gt;internal class Bundle&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Bundle(MutableDevice device1, MutableDevice device2) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.Device1, this.Device2) = (device1, device2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal MutableDevice Device1 { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal MutableDevice Device2 { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This type is apparently immutable. Once it is initialized with 2 device instances, there is no way to alter these 2 instances to different instances. However, these 2 device instances are mutable, their names and prices can be altered in place:&lt;/p&gt;
&lt;p&gt;internal static void ShallowImmutability()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MutableDevice device1 = new MutableDevice() { Name = &quot;Surface Book&quot;, Price = 1199M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MutableDevice device2 = new MutableDevice() { Name = &quot;HoloLens&quot;, Price = 3000M };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Bundle bundle = new Bundle(device1, device2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Reassignment to bundle.Device1, bundle.Device2 cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bundle.Device1.Name = &quot;Surface Studio&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bundle.Device1.Price = 2999M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bundle.Device2.Price -= 50M;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, the above type is only immutable to a certain level. Below that level, mutation can happen. This is called shallow immutability. In contrast, the following type is more immutable:&lt;/p&gt;
&lt;p&gt;internal class Bundle&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Bundle(ImmutableDevice device1, ImmutableDevice device2) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(this.Device1, this.Device2) = (device1, device2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableDevice Device1 { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ImmutableDevice Device2 { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This time a bundle consists of 2 immutable devices, and each immutable device consists of an immutable int value and an immutable string value. So, this type is immutable all levels down and completely thread-safe, which is called deep immutability.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Immutability is important in functional programming. C# has a number of features for immutable value, including constant local, enumeration, using statement and foreach statement, immutable alias, function’s immutable input and immutable output, LINQ expression’s range variable, and this reference in class instance function members. To implement immutable state inside an instance, C# provides constant field and readonly field for type, readonly structure, immutable anonymous type, and tuple. Microsoft also provide a library of immutable collections.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (13) Pure Function</title><link>https://dixin.github.io/posts/functional-csharp-pure-function/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-pure-function/</guid><description>The previous chapter discusses that functional programming encourages modelling data as immutable. Functional programming also encourages modelling operations as pure functions. The encouraged purity</description><pubDate>Thu, 13 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous chapter discusses that functional programming encourages modelling data as immutable. Functional programming also encourages modelling operations as pure functions. The encouraged purity for function is the significant difference from method and procedure in imperative programming.&lt;/p&gt;
&lt;h2&gt;Pure function and impure function&lt;/h2&gt;
&lt;p&gt;A function is pure if:&lt;/p&gt;
&lt;p&gt;· Its output only depends on input, and does not depend on anything outside the function, like global variable, input from outside world to the hardware, etc. In another word, given the same input, it always gives the same output.&lt;/p&gt;
&lt;p&gt;· It does not have obvious interaction with the environment outside the function or the world outside the hardware when it is called. In another word, the function has no side effect. Here are some examples of side effect:&lt;/p&gt;
&lt;p&gt;o Mutate state&lt;/p&gt;
&lt;p&gt;o Mutate arguments, free variable, or global variable, etc.&lt;/p&gt;
&lt;p&gt;o Produce I/O (input/output between the hardware running the function and the outside world of that hardware)&lt;/p&gt;
&lt;p&gt;So pure function is like mathematics function, which is a deterministic mapping between a set of input and a set of output. Other functions are called impure functions.&lt;/p&gt;
&lt;p&gt;For example, the following functions are not deterministic, and they are impure:&lt;/p&gt;
&lt;p&gt;· Console.Read, Console.ReadLine, Console.ReadKey: give unpredictable output when called each time, since the functions’ output totally depends on the input from outside world to the hardware.&lt;/p&gt;
&lt;p&gt;· Random.Next, Guid.NewGuid, System.IO.Path.GetRandomFileName: give random output when called each time.&lt;/p&gt;
&lt;p&gt;· DateTime.Now, DateTimeOffset.Now: give different output when called at different time.&lt;/p&gt;
&lt;p&gt;And the following functions have side effects and they are impure:&lt;/p&gt;
&lt;p&gt;· Property setter: usually mutate state.&lt;/p&gt;
&lt;p&gt;· System.Threading.Thread.Start, Thread.Abort: mutate thread state and hardware state.&lt;/p&gt;
&lt;p&gt;· int.TryParse, Interlocked.Increase: mutate argument through out/ref parameter.&lt;/p&gt;
&lt;p&gt;· Console.Read, Console.ReadLine, Console.ReadKey, Console.Write, Console.WriteLine: produce console I/O.&lt;/p&gt;
&lt;p&gt;· System.IO.Directory.Create, Directory.Move, Directory.Delete, File.Create, File.Move, File.Delete, File.ReadAllBytes, File.WriteAllBytes: produce file system I/O.&lt;/p&gt;
&lt;p&gt;· System.Net.Http.HttpClient.GetAsync, HttpClient.PostAsync, HttpClinet.PutAsync, HttpClient.DeleteAsync: produce network I/O.&lt;/p&gt;
&lt;p&gt;· IDisposable.Dispose: interact with environment to release unmanaged resources, and usually mutate the current state to disposed.&lt;/p&gt;
&lt;p&gt;Strictly speaking, any function can interact with the outside world. A function call can at least have the hardware consuming electric energy from outside world and producing heat to outside world. When identifying function’s purity, only explicit interactions are considered.&lt;/p&gt;
&lt;p&gt;In contrast, the following examples are pure functions because they are both deterministic and side effect free:&lt;/p&gt;
&lt;p&gt;· Most mathematics functions, like numeric primitive types and decimal’s arithmetic operators, most of System.Math type’s static methods, etc. Take Math.Max and Math.Min as examples, their computed output only depends on the input, and they do not produce any side effect, like mutating state/argument/global variable, producing I/O, etc.:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Math
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Max(int val1, int val2) =&amp;gt; (val1 &amp;gt;= val2) ? val1 : val2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Min(int val1, int val2) =&amp;gt; (val1 &amp;lt;= val2) ? val1 : val2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;· object’s methods, like GetHashCode, GetType, Equals, ReferenceEquals, ToString, etc.&lt;/p&gt;
&lt;p&gt;· System.Convert type’ conversion methods, like ToBoolean, ToInt32, etc.&lt;/p&gt;
&lt;p&gt;· Property getter to simply output a state without mutating any state or producing other side effect, like string.Length, Nullable&amp;lt;T&amp;gt;.HasValue, Console.Error, etc.&lt;/p&gt;
&lt;p&gt;· Immutable type’s function members for transformation, like string.Concat, string.Substring, string.Insert, string.Replace, string.Trim, string.ToUpper, string.ToLower, etc.&lt;/p&gt;
&lt;p&gt;Since pure function is deterministic and side effect free, a pure function call expression and a constant expression of the result can always replace each other. This is called referential transparency.&lt;/p&gt;
&lt;p&gt;Similar to immutable data, pure function can make code easier to write, test, and maintain in many cases. Pure function does not involve state mutation, and brings all benefits of immutability. Pure function is self-contained without external dependency or interaction, which greatly improves testability and maintainability. If 2 pure function calls have no input/output dependency, the function calls’ order does not matter, which greatly simplifies parallel computing. For example, purity is important in Parallel LINQ query, which is discussed in Parallel LINQ chapters.&lt;/p&gt;
&lt;p&gt;As mentioned in the introduction chapter, there is a specialized functional programming paradigm called purely functional programming, which only allows immutable data and pure function. A few languages, like Haskell, are designed for this paradigm only, and they are called purely functional language. Other functional languages, like C#, F#, allows immutable data and mutable data, pure function and impure function, and they are called impure functional language. In purely functional programming, side effects can be managed by monad, like I/O monad, etc. Monad is discussed in the category theory chapters.&lt;/p&gt;
&lt;h2&gt;Purity in .NET&lt;/h2&gt;
&lt;p&gt;.NET Standard provides System.Diagnostics.Contracts.PureAttribute. It can be used for a function member to specify that function is pure, or be used for a type to specify all function members of that type are pure:&lt;/p&gt;
&lt;p&gt;[Pure]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static bool IsPositive(int int32) =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool IsNegative(int int32) // Impure.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(int32); // Side effect: console I/O.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32 &amp;lt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static class AllFunctionsArePure
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int Increase(int int32) =&amp;gt; int32 + 1; // Pure.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int Decrease(int int32) =&amp;gt; int32 - 1; // Pure.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Looks great. Unfortunately, this attribute is provided not for general purpose but only for Code Contracts, a .NET tool provided (and now discontinued) by Microsoft. Code Contracts tool consists of:&lt;/p&gt;
&lt;p&gt;· Code contracts APIs under System.Diagnostics.Contracts namespace to specify preconditions, post conditions, invariant, purity, etc., including the above PureAttribute.&lt;/p&gt;
&lt;p&gt;· Contracts assemblies for most commonly used FCL assemblies&lt;/p&gt;
&lt;p&gt;· Compile time rewriter and analyzer&lt;/p&gt;
&lt;p&gt;· Runtime analyzer&lt;/p&gt;
&lt;p&gt;In a function member, the contracts for its code can be specified declaratively with System.Diagnostics.Contracts.Contract type’s static methods. These contracts can be analysed at compile time and runtime. Apparently, they must be referential transparent and cannot rely on any side effect. So, only pure function (function with [Pure] contract) are allowed to be called with contracts APIs, like the above IsPositive function:&lt;/p&gt;
&lt;p&gt;internal static int DoubleWithPureContracts(int int32)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(IsPositive(int32)); // Function precondition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Ensures(IsPositive(Contract.Result&amp;lt;int&amp;gt;())); // Function post condition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32 + int32; // Function body.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In contrast, the following example calls impure function (function without [Pure] contract) in contracts:&lt;/p&gt;
&lt;p&gt;internal static int DoubleWithImpureContracts(int int32)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(IsNegative(int32)); // Function precondition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Ensures(IsNegative(Contract.Result&amp;lt;int&amp;gt;())); // Function post condition.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32 + int32; // Function body.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;At compile time, Code Contracts gives a warning: Detected call to method IsNegative(System.Int32)&apos; without [Pure] in contracts of method ‘DoubleWithImpureContracts(System.Int32)&apos;.&lt;/p&gt;
&lt;p&gt;Code Contracts has been a very useful code tool for compile time and runtime, but Microsoft has discontinued this tool, so it only works for .NET Framework 4.0 and 4.5 on Windows. As a result, [Pure] attribute is actually obsolete.&lt;/p&gt;
&lt;p&gt;When code is compiled and built to assembly, its contracts can either be compiled to the same assembly, or to a separate contracts assembly. Since .NET Framework FCL assemblies are already shipped, Microsoft provides 25 contracts assemblies separately for 25 most commonly used assemblies, including mscorlib.Contracts.dll (contracts for mscorlib.dll core library), System.Core.Contracts.dll (contracts for System.Core.dll assembly of LINQ to Objects and LINQ to Parallel, and remote LINQ APIs), System.Xml.Linq.Contracts.dll (contracts for System.Xml.Linq.dll assembly of LINQ to XML), etc. For example, Math.Abs function is provided in mscorlib.dll, so its contracts are provided in mscorlib.Contracts.dll as empty function with the same signature, with only contracts:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Math
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Abs(int value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Requires(value != int.MinValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Ensures(Contract.Result&amp;lt;int&amp;gt;() &amp;gt;= 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Contract.Ensures((value - Contract.Result&amp;lt;int&amp;gt;()) &amp;lt;= 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# and .NET Standard are designed in impure paradigm to allow immutability and mutability, purity and impurity. As a result, only a small percentage of the provided functions are pure. This can be demonstrated by utilizing above contracts assemblies and [Pure] contract. The following example has 2 LINQ to Objects queries. The first query counts all pure public functions in the contract assemblies. As fore mentioned, if a function has [Pure] attribute, it is pure; if a type has [Pure] attribute, its functions are all pure. Then the second query counts all public functions in corresponding library assemblies. In both queries, Mono’s reflection library, Mono.Cecil NuGet package, is used, because it can load .NET Framework assemblies and contracts assemblies correctly from different platforms, including Linux/Mac/Windows.&lt;/p&gt;
&lt;p&gt;internal internal static void FunctionCount(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string contractsAssemblyDirectory, string assemblyDirectory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool HasPureAttribute(ICustomAttributeProvider member) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;member.CustomAttributes.Any(attribute =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;attribute.AttributeType.FullName.Equals(typeof(PureAttribute).FullName, StringComparison.Ordinal));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string[] contractsAssemblyPaths = Directory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.EnumerateFiles(contractsAssemblyDirectory, &quot;*.Contracts.dll&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToArray();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Query the count of pure functions in all contracts assemblies, including all public functions in public type with [Pure], and all public function members with [Pure] in public types.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int pureFunctionCount = contractsAssemblyPaths
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(AssemblyDefinition.ReadAssembly)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(contractsAssembly =&amp;gt; contractsAssembly.Modules)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(contractsModule =&amp;gt; contractsModule.GetTypes())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(contractsType =&amp;gt; contractsType.IsPublic)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(contractsType =&amp;gt; HasPureAttribute(contractsType)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? contractsType.Methods.Where(contractsFunction =&amp;gt; contractsFunction.IsPublic)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: contractsType.Methods.Where(contractsFunction =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;contractsFunction.IsPublic &amp;amp;&amp;amp; HasPureAttribute(contractsFunction)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;pureFunctionCount.WriteLine(); // 2223
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Query the count of all public functions in public types in all FCL assemblies.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int functionCount = contractsAssemblyPaths
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(contractsAssemblyPath =&amp;gt; Path.Combine(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;assemblyDirectory,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Path.ChangeExtension(Path.GetFileNameWithoutExtension(contractsAssemblyPath), &quot;dll&quot;)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(AssemblyDefinition.ReadAssembly)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(assembly =&amp;gt; assembly.Modules)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(module =&amp;gt; module.GetTypes())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(type =&amp;gt; type.IsPublic)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(type =&amp;gt; type.Methods)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(function =&amp;gt; function.IsPublic);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionCount.WriteLine(); // 82566
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As a result, in the 25 most commonly used FCL assemblies, there are only 2.69% public function members are pure.&lt;/p&gt;
&lt;h2&gt;Purity in LINQ&lt;/h2&gt;
&lt;p&gt;All built-in LINQ query methods have 3 kinds of output: a queryable source, a collection, and a single value. All query methods with queryable source output type are pure functions, the other query methods are impure. For example, the fore mentioned Where, Select, OrderBy query methods of local and remote LINQ are pure:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following ToArray, ToList query methods of local LINQ output collection, and they are impure:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static List&amp;lt;TSource&amp;gt; ToList&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following First query methods of local and remote LINQ output a single value, and they are also impure:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The query methods with queryable source output are implemented as pure function by simply constructing a new source instance with the input source. Calling these query methods only deterministically defines a new query and the query execution is deferred, so there is no state mutation or side effect. The output new query can be executed by pulling the results, which can mutate the query’s state and can produce side effect. The other query methods with collection or single value output are different. They immediately execute the pulling from their input source, which can mutate state and can produce side effect, so they are impure. The internal implementation of these methods is covered in the LINQ chapters.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Pure function is important in functional programming. Pure function is deterministic and side effect free, so they are easy to write, test, maintain and parallelize. In LINQ, all query methods with queryable source output are pure functions.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (11) Covariance and Contravariance</title><link>https://dixin.github.io/posts/functional-csharp-covariance-and-contravariance/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-covariance-and-contravariance/</guid><description>In programming languages with subtyping support, variance is the ability to substitute a type with a different subtype or supertype in a context. For example, having a subtype and a supertype, can a f</description><pubDate>Tue, 11 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;In programming languages with subtyping support, variance is the ability to substitute a type with a different subtype or supertype in a context. For example, having a subtype and a supertype, can a function of subtype output substitute a function of supertype output? Can a sequence of subtype substitute a sequence of supertype? C# supports covariance/contravariance, which means to use a more/less specific type to substitute the required type in the context of function and interface.&lt;/p&gt;
&lt;h2&gt;Subtyping and type polymorphism&lt;/h2&gt;
&lt;p&gt;The following is a simple example of subtyping:&lt;/p&gt;
&lt;p&gt;internal interface ISupertype { /* Members. */ }&lt;/p&gt;
&lt;p&gt;internal interface ISubtype : ISupertype { /* More members. */ }&lt;/p&gt;
&lt;p&gt;Here ISubtype interface implements ISupertype interface. In this relationship, ISubtype is more specific supertype, and ISupertype is less specific supertype, which can be denoted ISubtype &amp;lt;: ISupertype. A subtype instance can substitute a supertype instance. In another word, an instance’s type can be more specific than required type:&lt;/p&gt;
&lt;p&gt;internal static void Substitute(ISupertype supertype, ISubtype subtype)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;supertype = subtype;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In object-oriented programming, subtyping is intuitive with inheritance:&lt;/p&gt;
&lt;p&gt;internal class Base { }&lt;/p&gt;
&lt;p&gt;internal class Derived : Base { }&lt;/p&gt;
&lt;p&gt;Similarly, Derived is a more derived and more specific subtype, and Base is a less derived and less specific supertype. Apparently Derived &amp;lt;: Base (called a Derived instance “is a” Base instance in object-oriented programming), and Derived instance can substitute Base instance (called Liskov substitution principle in object-oriented programming):&lt;/p&gt;
&lt;p&gt;internal static void Substitute()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base @base = new Base();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@base = new Derived();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C#’s covariance and contravariance enables the subtyping and substitution relationship for functions and generic interfaces. Subtyping does not have to be inheritance, but to be intuitive to most C# developers, this chapter uses above Base and Derived types to demonstrate variances in all contexts. As discussed in the C# basics chapter, in C#, value types consist of structures and enumerations. All structures inherit System.ValueType class, and all enumerations inherit System.Enum class, so one value type cannot be subtype of another value type. As a result, C#’s covariance and contravariance only applies to reference types, so the above Base and Derived types are defined as classes.&lt;/p&gt;
&lt;h2&gt;Variances of non-generic function type&lt;/h2&gt;
&lt;p&gt;When using above Base and Derived as input and output type of function, there are 4 cases:&lt;/p&gt;
&lt;p&gt;// Derived -&amp;gt; Base&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Base DerivedToBase(Derived input) =&amp;gt; new Base();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Derived -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Derived DerivedToDerived(Derived input) =&amp;gt; new Derived();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Base -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Base BaseToBase(Base input) =&amp;gt; new Base();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal static Derived BaseToDerived(Base input) =&amp;gt; new Derived();&lt;/p&gt;
&lt;p&gt;Their function types can be represented by the following non-generic delegate types:&lt;/p&gt;
&lt;p&gt;// Derived -&amp;gt; Base&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Base DerivedToBase(Derived input);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Derived -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Derived DerivedToDerived(Derived input);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Base -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Base BaseToBase(Base input);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal delegate Derived BaseToDerived(Base input);&lt;/p&gt;
&lt;p&gt;Take the first function DerivedToBase as example, it is of type Derived -&amp;gt; Base, represented by the first delegate type DerivedToBase:&lt;/p&gt;
&lt;p&gt;internal static void NonGenericDelegate()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DerivedToDerived derivedToDerived = DerivedToDerived;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Derived output = derivedToDerived(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The second function DerivedToDerived is not of type Derived -&amp;gt; Base, but Derived -&amp;gt; Derived, represented by the second delegate type. Since C# 2.0, DerivedToBase can be substituted by DerivedToDerived in context of non-generic delegate:&lt;/p&gt;
&lt;p&gt;internal static void NonGenericDelegateCovariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance: Derived &amp;lt;: Base, so that Derived -&amp;gt; Derived &amp;lt;: Derived -&amp;gt; Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = DerivedToDerived; // Derived -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling derivedToBase, DerivedToDerived executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// derivedToBase should output Base, while DerivedToDerived outputs Derived.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Derived output substitutes the required Base output. This call always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output = derivedToBase(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, function with more derived/specific output can substitute function with less derived/specific output, as if former function type is subtype and latter function type is supertype. In another word, function instance’s actual output can be more derived/specific than function type’s required output. This is called covariance, because it persists the direction of subtyping/substitution: if Derived &amp;lt;: Based then function with Derived output &amp;lt;: function with Base output. Similarly, function instance’s input can be less derived/specific than function type input:&lt;/p&gt;
&lt;p&gt;internal static void NonGenericDelegateContravariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Contravariance: Derived &amp;lt;: Base, so that Base -&amp;gt; Base &amp;lt;: Derived -&amp;gt;Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = BaseToBase; // Base -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling derivedToBase, BaseToBase executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// derivedToBase should accept Derived input, while BaseToBase accepts Base input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Derived input substitutes the accepted Base input. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output = derivedToBase(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, function with less derived/specific input can substitute function with more derived input, or in another word, function instance’s output can be less derived/specific than function type’s required input. This is called contravariance, because it inverts the direction of subtyping/substitution: if Derived &amp;lt;: Base then function with Base input&amp;lt; : function with Derived inp_ut._ Covariance (for output) and contravariance (for input) can work at the same time:&lt;/p&gt;
&lt;p&gt;internal static void NonGenericDelegateCovarianceAndContravariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance and contravariance: Derived &amp;lt;: Base, so that Base -&amp;gt; Derived &amp;lt;: Derived -&amp;gt; Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = BaseToDerived; // Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling derivedToBase, BaseToDerived executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// derivedToBase should accept Derived input, while BaseToDerived accepts Base input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Derived input substitutes the accepted Base input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// derivedToBase should output Base, while BaseToDerived outputs Derived.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Derived output substitutes the required Base output. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output = derivedToBase(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;On the other hand, function output cannot be less derived/specific than required, and function input cannot be more derived/specific than required. The following function substitution cannot be compiled:&lt;/p&gt;
&lt;p&gt;internal static void NonGenericDelegateInvariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// baseToDerived should output Derived, while BaseToBase outputs Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Base output does not substitute the required Derived output. This cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;BaseToDerived baseToDerived = BaseToBase; // Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// baseToDerived should accept Base input, while DerivedToDerived accepts Derived input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Base input does not substitute the accepted Derived input. This cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseToDerived = DerivedToDerived; // Derived -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// baseToDerived should accept Base input, while DerivedToBase accepts Derived input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Base input does not substitute the expected Derived input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// baseToDerived should output Derived, while DerivedToBase outputs Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Base output does not substitute the required Derived output. This cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseToDerived = DerivedToBase; // Derived -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Variances of generic function type&lt;/h2&gt;
&lt;p&gt;With generic delegate type, all the above function types can be represented by:&lt;/p&gt;
&lt;p&gt;internal delegate TOutput GenericFunc&amp;lt;TInput, TOutput&amp;gt;(TInput input);&lt;/p&gt;
&lt;p&gt;Then the delegate instance can be initialized with variances:&lt;/p&gt;
&lt;p&gt;internal static void GenericDelegateCovarianceAndContravariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericFunc&amp;lt;Derived, Base&amp;gt; derivedToBase = DerivedToBase; // No variance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = DerivedToDerived; // Covariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = BaseToBase; // Contravariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = BaseToDerived; // Covariance and contravariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For functions of GenericFunc&amp;lt;TInput, TOutput&amp;gt; type, covariance enables TOutput to be substituted by more specific type, and contravariance enables TInput to be substituted by less derived type. So TOutput/TInput are called covariant/contravariant type parameter for this generic delegate type. C# 4.0 introduces the out/in modifiers for the covariant/contravariant type parameter:&lt;/p&gt;
&lt;p&gt;internal delegate TOutput GenericFuncWithVariances&amp;lt;in TInput, out TOutput&amp;gt;(TInput input);&lt;/p&gt;
&lt;p&gt;These modifiers enable further variances, the substitution of generic delegate instances:&lt;/p&gt;
&lt;p&gt;internal static void GenericDelegateInstanceSubstitution()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericFuncWithVariances&amp;lt;Derived, Base&amp;gt;derivedToBase = DerivedToBase; // Derived -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericFuncWithVariances&amp;lt;Derived, Derived&amp;gt;derivedToDerived = DerivedToDerived; // Derived -&amp;gt;Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericFuncWithVariances&amp;lt;Base, Base&amp;gt;baseToBase = BaseToBase; // Base -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericFuncWithVariances&amp;lt;Base, Derived&amp;gt;baseToDerived = BaseToDerived; // Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled without the out/in modifiers.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = derivedToDerived; // Covariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = baseToBase; // Contravariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;derivedToBase = baseToDerived; // Covariance and contravariance.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As discussed, TInput cannot be covariant, and TOutput cannot be contravariant, in the following definition, TInput with out modifier or TOutput with in modifier cannot work:&lt;/p&gt;
&lt;p&gt;// Cannot be compiled.&lt;/p&gt;
&lt;p&gt;internal delegate TOutput GenericFuncWithVariances&amp;lt;out TInput, in TOutput&amp;gt;(TInput input);&lt;/p&gt;
&lt;p&gt;As mentioned in the delegate chapter, unified Func and Action generic delegate types are provided to represent all function types. Since .NET Framework 4.0, all their type parameters have the out/in modifiers:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;out TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T1, in T2, out TResult&amp;gt;(T1 arg1, T2 arg2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T&amp;gt;(T obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T1, in T2&amp;gt;(T1 arg1, T2 arg2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Variant type parameter is not syntactic sugar, but a runtime feature. The out/in modifiers are compiled to the +/- flags in CIL, which can be read as can be more/less specific:&lt;/p&gt;
&lt;p&gt;.class public auto ansi sealed Func&amp;lt;-T, +TResult&amp;gt; extends System.MulticastDelegate&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Variances of generic interface&lt;/h2&gt;
&lt;p&gt;Besides generic function types, C# 4.0 also supports variances for generic interfaces. An interface can be viewed as a group of function types of named function members. For example:&lt;/p&gt;
&lt;p&gt;internal interface IOutput&amp;lt;out TOutput&amp;gt; // TOutput is covariant for all members using TOutput.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOutput ToOutput(); // TOutput is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOutput Output { get; } // Compiled to get_Output. TOutput is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void TypeParameterNotUsed();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above generic interface definition has 3 function members, where 2 function members uses the type parameter only as output type. Apparently, the type parameter is covariant for both 2 functions’ function types. In this case, the type parameter is covariant for the interface level, and the out modifier can be used to enable the substitution of interface instances:&lt;/p&gt;
&lt;p&gt;internal static void GenericInterfaceCovariance(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IOutput&amp;lt;Base&amp;gt; outputBase, IOutput&amp;lt;Derived&amp;gt; outputDerived)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance: Derived &amp;lt;: Base, so that IOutput&amp;lt;Derived&amp;gt; &amp;lt;: IOutput&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;outputBase = outputDerived;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling outputBase.ToOutput, outputDerived.ToOutput executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// outputBase.ToOutput should output Base, outputDerived.ToOutput outputs Derived.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Derived output substitutes the required Base output. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output1 = outputBase.ToOutput();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output2 = outputBase.Output; // .get_Output();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;IOutput&amp;lt;Derived&amp;gt; interface does not implement IOutput&amp;lt;Base&amp;gt; interface, but with out modifier, IOutput&amp;lt;Derived&amp;gt; instance can still substitute IOutput&amp;lt;Base&amp;gt; instance, as if IOutput&amp;lt;Derived&amp;gt; is subtype and IOutput&amp;lt;Base&amp;gt; is supertype.&lt;/p&gt;
&lt;p&gt;Similarly, generic interface can also have contravariant type parameter, with in modifier:&lt;/p&gt;
&lt;p&gt;internal interface IInput&amp;lt;in TInput&amp;gt; // TInput is contravariant for all members using TInput.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void InputToVoid(TInput input); // TInput is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TInput Input { set; } // Compiled to set_Input. TInput is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void TypeParameterNotUsed();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above generic interface definition has 3 function members, where 2 function members uses the type parameter only as input type. Apparently, the type parameter is contravariant for both 2 functions’ function types. In this case, the type parameter is contravariant for the interface level, and the in modifier can be used to enable the substitution of interface instances:&lt;/p&gt;
&lt;p&gt;internal static void GenericInterfaceContravariance(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IInput&amp;lt;Derived&amp;gt; inputDerived, IInput&amp;lt;Base&amp;gt; inputBase)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Contravariance: Derived &amp;lt;: Base, so that IInput&amp;lt;Base&amp;gt; &amp;lt;: IInput&amp;lt;Derived&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerived = inputBase;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling inputDerived.Input, inputBase.Input executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// inputDerived.Input should accept Derived input, while inputBase.Input accepts Base input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Derived output substitutes the accepted Base input. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerived.InputToVoid(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerived.Input = new Derived(); // .set_Input(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;IInput&amp;lt;Base&amp;gt; interface does not implement IInput&amp;lt;Derived&amp;gt; interface, but with in modifier, IInput&amp;lt;Base&amp;gt; instance can still substitute IInput&amp;lt;Derived&amp;gt; instance, as if IInput&amp;lt;Base&amp;gt; is subtype and IInput&amp;lt;Derived&amp;gt; is supertype.&lt;/p&gt;
&lt;p&gt;Similar to generic delegate type, generic interface can have covariant type parameter and contravariant type parameter at the same time:&lt;/p&gt;
&lt;p&gt;internal interface IInputOutput&amp;lt;in TInput, out TOutput&amp;gt; // TInput is contravariant for all members using TInput, TOutput is covariant for all members usingTOutput.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void InputToVoid(TInput input); // TInput is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TInput Input { set; } // Compiled to set_Input. TInput is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOutput ToOutput(); // TOutput is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TOutput Output { get; } // Compiled to get_Output. TOutput is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void TypeParameterNotUsed();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example demonstrates the covariance and contravariance:&lt;/p&gt;
&lt;p&gt;internal static void GenericInterfaceCovarianceAndContravariance(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IInputOutput&amp;lt;Derived, Base&amp;gt;inputDerivedOutputBase,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IInputOutput&amp;lt;Base, Derived&amp;gt; inputBaseOutputDerived)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance and contravariance: Derived &amp;lt;: Base, so that IInputOutput&amp;lt;Base, Derived&amp;gt; &amp;lt;: IInputOutput&amp;lt;Derived, Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerivedOutputBase = inputBaseOutputDerived;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerivedOutputBase.InputToVoid(new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inputDerivedOutputBase.Input = new Derived(); // .set_Input(input: new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output1 = inputDerivedOutputBase.ToOutput();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base output2 = inputDerivedOutputBase.Output; // .get_Output();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Not all type parameters can be variant for generic interface. For example:&lt;/p&gt;
&lt;p&gt;internal interface IInvariant&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T Output(); // T is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Input(T input); // T is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The type parameter T is neither covariant for all function members using T, nor contravariant for all function members using T, so T cannot be covariant or contravariant for the interface level.&lt;/p&gt;
&lt;h2&gt;Variances of generic higher-order function type&lt;/h2&gt;
&lt;p&gt;The variances are interesting for generic higher-order function types. Higher-order function type can be defined by outputting function, since it outputs a function. Regarding the type parameter is only used as output, use the out modifier:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; () -&amp;gt; TOutput Equivalent to Func&amp;lt;Func&amp;lt;TOutput&amp;gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;internal delegate Func&amp;lt;TOutput&amp;gt; ToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant output type.&lt;/p&gt;
&lt;p&gt;Marking the type parameter as covariant, the code can still be compiled. The following example demonstrates how the variance and substitution work at runtime:&lt;/p&gt;
&lt;p&gt;internal static void OutputCovariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// First order functions.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Base&amp;gt;toBase = () =&amp;gt; new Base(); // () -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Derived&amp;gt; toDerived = () =&amp;gt; new Derived(); // () -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Higher-order functions.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ToFunc&amp;lt;Base&amp;gt;toToBase = () =&amp;gt; toBase; // () -&amp;gt; () -&amp;gt; Base
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ToFunc&amp;lt;Derived&amp;gt; toToDerived = () =&amp;gt; toDerived; // () -&amp;gt; () -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance: Derived &amp;lt;: Base, so that () -&amp;gt; () -&amp;gt; Derived &amp;lt;: () -&amp;gt; () -&amp;gt; Base.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;toToBase = toToDerived;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling toToBase, toToDerived executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// toToBase should output Func&amp;lt;Base&amp;gt;, while toToDerived outputs Func&amp;lt;Derived&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The actual Func&amp;lt;Derived&amp;gt; output substitutes the required Func&amp;lt;Base&amp;gt; output. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Base&amp;gt;output = toToBase();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The reason is, covariance persists the direction of subtyping and substitution, Derived &amp;lt;: Base in Context&amp;lt;out T&amp;gt; leads to Context&amp;lt;Derived&amp;gt; &amp;lt;: Context&amp;lt;Base&amp;gt;, Context&amp;lt;Context&amp;lt;Derived&amp;gt;&amp;gt; &amp;lt;: Context&amp;lt;Context&amp;lt;Base&amp;gt;&amp;gt;, Context&amp;lt;Context&amp;lt;Context&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; &amp;lt;: Context&amp;lt;Context&amp;lt;Context&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt;, and so on. T is always covariant for Context&amp;lt;Context&amp;lt;T&amp;gt;&amp;gt;, Context&amp;lt;Context&amp;lt;Context&amp;lt;T&amp;gt;&amp;gt;&amp;gt;, etc. Take above Func&amp;lt;out TResult&amp;gt; as example:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; TOutput&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate TOutput Func&amp;lt;out TOutput&amp;gt;(); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; () -&amp;gt; TOutput: Equivalent to Func&amp;lt;Func&amp;lt;TOutput&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Func&amp;lt;TOutput&amp;gt; ToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; () -&amp;gt; () -&amp;gt; TOutput: Equivalent to Func&amp;lt;Func&amp;lt;Func&amp;lt;TOutput&amp;gt;&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate ToFunc&amp;lt;TOutput&amp;gt; ToToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; () -&amp;gt; () -&amp;gt; () -&amp;gt; TOutput: Equivalent to Func&amp;lt;Func&amp;lt;Func&amp;lt;Func&amp;lt;TOutput&amp;gt;&amp;gt;&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate ToToFunc&amp;lt;TOutput&amp;gt; ToToToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;p&gt;Higher-order function type can also be defined by accepting function as input. Regarding the type parameter is only used as input, use the in modifier:&lt;/p&gt;
&lt;p&gt;// (TInput -&amp;gt; void) -&amp;gt; void: Equivalent to Action&amp;lt;Action&amp;lt;TInput&amp;gt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;internal delegate void ActionToVoid&amp;lt;in TTInput&amp;gt;(Action&amp;lt;TTInput&amp;gt; action); // Cannot be compiled.&lt;/p&gt;
&lt;p&gt;However, the above code cannot be compiled. Marking the type parameter as covariant works:&lt;/p&gt;
&lt;p&gt;// (TInput -&amp;gt; void) -&amp;gt; void: Equivalent to Action&amp;lt;Action&amp;lt;TInput&amp;gt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;internal delegate void ActionToVoid&amp;lt;out TInput&amp;gt;(Action&amp;lt;TInput&amp;gt; action);&lt;/p&gt;
&lt;p&gt;And this is how the variance and substitution works at runtime:&lt;/p&gt;
&lt;p&gt;internal static void InputCovarianceAndContravariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Higher-order functions.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ActionToVoid&amp;lt;Derived&amp;gt; derivedToVoidToVoid = (Action&amp;lt;Derived&amp;gt; derivedToVoid) =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ActionToVoid&amp;lt;Base&amp;gt; baseToVoidToVoid = (Action&amp;lt;Base&amp;gt;baseToVoid) =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance: Derived &amp;lt;: Base, so that(Derived -&amp;gt; void) -&amp;gt; void &amp;lt;: (Base -&amp;gt; void) -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseToVoidToVoid = derivedToVoidToVoid;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When calling baseToVoidToVoid, derivedToVoidToVoid executes.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// baseToVoidToVoid should accept Action&amp;lt;Base&amp;gt; input, while derivedToVoidToVoid accepts Action&amp;lt;Derived&amp;gt; input.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// The required Action&amp;lt;Derived&amp;gt; input substitutes the accepted Action&amp;lt;Base&amp;gt; input. This always works.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseToVoidToVoid(default(Action&amp;lt;Base&amp;gt;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The reason is, contravariance inverts the direction of subtyping and substitution, Derived &amp;lt;: Base in Context&amp;lt;in T&amp;gt; leads to Context&amp;lt;Base&amp;gt; &amp;lt;: Context&amp;lt;Derived&amp;gt;, Context&amp;lt;Context&amp;lt;Derived&amp;gt;&amp;gt; &amp;lt;: Context&amp;lt;Context&amp;lt;Base&amp;gt;&amp;gt;, Context&amp;lt;Context&amp;lt;Context&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; &amp;lt;: Context&amp;lt;Context&amp;lt;Context&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt;, and so on. T becomes covariant for Context&amp;lt;Context&amp;lt;T&amp;gt;&amp;gt;, contravariant for Context&amp;lt; Context&amp;lt;Context&amp;lt;T&amp;gt;&amp;gt;&amp;gt;, covariant for Context&amp;lt;Context&amp;lt;Context&amp;lt;Context&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;, etc. Take above Action&amp;lt;in T&amp;gt; as example:&lt;/p&gt;
&lt;p&gt;// TInput -&amp;gt; void&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void Action&amp;lt;in TInput&amp;gt;(TInput input); // Contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (TInput -&amp;gt; void) -&amp;gt; void: Equivalent to Action&amp;lt;Action&amp;lt;TInput&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void ActionToVoid&amp;lt;out TTInput&amp;gt;(Action&amp;lt;TTInput&amp;gt; action); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ((TInput -&amp;gt; void) -&amp;gt; void) -&amp;gt; void: Equivalent to Action&amp;lt;Action&amp;lt;Action&amp;lt;TInput&amp;gt;&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void ActionToVoidToVoid&amp;lt;in TTInput&amp;gt;(ActionToVoid&amp;lt;TTInput&amp;gt; actionToVoid); // Contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (((TInput -&amp;gt; void) -&amp;gt; void) -&amp;gt; void) -&amp;gt; void: Equivalent to Action&amp;lt;Action&amp;lt;Action&amp;lt;Action&amp;lt;TInput&amp;gt;&amp;gt;&amp;gt;&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void ActionToVoidToVoidToVoid&amp;lt;out TTInput&amp;gt;(ActionToVoidToVoid&amp;lt;TTInput&amp;gt; actionToVoidToVoid); // Covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;h2&gt;Covariance of array&lt;/h2&gt;
&lt;p&gt;Array T[] implements IList&amp;lt;T&amp;gt; interface:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IList&amp;lt;T&amp;gt;: ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T this[int index] { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Indexer getter is compiled to get_Item. T is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Indexer setter is compiled to set_Item. T is contravariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For IList&amp;lt;T&amp;gt;, T is used by indexer getter and setter function members. T is the output type of the compiled get_Item function, and is the input type of the compiled set_Item function. Apparently, T is neither covariant for both functions’ types, and nor contravariant for both functions’ types. So, T should be invariant for IList&amp;lt;T&amp;gt; and array T[]. However, C# compiler and .NET runtime unexpectedly support covariance for array. The following example can be compiled, but throws ArrayTypeMismatchException at runtime, which can be a source of bugs:&lt;/p&gt;
&lt;p&gt;internal static void ArrayCovariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Base[] baseArray = new Base[3];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Derived[] derivedArray = new Derived[3];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseArray = derivedArray; // Array covariance: Derived &amp;lt;: Base, so that Derived[]&amp;lt; : Base[], baseArray refers to a Derived array at runtime.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseArray[1] = new Derived(); // .set_Item(new Derived());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;baseArray[2] = new Base(); // .set_Item(new Base());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ArrayTypeMismatchException at runtime. The actual Derived array requires Derived instance, the provided Base instance cannot substitute Derived instance.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Array covariance is first introduced to Java by its designers. They intended to remove this feature from Java around 1995, but they were unable to make it. Later, when .NET Framework is initially released, array covariance is implemented by CLR and C# as a Java feature for the convenience of Java developers. This is a C# language feature that should not be used.&lt;/p&gt;
&lt;h2&gt;Variances in .NET and LINQ&lt;/h2&gt;
&lt;p&gt;The following LINQ query finds the generic delegate types and interfaces with variant type parameters in .NET core library:&lt;/p&gt;
&lt;p&gt;internal static void TypesWithVariance()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly coreLibrary = typeof(object).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;coreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(type =&amp;gt; type.GetGenericArguments().Any(typeArgument =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;GenericParameterAttributes attributes = typeArgument.GenericParameterAttributes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return attributes.HasFlag(GenericParameterAttributes.Covariant)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|| attributes.HasFlag(GenericParameterAttributes.Contravariant);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(type =&amp;gt; type.FullName)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.WriteLines();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Action`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Action`2[T1,T2]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// …
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Action`8[T1,T2,T3,T4,T5,T6,T7,T8]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IComparer`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IEnumerable`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IEnumerator`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IEqualityComparer`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IReadOnlyCollection`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Collections.Generic.IReadOnlyList`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Comparison`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Converter`2[TInput,TOutput]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Func`1[TResult]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Func`2[T,TResult]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// …
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Func`9[T1,T2,T3,T4,T5,T6,T7,T8,TResult]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.IComparable`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.IObservable`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.IObserver`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.IProgress`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// System.Predicate`1[T]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Under System.Linq namespace, there are also a number of generic interfaces with variance: IGrouping&amp;lt;out TKey, out TElement&amp;gt;, IQueryable&amp;lt;out T&amp;gt;, IOrderedQueryable&amp;lt;out T&amp;gt;. Microsoft has documented the List of Variant Generic Interface and Delegate Types: https://docs.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance#VariantList, but it is inaccurate. It says TElement is covariant for IOrderedEnumerable&amp;lt;TElement&amp;gt;, but actually not:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Local LINQ query is represented by IEnumerable&amp;lt;T&amp;gt; generic interface, where T is covariant:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T Current { get; } // Compiled to get_Current.T is covariant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;First, In IEnumerator&amp;lt;T&amp;gt; interface, its type parameter is only used as output type of its Current property’s getter, which is compiled to get_Current function. Apparently T is covariance for its function type, so that T is also covariant for IEnumerator&amp;lt;T&amp;gt; interface level. Then, in IEnumerable&amp;lt;T&amp;gt;, T is only used by GetEnumerator. Here IEnumerator&amp;lt;T&amp;gt; can be virtually viewed as a simple wrapper of get_Current function, and GetEnumerator can be virtually viewed as a higher-order function that outputs (a wrapper of) get_Current function. As discussed, T is covariant for get_Current function, covariant for higher-order function GetEnumerator, and eventually covariant for IEnumerable&amp;lt;T&amp;gt; interface level.&lt;/p&gt;
&lt;p&gt;Remote LINQ query is represented by IQueryable&amp;lt;T&amp;gt;, where T is also covariant:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryable : IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Type ElementType { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression Expression { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider Provider { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;, Its type parameter T is only used by the GetEnumerator member from IEnumerable&amp;lt;T&amp;gt;, so apparently, T remains covariant for IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;Variance brings convenience to LINQ queries. Take the Concat and Select local query methods as example:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt;first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the following example, Concat is called with IEnumerable&amp;lt;Base&amp;gt; instance, so another IEnumerable&amp;lt;Base&amp;gt; instance is required. With covariance, IEnumerable&amp;lt;Derived&amp;gt; can substitute IEnumerable&amp;lt;Base&amp;gt;, so IEnumerable&amp;lt;Derived&amp;gt; argument can be directly passed to IEnumerable&amp;lt;base&amp;gt; parameter:&lt;/p&gt;
&lt;p&gt;internal static void Concat(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt; enumerableOfBase, IEnumerable&amp;lt;Derived&amp;gt; enumerableOfDerived)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance of Concat input: IEnumerable&amp;lt;Derived&amp;gt; &amp;lt;: IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Concat: (IEnumerable&amp;lt;Base&amp;gt;, IEnumerable&amp;lt;Base&amp;gt;) -&amp;gt; IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;enumerableOfBase = enumerableOfBase.Concat(enumerableOfDerived);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the following example, Select is called with IEnumerable&amp;lt;Derived&amp;gt; instance, and the output is stored as IEnumerable&amp;lt;Base&amp;gt; instance. According to the signature of Select, the selector function is required to be of Derived -&amp;gt; Base type. With covariance, selector function of Base -&amp;gt; Base, Derived -&amp;gt; Derived, and Base -&amp;gt; Derived types work as well:&lt;/p&gt;
&lt;p&gt;internal static void Select(IEnumerable&amp;lt;Derived&amp;gt; enumerableOfDerived)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt; enumerableOfBase;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Default with no variance.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select: (IEnumerable&amp;lt;Derived&amp;gt;, Derived -&amp;gt; Base) -&amp;gt; IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;enumerableOfBase = enumerableOfDerived.Select(DerivedToBase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance of Select input: IEnumerable&amp;lt;Derived&amp;gt; &amp;lt;: IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select: (IEnumerable&amp;lt;Base&amp;gt;, Base -&amp;gt; Base) -&amp;gt; IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;enumerableOfBase = enumerableOfDerived.Select(BaseToBase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance of Select output: IEnumerable&amp;lt;Derived&amp;gt; &amp;lt;: IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select: (IEnumerable&amp;lt;Derived&amp;gt;, Derived -&amp;gt; Derived) -&amp;gt; IEnumerable&amp;lt;Derived&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;enumerableOfBase = enumerableOfDerived.Select(DerivedToDerived);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Covariance of Select input and output: IEnumerable&amp;lt;Derived&amp;gt; &amp;lt;: IEnumerable&amp;lt;Base&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Select: (IEnumerable&amp;lt;Base&amp;gt;, Base -&amp;gt; Derived) -&amp;gt; IEnumerable&amp;lt;Derived&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;enumerableOfBase = enumerableOfDerived.Select(BaseToDerived);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses C#’s covariance and contravariance feature in the context of non-generic delegate types, generic delegate types, generic interfaces, generic higher-order function types, as well as arrays. Variances also brings convenience to LINQ query, since LINQ follows the pattern of fluent interface, which has covariant type parameter.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (10) Query Expression</title><link>https://dixin.github.io/posts/functional-csharp-query-expression/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-query-expression/</guid><description>C# 3.0 introduces query expression, a SQL-like query syntactic sugar for query methods composition.</description><pubDate>Mon, 10 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces query expression, a SQL-like query syntactic sugar for query methods composition.&lt;/p&gt;
&lt;h2&gt;Syntax and compilation&lt;/h2&gt;
&lt;p&gt;The following is the syntax of query expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from [Type] identifier in source
[from [Type] identifier in source]
[join [Type] identifier in source on expression equals expression [into identifier]]
[let identifier = expression]
[where predicate]
[orderby ordering [ascending | descending][, ordering [ascending | descending], …]]
select expression | group expression by key [into identifier]
[continuation]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It introduces new language keywords to C#, which are called query keywords:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;from&lt;/li&gt;
&lt;li&gt;join, on, equals&lt;/li&gt;
&lt;li&gt;let&lt;/li&gt;
&lt;li&gt;where&lt;/li&gt;
&lt;li&gt;orderby, ascending, descending&lt;/li&gt;
&lt;li&gt;select&lt;/li&gt;
&lt;li&gt;group, by&lt;/li&gt;
&lt;li&gt;into&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Query expression is compiled to query method calls at compile time:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;672&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Query expression&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Query method&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;single from clause with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;multiple from clauses with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;SelectMany&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Type in from/join clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Cast&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause without into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause with into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupJoin&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;let clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;where clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Where&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with or without ascending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderBy, ThenBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderByDescending, ThenByDescending&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;group clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;into with continuation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Nested query&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;It is already demonstrated how query expression syntax works for LINQ. Actually, this syntax is not specific for LINQ query or IEnumerable&amp;lt;T&amp;gt;/ParallelQuery&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt; types, but a &lt;a href=&quot;https://www.infoq.com/interviews/LINQ-Erik-Meijer&quot;&gt;general C# syntactic sugar&lt;/a&gt;. Take select clause (compiled to Select method call) as example, it can work for any type, as long as the compiler can find a Select instance method or extension method for that type. Take int as example, it does not have a Select instance method, so the following extension method can be defined to accept a selector function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Int32Extensions
{
    internal static TResult Select&amp;lt;TResult&amp;gt;(this int int32, Func&amp;lt;int, TResult&amp;gt; selector) =&amp;gt; 
        selector(int32);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now select clause of query expression syntax can be applied to int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryExpression
{
    internal static void SelectInt32()
    {
        int mapped1 = from zero in default(int) // 0
                      select zero; // 0
        double mapped2 = from three in 1 + 2 // 3
                         select Math.Sqrt(three + 1); // 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And they are compiled to above Select extension method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledSelectInt32()
{
    int mapped1 = Int32Extensions.Select(default, zero =&amp;gt; zero); // 0
    double mapped2 = Int32Extensions.Select(1 + 2, three =&amp;gt; Math.Sqrt(three + 1)); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More generally, Select method can be defined for any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ObjectExtensions
{
    internal static TResult Select&amp;lt;TSource, TResult&amp;gt;(this TSource value, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
        selector(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now select clause and Select method can be applied to any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectGuid()
{
    string mapped = from newGuid in Guid.NewGuid()
                    select newGuid.ToString();
}

internal static void CompiledSelectGuid()
{
    string mapped = ObjectExtensions.Select(Guid.NewGuid(), newGuid =&amp;gt; newGuid.ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some tools, like &lt;a href=&quot;https://www.jetbrains.com/resharper&quot;&gt;Resharper&lt;/a&gt;, a powerful &lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/EA4AC039-1B5C-4D11-804E-9BEDE2E63ECF&quot;&gt;extension for Visual Studio&lt;/a&gt;, can help converting query expressions to query methods at design time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/1c28168c455a_2436/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/1c28168c455a_2436/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Query expression pattern&lt;/h2&gt;
&lt;p&gt;To enable all the query keywords for a certain type, a set of query methods are required to be provided. The following interfaces demonstrate the signatures of the required methods for a locally queryable type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ILocal
{
    ILocal&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
}

public interface ILocal&amp;lt;T&amp;gt; : ILocal
{
    ILocal&amp;lt;T&amp;gt; Where(Func&amp;lt;T, bool&amp;gt; predicate);

    ILocal&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Func&amp;lt;T, TResult&amp;gt; selector);

    ILocal&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        Func&amp;lt;T, ILocal&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;T, TSelector, TResult&amp;gt; resultSelector);

    ILocal&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
        ILocal&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, TInner, TResult&amp;gt; resultSelector);

    ILocal&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
        ILocal&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, ILocal&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector);

    IOrderedLocal&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    IOrderedLocal&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    ILocal&amp;lt;ILocalGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    ILocal&amp;lt;ILocalGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
        Func&amp;lt;T, TKey&amp;gt; keySelector, Func&amp;lt;T, TElement&amp;gt; elementSelector);
}

public interface IOrderedLocal&amp;lt;T&amp;gt; : ILocal&amp;lt;T&amp;gt;
{
    IOrderedLocal&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    IOrderedLocal&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);
}

public interface ILocalGroup&amp;lt;TKey, T&amp;gt; : ILocal&amp;lt;T&amp;gt;
{
    TKey Key { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All above methods return ILocalSource&amp;lt;T&amp;gt;, so these methods or query expression clauses can be easily composed. The above query methods are represented as instance methods. As fore mentioned, extension methods work too. This is called the query expression pattern. Similarly, the following interfaces demonstrate the signatures of the required query methods for a remotely queryable type, which replaces all function parameters with expression tree parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IRemote
{
    IRemote&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
}

public interface IRemote&amp;lt;T&amp;gt; : IRemote
{
    IRemote&amp;lt;T&amp;gt; Where(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; predicate);

    IRemote&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt; selector);

    IRemote&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TSelector&amp;gt;&amp;gt;&amp;gt; selector,
        Expression&amp;lt;Func&amp;lt;T, TSelector, TResult&amp;gt;&amp;gt; resultSelector);

    IRemote&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
        IRemote&amp;lt;TInner&amp;gt; inner,
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
        Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
        Expression&amp;lt;Func&amp;lt;T, TInner, TResult&amp;gt;&amp;gt; resultSelector);

    IRemote&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
        IRemote&amp;lt;TInner&amp;gt; inner,
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
        Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
        Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TInner&amp;gt;, TResult&amp;gt;&amp;gt; resultSelector);

    IOrderedRemote&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IOrderedRemote&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector, Expression&amp;lt;Func&amp;lt;T, TElement&amp;gt;&amp;gt; elementSelector);
}

public interface IOrderedRemote&amp;lt;T&amp;gt; : IRemote&amp;lt;T&amp;gt;
{
    IOrderedRemote&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IOrderedRemote&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
}

public interface IRemoteGroup&amp;lt;TKey, T&amp;gt; : IRemote&amp;lt;T&amp;gt;
{
    TKey Key { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates how the query expression syntax is enabled for ILocal&amp;lt;T&amp;gt; and IRemote&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalQuery(ILocal&amp;lt;Uri&amp;gt; uris)
{
    ILocal&amp;lt;string&amp;gt; query =
        from uri in uris
        where uri.IsAbsoluteUri // ILocal.Where and anonymous method.
        group uri by uri.Host into hostUris // ILocal.GroupBy and anonymous method.
        orderby hostUris.Key // ILocal.OrderBy and anonymous method.
        select hostUris.ToString(); // ILocal.Select and anonymous method.
}

internal static void RemoteQuery(IRemote&amp;lt;Uri&amp;gt; uris)
{
    IRemote&amp;lt;string&amp;gt; query =
        from uri in uris
        where uri.IsAbsoluteUri // IRemote.Where and expression tree.
        group uri by uri.Host into hostUris // IRemote.GroupBy and expression tree.
        orderby hostUris.Key // IRemote.OrderBy and expression tree.
        select hostUris.ToString(); // IRemote.Select and expression tree.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their syntax looks identical but they are compiled to different query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLocalQuery(ILocal&amp;lt;Uri&amp;gt; uris)
{
    ILocal&amp;lt;string&amp;gt; query = uris
        .Where(uri =&amp;gt; uri.IsAbsoluteUri) // ILocal.Where and anonymous method.
        .GroupBy(uri =&amp;gt; uri.Host) // ILocal.GroupBy and anonymous method.
        .OrderBy(hostUris =&amp;gt; hostUris.Key) // ILocal.OrderBy and anonymous method.
        .Select(hostUris =&amp;gt; hostUris.ToString()); // ILocal.Select and anonymous method.
}

internal static void CompiledRemoteQuery(IRemote&amp;lt;Uri&amp;gt; uris)
{
    IRemote&amp;lt;string&amp;gt; query = uris
        .Where(uri =&amp;gt; uri.IsAbsoluteUri) // IRemote.Where and expression tree.
        .GroupBy(uri =&amp;gt; uri.Host) // IRemote.GroupBy and expression tree.
        .OrderBy(hostUris =&amp;gt; hostUris.Key) // IRemote.OrderBy and expression tree.
        .Select(hostUris =&amp;gt; hostUris.ToString()); // IRemote.Select and expression tree.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides 3 sets of built-in query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt; represents local sequential data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.Enumerable&lt;/li&gt;
&lt;li&gt;ParallelQuery&amp;lt;T&amp;gt; represents local parallel data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.ParallelEnumerable&lt;/li&gt;
&lt;li&gt;IQueryable&amp;lt;T&amp;gt; represents remote data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.Queryable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So query expression works for these 3 kinds of LINQ. The details of query expression usage and compilation is covered by the LINQ to Objects chapter.&lt;/p&gt;
&lt;h2&gt;Query expression vs. query method&lt;/h2&gt;
&lt;p&gt;Query expression is compiled to query method calls, either syntax can be used to build a LINQ query. However, query expression does not cover all query methods and their overloads. For example, Skip and Take query are not supported by query expression syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

        public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following query implement filtering and mapping queries with query expression, but Skip and Take have to be called as query methods, so it is in a hybrid syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void QueryExpressionAndMethod(IEnumerable&amp;lt;Product&amp;gt; products)
{
    IEnumerable&amp;lt;string&amp;gt; query =
        (from product in products
         where product.ListPrice &amp;gt; 0
         select product.Name)
        .Skip(20)
        .Take(10);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is, Where query method for IEnumerable&amp;lt;T&amp;gt; has 2 overloads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first Where overload is supported by query expression where clause, the second overload is not.&lt;/p&gt;
&lt;p&gt;All query expression syntax and all query methods will be discussed in detail in later chapters. Query expression is also a tool to build general functional workflow, which will also be discussed in the Category Theory chapter.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (9) Function Composition and Chaining</title><link>https://dixin.github.io/posts/functional-csharp-function-composition-and-method-chaining/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-composition-and-method-chaining/</guid><description>As demonstrated in the introduction chapter, in object-oriented programming, program is modelled as objects, and object composition is very common, which combines simple objects to more complex object</description><pubDate>Sun, 09 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As demonstrated in the introduction chapter, in object-oriented programming, program is modelled as objects, and object composition is very common, which combines simple objects to more complex objects. In functional programming, program is modelled as functions, function composition is emphasized, which combines simple functions to build more complex functions. LINQ query is composition of quelop.&lt;/p&gt;
&lt;h2&gt;Forward composition and backward composition&lt;/h2&gt;
&lt;p&gt;In mathematics, function composition means to pass a first function f’s output to a second function g as input, which produces a new function h. The result function h is called composite function, it maps its argument x to g(f(x)), and is denoted g ∘ f. This notation can be read g circle f, g composed with f, or more intuitively, g after f. Since C# is strongly typed, if a first function’s output type is the same as the second function’s input type, then the first function’s output can be used to call the second function as input. So, a first function of type T -&amp;gt; TResult1 and a second function of type TResult1 -&amp;gt; TResult2 can be composed to a new function of type T -&amp;gt; TResult2:&lt;/p&gt;
&lt;p&gt;internal static void OutputAsInput&amp;lt;T, TResult1, TResult2&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TResult1, TResult2&amp;gt; second, // TResult1 -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TResult1&amp;gt; first) // T -&amp;gt;TResult1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TResult2&amp;gt; composition = value =&amp;gt; second(first(value)); // T -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example is a sequence of function calls, where a previous function’s output is passed to a next function as input:&lt;/p&gt;
&lt;p&gt;internal static void OutputAsInput()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string @string = &quot;-2&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int int32 = int.Parse(@string); // string -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int absolute = Math.Abs(int32); // int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double @double = Convert.ToDouble(absolute); // int -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double squareRoot = Math.Sqrt(@double); // double -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above int.Parse, Math.Abs Convert.ToDouble, and Math.Sqrt functions can be composed to a new function:&lt;/p&gt;
&lt;p&gt;// string -&amp;gt; double&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static double Composition(string value) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Math.Sqrt(Convert.ToDouble(Math.Abs(int.Parse(value))));&lt;/p&gt;
&lt;p&gt;C# does not have built-in composition operators to combine functions, but the composition operation can be implemented as extension methods for Func generic delegate type:&lt;/p&gt;
&lt;p&gt;// Input: TResult1 -&amp;gt; TResult2, T -&amp;gt; TResult1.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Output: T -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T, TResult2&amp;gt; After&amp;lt;T, TResult1, TResult2&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;TResult1, TResult2&amp;gt; second, Func&amp;lt;T, TResult1&amp;gt; first) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value =&amp;gt; second(first(value));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: T -&amp;gt; TResult1, TResult1 -&amp;gt; TResult2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: T -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T, TResult2&amp;gt; Then&amp;lt;T, TResult1, TResult2&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T, TResult1&amp;gt; first, Func&amp;lt;TResult1, TResult2&amp;gt; second) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;value =&amp;gt; second(first(value));&lt;/p&gt;
&lt;p&gt;And their usage is straightforward:&lt;/p&gt;
&lt;p&gt;internal static void Composition&amp;lt;T, TResult1, TResult2&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TResult1, TResult2&amp;gt; second, // TResult1 -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TResult1&amp;gt; first) // T -&amp;gt; TResult1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TResult2&amp;gt; composition; // T -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;composition = second.After(first);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;composition = first.Then(second);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above 2 extension methods work the same, they just provide different syntaxes. The After extension method implements the above ∘ operator. It composes the first function and the second function as second.After(first), where the right operand is called earlier, and the left operand is called later. Since reading code is from left to right, The Then extension method is implemented for a more readable syntax first.Then(second). Now the above int.Parse, Math.Abs Convert.ToDouble, and Math.Sqrt functions can be composed with After or Then::&lt;/p&gt;
&lt;p&gt;internal static void BackwardCompositionForwardComposition()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, int&amp;gt; parse = int.Parse; // string -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; abs = Math.Abs; // int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, double&amp;gt; convert = Convert.ToDouble; // int -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double&amp;gt; sqrt = Math.Sqrt; // double -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, double&amp;gt; backwardComposition = sqrt.After(convert).After(abs).After(parse);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;backwardComposition(&quot;-2&quot;).WriteLine(); // 1.4142135623731
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, double&amp;gt; forwardComposition = parse.Then(abs).Then(convert).Then(sqrt);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;forwardComposition(&quot;-2&quot;).WriteLine(); // 1.4142135623731
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As demonstrated above, After composes functions from right to end, which is called backward composition. Then composes function from left to right, which is called forward composition. Again, backward composition and forward composition are just different syntaxes, they produce new functions doing the same work.&lt;/p&gt;
&lt;p&gt;If functions’ output type and input type do not match, they cannot be composed directly and their design need to be adjusted. For example, .NET Standard’s list type is designed in object-oriented paradigm. The following are a few examples of its function members:&lt;/p&gt;
&lt;p&gt;namespace System.Collections.Generic&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class List&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IList&amp;lt;T&amp;gt;, IReadOnlyCollection&amp;lt;T&amp;gt;, IReadOnlyList&amp;lt;T&amp;gt;, ICollection, IList
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Add(T item); // (List&amp;lt;T&amp;gt;, T) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Clear(); // List&amp;lt;T&amp;gt; -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public List&amp;lt;T&amp;gt; FindAll(Predicate&amp;lt;T&amp;gt; match); // (List&amp;lt;T&amp;gt;, Predicate&amp;lt;T&amp;gt;) -&amp;gt; List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void ForEach(Action&amp;lt;T&amp;gt; action); // (List&amp;lt;T&amp;gt;, Action&amp;lt;T&amp;gt;) -&amp;gt;void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void RemoveAt(int index); // (List&amp;lt;T&amp;gt;, index) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Reverse(); // List&amp;lt;T&amp;gt; -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Notice FindAll accept a match function of type Predicate&amp;lt;T&amp;gt;, which is T -&amp;gt; bool. When FIndAll is called, it calls match function with each value in the list. If match outputs true, the value is added to the result list. Predicate&amp;lt;T&amp;gt; is equivalent to Func&amp;lt;T, bool&amp;gt;. FindAll does not use Func&amp;lt;T, bool&amp;gt; because List&amp;lt;T&amp;gt; type is released in .NET Framework 2.0, and the unified Func generic delegate types are introduced in .NET Framework 3.5. The above list functions accept different numbers of parameters. Some of them output a list and some output void. The following example operates a list in place. Apparently, these functions cannot be composed directly:&lt;/p&gt;
&lt;p&gt;internal static void ListOperations()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.RemoveAt(0); // -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list = list.FindAll(int32 =&amp;gt; int32 &amp;gt; 0); // -&amp;gt; List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.Reverse(); // -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.ForEach(int32 =&amp;gt; int32.WriteLine()); // -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.Clear(); // -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.Add(1); // -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As discussed in the named function chapter, a type’s instance function member can be viewed as a static method with an additional first parameter of that type, which represents this reference to the current instance. For example, the type of Add looks like T -&amp;gt; void, and the type of Clear looks like () -&amp;gt; void, but since they are instance members, their types are actually (List&amp;lt;T&amp;gt;, T) -&amp;gt; void and List&amp;lt;T&amp;gt; -&amp;gt; void. To make these function composable. One refactor option is: If a function does not output list, have it output the result list; if a function has more parameter besides the list, swap the parameters so that the list parameter becomes the last parameter, and finally curry the function. The following are the transformed functions:&lt;/p&gt;
&lt;p&gt;// // T -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;List&amp;lt;T&amp;gt;, List&amp;lt;T&amp;gt;&amp;gt; Add&amp;lt;T&amp;gt;(T value) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list =&amp;gt; { list.Add(value); return list; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; Clear&amp;lt;T&amp;gt;(List&amp;lt;T&amp;gt; list) { list.Clear(); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Predicate&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt;List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;List&amp;lt;T&amp;gt;, List&amp;lt;T&amp;gt;&amp;gt; FindAll&amp;lt;T&amp;gt;(Predicate&amp;lt;T&amp;gt; match) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list =&amp;gt; list.FindAll(match);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Action&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt;List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;List&amp;lt;T&amp;gt;, List&amp;lt;T&amp;gt;&amp;gt; ForEach&amp;lt;T&amp;gt;(Action&amp;lt;T&amp;gt; action) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list =&amp;gt; { list.ForEach(action); return list; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;List&amp;lt;T&amp;gt;, List&amp;lt;T&amp;gt;&amp;gt; RemoveAt&amp;lt;T&amp;gt;(int index) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list =&amp;gt; { list.RemoveAt(index); return list; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal static List&amp;lt;T&amp;gt; Reverse&amp;lt;T&amp;gt;(List&amp;lt;T&amp;gt; list) { list.Reverse(); return list; }&lt;/p&gt;
&lt;p&gt;For example, Add is originally of type (List&amp;lt;T&amp;gt;, T) -&amp;gt; void. First, have Add output the manipulated list itself, which is super easy, and Add becomes (List&amp;lt;T&amp;gt;, T) -&amp;gt;List&amp;lt;T&amp;gt;; then swap the 2 parameters, Add becomes (T, List&amp;lt;T&amp;gt;) -&amp;gt;List&amp;lt;T&amp;gt;. Finally, curry Add to transformed it to T -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;. Applying the refactor to all functions, their function types become either transformed to List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;, or curried function type SomeType -&amp;gt; List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;. Once a curried function is “partially applied” with a single argument, the result is also a function of type List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;. Since all function types finally become List&amp;lt;T&amp;gt; -&amp;gt; List&amp;lt;T&amp;gt;, they can be composed:&lt;/p&gt;
&lt;p&gt;internal static void TransformationForComposition()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// List&amp;lt;int&amp;gt; -&amp;gt; List&amp;lt;int&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; removeAtWithIndex = RemoveAt&amp;lt;int&amp;gt;(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; findAllWithPredicate = FindAll&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; reverse = Reverse;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; forEachWithAction = ForEach&amp;lt;int&amp;gt;(int32 =&amp;gt; int32.WriteLine());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; clear = Clear;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; addWithValue = Add(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; backwardComposition =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;addWithValue
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.After(clear)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.After(forEachWithAction)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.After(reverse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.After(findAllWithPredicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.After(removeAtWithIndex);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; forwardComposition =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;removeAtWithIndex
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(findAllWithPredicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(reverse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(forEachWithAction)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(clear)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(addWithValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, if these functions have unified list output, and have the input list as the last parameter, then these functions can be composed with the help of partial application. This is the pattern of how to compose list operations in some functional languages:&lt;/p&gt;
&lt;p&gt;internal static void ForwardCompositionWithPartialApplication()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;List&amp;lt;int&amp;gt;, List&amp;lt;int&amp;gt;&amp;gt; forwardComposition =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;RemoveAt&amp;lt;int&amp;gt;(0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(FindAll&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(Reverse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(ForEach&amp;lt;int&amp;gt;(int32 =&amp;gt; int32.WriteLine()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(Clear)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Then(Add(1));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; result = forwardComposition(list);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Forward piping&lt;/h2&gt;
&lt;p&gt;Another option to compose these functions is to use forward pipe operator, which simply forward argument to function call. Again, C# does not have built-in forward pipe operator. It can be implemented as an extension method:&lt;/p&gt;
&lt;p&gt;// Input, T, T -&amp;gt; TResult.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Output TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;public static TResult Forward&amp;lt;T, TResult&amp;gt;(this T value, Func&amp;lt;T, TResult&amp;gt; function) =&amp;gt;&lt;/p&gt;
&lt;p&gt;Its usage is also straightforward:&lt;/p&gt;
&lt;p&gt;internal static void OutputAsInput&amp;lt;T, TResult1, TResult2&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TResult1, TResult2&amp;gt; second, // TResult1 -&amp;gt; TResult2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TResult1&amp;gt; first, // T -&amp;gt; TResult1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TResult2 result = value.Forward(first).Forward(second);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the argument is forwarded to call the first function, then forward first function’s output to call the second function as input. So, the piping can go on with the third function, the fourth function, etc. This is called forward piping. For example:&lt;/p&gt;
&lt;p&gt;internal static void ForwardPiping()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double result = &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(int.Parse) // string -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Math.Abs) // int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Convert.ToDouble) // int -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Math.Sqrt); // double -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To pipe functions with more parameters, just partially applied the function to result a new function with single parameter, then a single argument can be forwarded to the single parameter function. The syntax also looks similar to forward composition:&lt;/p&gt;
&lt;p&gt;internal static void ForwardPipingWithPartialApplication()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; result = new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(RemoveAt&amp;lt;int&amp;gt;(1))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(FindAll&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Reverse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(ForEach&amp;lt;int&amp;gt;(int32 =&amp;gt; int32.WriteLine()))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Clear)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Forward(Add(1));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above syntax looks similar to forward composition. Forward composition and forward piping both compose functions from left to right. Their difference is that forward composition starts from the first function to be composed, it does not call any composed function, and outputs a new composite function; while forward piping starts from the argument, it directly calls the composed functions, and outputs the result.&lt;/p&gt;
&lt;h2&gt;Method chaining and fluent interface&lt;/h2&gt;
&lt;p&gt;In object-oriented programming, if a type has instance methods output that type, then these instance methods can be easily composed by just chaining the calls, for example:&lt;/p&gt;
&lt;p&gt;internal static void InstanceMethodComposition(string @string)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string result = @string.Trim().Substring(1).Remove(10).ToUpperInvariant();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above function members, Trim, Substring, Replace, ToUpperInvariant, are all instance methods of string, and they all output string. so that they can be chained. As fore mentioned, instance function member instance.Method(arg1, arg2, …) can be viewed as static function member Method(instance, arg1, arg2, …) at compile time. At runtime, unlike instance field member is allocated for each instance, instance function member is allocated only once in total just like static function member and static field member. In another word, in C#’s instance method calls syntax instance.Method(arg1, arg2, …), the . operator works like the forward pipe operator. The left side of . is a single argument for Method, the right side is the partial application of Method with other arguments. In instance method call, . just forwards the instance argument to Method function partially applied with other arguments, and finally output the result. So instance method chaining can be virtually viewed a simplified syntax of forward piping.&lt;/p&gt;
&lt;p&gt;To compose the above list operations with method chaining. instance methods are required, and they must output list. Regarding list already have instance methods, but most of them output void, there are some options to implement method chaining. One option is to define a wrapper type to provide these instance methods for chaining:&lt;/p&gt;
&lt;p&gt;internal class FluentList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList(List&amp;lt;T&amp;gt; list) =&amp;gt; this.List = list;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal List&amp;lt;T&amp;gt; List { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; Add(T value) { this.List.Add(value); return this; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; Clear() { this.List.Clear(); return this; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; FindAll(Predicate&amp;lt;T&amp;gt; predicate) =&amp;gt; new FluentList&amp;lt;T&amp;gt;(this.List.FindAll(predicate));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; ForEach(Action&amp;lt;T&amp;gt; action) { this.List.ForEach(action); return this; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; RemoveAt(int index) { this.List.RemoveAt(index); return this; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FluentList&amp;lt;T&amp;gt; Reverse() { this.List.Reverse(); return this; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void InstanceMethodComposition()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FluentList&amp;lt;int&amp;gt; resultWrapper = new FluentList&amp;lt;int&amp;gt;(list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.RemoveAt(0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.FindAll(int32 =&amp;gt; int32 &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Reverse()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ForEach(int32 =&amp;gt; int32.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Clear()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Add(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; result = resultWrapper.List;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since C# supports extension method, which virtually adds instance method to existing type, another option is to provide list extension methods for chaining:&lt;/p&gt;
&lt;p&gt;internal static List&amp;lt;T&amp;gt; ExtensionAdd&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, T item)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ list.Add(item); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; ExtensionClear&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ list.Clear(); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; ExtensionFindAll&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, Predicate&amp;lt;T&amp;gt; predicate) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;list.FindAll(predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; ExtensionForEach&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, Action&amp;lt;T&amp;gt; action)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ list.ForEach(action); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; ExtensionRemoveAt&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, int index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ list.RemoveAt(index); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static List&amp;lt;T&amp;gt; ExtensionReverse&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ list.Reverse(); return list; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExtensionMethodComposition()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; result = new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionRemoveAt(0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionFindAll(int32 =&amp;gt; int32 &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionReverse()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionForEach(int32 =&amp;gt; int32.WriteLine())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionClear()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ExtensionAdd(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As discussed in the named function chapter, extension method is compiled to static method. Similar to instance method call, the extension method calls syntax instance.ExtensionMethod(arg1, arg2, …) can also be viewed as forwarding instance argument to static function member ExtensionMethod partially applied with other arguments. The above extension method chaining is compiled to the following static method composition:&lt;/p&gt;
&lt;p&gt;internal static void CompiledExtensionMethodComposition()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; result =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionAdd(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionClear(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionForEach(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionReverse(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionFindAll(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ExtensionRemoveAt(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new List&amp;lt;int&amp;gt;() { -2, -1, 0, 1, 2 },
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; int32&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; int32.WriteLine()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For example, the previous forward piping of int. Parse, Math.Abs Convert.ToDouble, and Math.Sqrt functions can be simplified with extension methods:&lt;/p&gt;
&lt;p&gt;internal static int ParseInt32(this string @string) =&amp;gt; int.Parse(@string);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int Abs(this int int32) =&amp;gt; Math.Abs(int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static double ToDouble(this int int32) =&amp;gt; Convert.ToDouble(int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static double Sqrt(this double @double) =&amp;gt; Math.Sqrt(@double);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForwardPipingWithExtensionMethod()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double result = &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ParseInt32() // .Forward(int.Parse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Abs() // .Forward(Math.Abs)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ToDouble() // .Forward(Convert.ToDouble)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Sqrt(); // .Forward(Math.Sqrt);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If an interface type supports method chaining, it is called fluent interface. For example, the following IAnimal interface has instance methods and extension method that output the interface type itself:&lt;/p&gt;
&lt;p&gt;internal interface IAnimal&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IAnimal Eat();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IAnimal Move();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static class AnimalExtensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static IAnimal Sleep(this IAnimal animal) =&amp;gt; animal;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;All these methods can be composed by chaining, and IAnimal is a fluent interface:&lt;/p&gt;
&lt;p&gt;internal static void FluentInterface(IAnimal animal)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IAnimal result = animal.Eat().Move().Sleep();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;LINQ query composition&lt;/h2&gt;
&lt;p&gt;As demonstrated in the introduction chapter, LINQ query has 2 syntaxes, query method syntax and query expression syntax. They are both syntactic sugar for function composition.&lt;/p&gt;
&lt;h3&gt;LINQ query method&lt;/h3&gt;
&lt;p&gt;In the query method syntax, the LINQ query APIs are composed with the extension method chaining approach of fluent interface. In LINQ, System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt; interface represents a local data source (a sequence of .NET objects) to be queried, or a local LINQ query that can be executed; System.Linq.IQueryable&amp;lt;T&amp;gt; interface represents a remote data source (e.g. data rows in a database table) to be queried, or a remote LINQ query that can be executed. The IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt; interfaces only have a few members, and the built-in local/remote LINQ query APIs are implemented as static function members of System.Linq.Enumerable/System.Linq.Queryable static classes. Most of these functions are extension methods for IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;, and many of those extension methods output IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;. For example:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This kind of functions can be composed with extension method chaining. And they make IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt; fluent interface.&lt;/p&gt;
&lt;p&gt;The ordering functions are slightly different. OrderBy/OrderByDescending are extension methods of IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;. However, they output IOrderedEnumerable&amp;lt;T&amp;gt;/IOrderedQueryable&amp;lt;T&amp;gt;. which represent ordered data source or ordered query, and these interfaces implement IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;. LINQ also provides ThenBy/ThenByDesending to perform subsequent ordering on an ordered data source or ordered query, so ThenBy/ThenByDesending are extension methods of IOrderedEnumerable&amp;lt;T&amp;gt;/IOrderedQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedEnumerable&amp;lt;out TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IOrderedQueryable, IQueryable, IQueryable&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With this design, OrderBy/OrderByDescending can be chained after other query methods which output IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;, but ThenBy/ThenByDesending can only be chained right after OrderBy/OrderByDescending which output IOrderedEnumerable&amp;lt;T&amp;gt;/IOrderedQueryable&amp;lt;T&amp;gt;. Regarding ThenBy/ThenByDesending perform subsequent ordering, this totally make sense. All the other non-ordering extension methods can be chained after OrderBy/OrderByDescending and ThenBy/ThenByDesending, since the output IOrderedEnumerable&amp;lt;T&amp;gt; is an IEnumerable&amp;lt;T&amp;gt; and IOrderedQueryable&amp;lt;T&amp;gt; is an IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;Some APIs are not extension methods but static methods that output IEnumerable&amp;lt;T&amp;gt;. These static methods can be called to start query composition.&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Empty&amp;lt;TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;There are other query APIs which do not output IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt;. They can be used to end the query composition. For example:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following is an example of query composition:&lt;/p&gt;
&lt;p&gt;internal static void LinqComposition()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int queryResultCount = Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Repeat(0, 10) // -&amp;gt; IEnumerable&amp;lt;int&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; Path.GetRandomFileName()) // -&amp;gt; IEnumerable&amp;lt;string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(@string =&amp;gt; @string.Length) // -&amp;gt; IOrderedEnumerable&amp;lt;string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ThenBy(@string =&amp;gt; @string) // -&amp;gt; IOrderedEnumerable&amp;lt;string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(@string =&amp;gt; $&quot;{@string.Length}: {@string}&quot;) // -&amp;gt; IEnumerable&amp;lt;string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Count(); // -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, the above extension method chaining is compiled to the following function composition:&lt;/p&gt;
&lt;p&gt;internal static void CompiledLinqComposition()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string firstQueryResult =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.First(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Select(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.ThenBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.OrderByDescending(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Select(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Repeat(0, 10),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; Path.GetRandomFileName()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; @string.Length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; @string
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; $&quot;{@string.Length}: {@string}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, in query method syntax, LINQ query is represented by fluent interface and query methods are composed with extension method chaining. This design makes LINQ easy to use, as well as extensible. The above built-in functions provided by Enumerable/Queryable are called LINQ standard query methods or standard query operators. Developers can also implement custom query APIs as extension methods of IEnumerable&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt; and compose built-in query methods and custom query methods by chaining. The details of local and remote LINQ query methods are discussed in the LINQ chapters.&lt;/p&gt;
&lt;h3&gt;LINQ query expression&lt;/h3&gt;
&lt;p&gt;LINQ query expression is a SQL/XQuery-like declarative query syntactic sugar for LINQ query composition. As an expression, it is composed with clauses. The following is the syntax of query expression:&lt;/p&gt;
&lt;p&gt;from [Type] rangeVariable in source&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[from [Type] rangeVariable in source]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[join [Type] rangeVariable in source on outerKey equals innerKey [into rangeVariable]]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[let rangeVariable = expression]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[where predicate]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[orderby orderingKey [ascending | descending][, orderingKey [ascending | descending], …]]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select projection | group projection by groupKey [into rangeVariable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;continuationClauses]&lt;/p&gt;
&lt;p&gt;A query expression must start with a from clause, and end with either a select clause or a group clause. In the middle, it can have from/join/let/where/orderby clauses. These query expression clauses introduce new language keywords to C#, which are called query keywords:&lt;/p&gt;
&lt;p&gt;· from&lt;/p&gt;
&lt;p&gt;· join, on, equals&lt;/p&gt;
&lt;p&gt;· let&lt;/p&gt;
&lt;p&gt;· where&lt;/p&gt;
&lt;p&gt;· orderby, ascending, descending&lt;/p&gt;
&lt;p&gt;· select&lt;/p&gt;
&lt;p&gt;· group, by&lt;/p&gt;
&lt;p&gt;· into&lt;/p&gt;
&lt;p&gt;Query expression is just syntactic sugar, it is compiled to query method calls:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Query expression&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Query method&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Single from clause with select clause&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Select&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;let clause&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Select&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Multiple from clauses with select clause&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;SelectMany&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Type in from/join clauses&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Cast&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;where clauses&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Where&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;orderby clause with or without ascending&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;OrderBy, ThenBy&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;orderby clause with descending&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;OrderByDescending, ThenByDescending&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;group clause with/without into&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;GroupBy&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;join clause without into&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Join&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;join clause with into&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;GroupJoin&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;into with continuation clauses&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Query method chaining&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;The local-variable-like identifiers declared in query expression are called range variables. The scope of range variable ends either at the end of query expression or at the into keyword that begins a continuation clause. For example:&lt;/p&gt;
&lt;p&gt;internal static void RangeVariable(IEnumerable&amp;lt;int&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from variable in source // variable is int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where variable &amp;gt; 0 // variable is int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select variable.ToString() /* variable is int. */ into variable // variable is string.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby variable.Length // variable is string.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select variable.ToUpperInvariant(); // variable is string.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The from clause declares range variable of type int, which represents each value in the int source sequence. The variable can be used in the next clauses until select clause’s into keyword. The into keyword is followed by a different range variable of type string, and can be used until the end of query, since there is no further continuation.&lt;/p&gt;
&lt;p&gt;The following example demonstrate the syntax of each kind of clauses in local query, and the query methods they are compiled to:&lt;/p&gt;
&lt;p&gt;internal static void QueryExpressionClause(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; int32Sequence, IEnumerable&amp;lt;string&amp;gt; stringSequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; singleFromWithSelect;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;singleFromWithSelect = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int32;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;singleFromWithSelect = int32Sequence.Select(int32 =&amp;gt; int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; let;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let variable = int32 + 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select variable.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let = int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; new { int32, variable = int32 + 1 })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(context =&amp;gt; context.variable.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; multipleFromWithSelect;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;multipleFromWithSelect = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from @string in stringSequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int32 + @string.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector, Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;multipleFromWithSelect = int32Sequence.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; stringSequence, (int32, @string) =&amp;gt; int32 + @string.Length);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;DayOfWeek&amp;gt; typeInFrom;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;typeInFrom = from DayOfWeek dayOfWeek in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select dayOfWeek;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;typeInFrom = int32Sequence.Cast&amp;lt;DayOfWeek&amp;gt;().Select(dayOfWeek =&amp;gt; dayOfWeek);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; where;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where int32 &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int32;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where = int32Sequence.Where(int32 =&amp;gt; int32 &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;string&amp;gt; orderByWithSingleKey;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderByWithSingleKey = from @string in stringSequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby @string.Length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select @string;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderByWithSingleKey = stringSequence.OrderBy(@string =&amp;gt; @string.Length);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;string&amp;gt; orderByWithMultipleKeys;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderByWithMultipleKeys = from @string in stringSequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby @string.Length, @string descending
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select @string;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderByWithMultipleKeys = stringSequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(@string =&amp;gt; @string.Length).ThenByDescending(@string =&amp;gt; @string);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;int, int&amp;gt;&amp;gt; group;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group int32 by int32 % 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group = int32Sequence.GroupBy(int32 =&amp;gt; int32 % 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; groupWithElementSelector;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groupWithElementSelector = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group int32.ToString() by int32 % 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, Func&amp;lt;TSource, TElement&amp;gt; elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;groupWithElementSelector = int32Sequence.GroupBy(int32 =&amp;gt; int32 % 10, int32 =&amp;gt; int32.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; join;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join @string in stringSequence on int32 equals @string.Length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{int32} - {@string}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join = int32Sequence.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stringSequence,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; int32,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; @string.Length,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int32, @string) =&amp;gt; $&quot;{int32} - {@string}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; joinWithInto;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;joinWithInto = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join @string in stringSequence on int32 equals @string.Length into stringGroup
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select $&quot;{int32} - {string.Join(&quot;, &quot;, stringGroup)}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;joinWithInto = int32Sequence.GroupJoin(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stringSequence,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 =&amp;gt; int32,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; @string.Length,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int32, stringGroup) =&amp;gt; $&quot;{int32} - {string.Join(&quot;, &quot;, stringGroup)}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;char, string&amp;gt;&amp;gt; intoWithContinuation;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;intoWithContinuation = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Abs(int32) into absolute
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select absolute.ToString() into @string
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group @string by @string[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;intoWithContinuation = int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; Math.Abs(int32))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(absolute =&amp;gt; absolute.ToString())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(@string =&amp;gt; @string[0]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The compilation of remote LINQ querie expressions works in the same way. The details of these query methods are discussed in the LINQ chapters. Query expressions composed with multiple clauses is compiled to query methods composition:&lt;/p&gt;
&lt;p&gt;internal static void QueryExpression(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; int32Sequence, IEnumerable&amp;lt;string&amp;gt; stringSequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;char, ConsoleColor&amp;gt;&amp;gt; query;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query = from int32 in int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from @string in stringSequence // SelectMany.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let length = @string.Length // Select.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where length &amp;gt; 1 // Where.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int32 + length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;into sum // Select.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;join ConsoleColor color in int32Sequence on sum % 15 equals (int)color // Join.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby color // OrderBy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group color by color.ToString()[0]; // GroupBy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query = int32Sequence
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(int32 =&amp;gt; stringSequence, (int32, @string) =&amp;gt; new { int32, @string }) // Multiple from clauses.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(context =&amp;gt; new { context, length = context.@string.Length }) // let clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(context =&amp;gt; context.length &amp;gt; 1) // where clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(context =&amp;gt; context.context.int32 + context.length) // select clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32Sequence.Cast&amp;lt;ConsoleColor&amp;gt;(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sum =&amp;gt; sum % 15,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;color =&amp;gt; (int)color,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(sum, color) =&amp;gt; new { sum, color }) // join clause without into.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(context =&amp;gt; context.color) // orderby clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.color.ToString()[0],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.color); // group by clause without element selector.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The both LINQ syntaxes are compiled to the following function composition, where one query API’s out put is passed to another query API as input:&lt;/p&gt;
&lt;p&gt;internal static void CompiledQueryExpression(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; int32Sequence, IEnumerable&amp;lt;string&amp;gt; stringSequence)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;char, ConsoleColor&amp;gt;&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.GroupBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.OrderBy(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Join(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Select(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Where(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Select(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32Sequence, int32 =&amp;gt; stringSequence,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int32, @string) =&amp;gt; new { int32, @string }),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; new { context, length = context.@string.Length }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.length &amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.context.int32 + context.length
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Cast&amp;lt;ConsoleColor&amp;gt;(int32Sequence),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sum =&amp;gt; sum % 15,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;color =&amp;gt; (int)color,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(sum, color) =&amp;gt; new { sum, color }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.color
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.color.ToString()[0],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; context.color
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This comparison demonstrates that query expression and query method chaining are great syntactic sugar to write declarative and functional code.&lt;/p&gt;
&lt;p&gt;Some tools, like Resharper, an extension for Visual Studio, utilizes C# compiler to convert query expressions to query methods at design time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-C-6-Higher-order-Function-and_9058/clip_image002_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-C-6-Higher-order-Function-and_9058/clip_image002_thumb.jpg&quot; alt=&quot;clip_image002&quot; title=&quot;clip_image002&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Query expression pattern&lt;/h2&gt;
&lt;p&gt;LINQ query expression is also an extensible model. In the above examples, query expression for IEnumerable&amp;lt;T&amp;gt; is compiled to calls of query method for IEnumerable&amp;lt;T&amp;gt;. Just like extension method chaining can be implemented for any type, query expression can be available for any type as well. If the compiler can find a query method exists for a type, the compiler supports the corresponding query expression clause’s syntax for that type. For example, the following example implements Select query method for int and System.Guid types:&lt;/p&gt;
&lt;p&gt;private static TResult Select&amp;lt;TResult&amp;gt;(this int source, Func&amp;lt;int, TResult&amp;gt; selector) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;selector(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static TResult Select&amp;lt;TResult&amp;gt;(this Guid source, Func&amp;lt;Guid, TResult&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;selector(source);&lt;/p&gt;
&lt;p&gt;Similar to Enumerable.Select for IEnumerable&amp;lt;T&amp;gt;, the above Select methods are also extension methods for int/Guid. They accept a function parameter, and output a result. Now C# compiler supports query expression of single from clause with select clause for int/Guid. The following is the query expression syntax and the equivalent query method syntax:&lt;/p&gt;
&lt;p&gt;internal static void Select()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int defaultInt32;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;defaultInt32 = from zero in default(int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select zero;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;defaultInt32 = Select(default(int), zero =&amp;gt; zero);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double squareRoot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;squareRoot = from three in 1 + 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Sqrt(three + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;squareRoot = Select(1 + 2, three =&amp;gt; Math.Sqrt(three + 1));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string guidString;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;guidString = from guid in Guid.NewGuid()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select guid.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;guidString = Select(Guid.NewGuid(), guid =&amp;gt; guid.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If Where is implemented for int, then C# compiler supports where clause for int. If SelectMany is implemented for Guid, then C# compiler supports multiple from clauses for Guid:&lt;/p&gt;
&lt;p&gt;private static int? Where(this int source, Func&amp;lt;int, bool&amp;gt; predicate) =&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;predicate(source) ? (int?)source : null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static TResult SelectMany&amp;lt;TSelector, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Guid source, Func&amp;lt;Guid, TSelector&amp;gt; selector, Func&amp;lt;Guid, TSelector, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSelector selectorResult = selector(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return resultSelector(source, selectorResult);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectMany()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int? positive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;positive = from random in new Random().Next()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where random &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select random;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;positive = new Random().Next().Where(random =&amp;gt; random &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string doubleGuidString;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;doubleGuidString = from guild1 in Guid.NewGuid()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from guid2 in Guid.NewGuid()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select guild1.ToString() + guid2.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;doubleGuidString = Guid.NewGuid().SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;guild1 =&amp;gt; Guid.NewGuid(), (guild1, guid2) =&amp;gt; guild1.ToString() + guid2.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If more query methods are implemented for a type, more query expression clauses are supported for that type. And, to compose the clauses, the query methods must be able to fluently chainable, which means their input type and output type must be matching a pattern. The following are the type designs and query method input/output designs needed to make all local LINQ query expression clauses available and composable. This is called the query expression pattern of C#:&lt;/p&gt;
&lt;p&gt;public interface ILocal&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface ILocal&amp;lt;T&amp;gt; : ILocal
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Func&amp;lt;T, TResult&amp;gt; selector); // select clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, ILocal&amp;lt;TSelector&amp;gt;&amp;gt; selector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TSelector, TResult&amp;gt; resultSelector); // Multiple from clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;T&amp;gt; Where(Func&amp;lt;T, bool&amp;gt; predicate); // where clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedLocal&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector); // orderby clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedLocal&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector); // orderby clause with descending.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;ILocalGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector); // group clause without element selector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;ILocalGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TKey&amp;gt; keySelector, Func&amp;lt;T, TElement&amp;gt; elementSelector); // group clause with element selector.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TInner, TResult&amp;gt; resultSelector); // join clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ILocal&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T, ILocal&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector); // join clause with into.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedLocal&amp;lt;T&amp;gt; : ILocal&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedLocal&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector); // Multiple keys in orderby clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedLocal&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector); // Multiple keys with descending in orderby clause.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface ILocalGroup&amp;lt;TKey, T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey Key { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above query methods are demonstrated as instance methods for convenience. As fore mentioned, extension methods work too. Similarly, the following type design and query method design demonstrate the remote LINQ query expression pattern, where all function parameters are replaced with corresponding expression tree parameters:&lt;/p&gt;
&lt;p&gt;public interface IRemote&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IRemote&amp;lt;T&amp;gt; : IRemote
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TSelector&amp;gt;&amp;gt;&amp;gt; selector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, TSelector, TResult&amp;gt;&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;T&amp;gt; Where(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedRemote&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedRemote&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector, Expression&amp;lt;Func&amp;lt;T, TElement&amp;gt;&amp;gt; elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, TInner, TResult&amp;gt;&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IRemote&amp;lt;TInner&amp;gt; inner,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TInner&amp;gt;, TResult&amp;gt;&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IOrderedRemote&amp;lt;T&amp;gt; : IRemote&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedRemote&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedRemote&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IRemoteGroup&amp;lt;TKey, T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TKey Key { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET Standard provides 3 sets of built-in query APIs, implementing the above query expression pattern:&lt;/p&gt;
&lt;p&gt;· The IEnumerable, IEnumerable&amp;lt;T&amp;gt;, IOrderedEnumerable&amp;lt;T&amp;gt; and IGrouping&amp;lt;TKey, TElement&amp;gt; types follow the above type designs, and Enumerable’s function members follow the above query method designs and implement local sequential queries.&lt;/p&gt;
&lt;p&gt;· The ParallelQuery, ParallelQuery&amp;lt;TSource&amp;gt;, OrderedParallelQuery&amp;lt;TSource&amp;gt; and IGrouping&amp;lt;TKey, TElement&amp;gt; types follow the above type designs, and System.Linq.ParallelEnumerable’s function members follow the above query method designs and implement local parallel queries.&lt;/p&gt;
&lt;p&gt;· The IQueryable, IQueryable&amp;lt;T&amp;gt;, IOrderedQueryable&amp;lt;T&amp;gt; and IGrouping&amp;lt;TKey, TElement&amp;gt; types follow the above type designs, and Queryable’s function members follow the above query method designs and are used for remote queries.&lt;/p&gt;
&lt;p&gt;The details of local sequential queries are discussed in LINQ to Objects chapters, local parallel queries are discussed in the Parallel LINQ chapters, and the remote queries are discussed in the LINQ to Entities chapters.&lt;/p&gt;
&lt;h3&gt;Forward piping with LINQ&lt;/h3&gt;
&lt;p&gt;As fore mentioned, LINQ query method chaining or query expression is essentially function composition through forward piping. General forward piping can be also implemented by LINQ. One option is to use Select. The Select query method for IEnumerable&amp;lt;T&amp;gt; forwards each value in the IEnumerable&amp;lt;T&amp;gt; sequence to the selector function. In the previous examples, The Select query method for int/Guid forwards the int/Guid value to the selector function too. Following this pattern, a generic Select query method can be implemented for all types:&lt;/p&gt;
&lt;p&gt;private static TResult Select&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this TSource source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;selector(source);&lt;/p&gt;
&lt;p&gt;This version of Select becomes the same as the Forward operator, so the previous example’s Forward calls can be replaced by Select calls. For query expression, 1 Select call can be compiled from a select clause. 2 chaining Select calls can be compiled from a select clause with into and continuation of another select clauses. So the equivalent query expression version of forward piping can be by multiple select clauses with into:&lt;/p&gt;
&lt;p&gt;internal private static TResult Select&amp;lt;TSource, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this TSource source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;selector(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForwardPipingWithSelect()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double squareRoot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;squareRoot = from @string in &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int.Parse(@string) into int32
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Abs(int32) into absolute
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Convert.ToDouble(absolute) into @double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Sqrt(@double);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;squareRoot = &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int.Parse)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(Math.Abs)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(Convert.ToDouble)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(Math.Sqrt);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The other option is SelectMany. Instead of multiple select clauses, SelectMany enables multiple from clauses to implement forward piping. The following are the generic SelectMany query method for all types, the forward piping query expression with multiple from clauses, and the equivalent query method call version:&lt;/p&gt;
&lt;p&gt;private static TResult SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this TSource source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSelector&amp;gt; selector,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TSelector selectorResult = selector(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return resultSelector(source, selectorResult);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForwardPipingWithQueryExpression()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double result;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result = from @string in &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from int32 in int.Parse(@string)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from absolute in Math.Abs(int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from @double in Convert.ToDouble(absolute)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from squareRoot in Math.Sqrt(@double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select squareRoot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result = &quot;-2&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@string =&amp;gt; int.Parse(@string),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(@string, int32) =&amp;gt; new { @string, int32 })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; Math.Abs(context.int32),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(context, absolute) =&amp;gt; new { context, absolute })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; Convert.ToDouble(context.absolute),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(context, @double) =&amp;gt; new { context, @double })
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.SelectMany(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;context =&amp;gt; Math.Sqrt(context.@double),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(context, squareRoot) =&amp;gt; squareRoot);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Query expression vs. query method&lt;/h3&gt;
&lt;p&gt;Query expression is compiled to query method calls. Query expression is declarative and intuitive, but it has 2 disadvantages. First, query expression does not cover all the built-in query methods. For example, Skip and Take query are not supported by query expression syntax:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With query expression, to skip a number of values and take a number of values, a hybrid syntax has to be used:&lt;/p&gt;
&lt;p&gt;internal static void QueryExpressionAndQueryMethod(IEnumerable&amp;lt;int&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(from int32 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where int32 &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Skip(20)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Take(10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Second, for the covered query methods, not all query method overloads are supported. For example, Where has 2 overloads:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt;predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The first Where overload is supported by query expression, and can be compiled from where clause. The second overload accepts a predicate function with index input. It is not supported by query expression syntax, and can only used with query method call:&lt;/p&gt;
&lt;p&gt;internal static void WhereWithIndex(IEnumerable&amp;lt;int&amp;gt; source)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; query = source.Where((int32, index) =&amp;gt; int32&amp;gt; 0 &amp;amp;&amp;amp; index % 2 == 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses functional composition. In functional programming, function can be composed with forward composition, backward composition, and forward piping. In C#, LINQ query is a composition of query method, it is a forward piping implemented by extension method chaining. LINQ also supports query expression. Query expression is composed with clauses, and compiled to query methods chaining.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (8) Higher-order Function, Currying and First Class Function</title><link>https://dixin.github.io/posts/functional-csharp-higher-order-function-currying-and-first-class-function/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-higher-order-function-currying-and-first-class-function/</guid><description>The delegate chapter and other previous chapters have demonstrated that in C#, function supports many operations that are available for object. This chapter discusses one more aspect, higher-order fun</description><pubDate>Sat, 08 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The delegate chapter and other previous chapters have demonstrated that in C#, function supports many operations that are available for object. This chapter discusses one more aspect, higher-order function, and how it and other functional features make function the first-class citizen in C# language.&lt;/p&gt;
&lt;h2&gt;First-order function and higher-order function&lt;/h2&gt;
&lt;p&gt;Higher-order function is a function that accept one or more function parameters as input, or output a function. In contrast, function does not input or output any function is called first-order function. C# supports higher-order function from the beginning, because C# function can have almost any data type and function type as its input and output, except:&lt;/p&gt;
&lt;p&gt;· Static classes, like System.Convert, System.Math, etc., because they cannot be instantiated.&lt;/p&gt;
&lt;p&gt;· Special type System.Void.&lt;/p&gt;
&lt;p&gt;This chapter use the following simple data type and simple function type for demonstration:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Data(int value) =&amp;gt; this.Value = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Value { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal delegate void Function();&lt;/p&gt;
&lt;p&gt;A first-order function can have normal data value as input and output:&lt;/p&gt;
&lt;p&gt;internal static void CallFirstOrderFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data FirstOrderFunction(Data value) { return value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data input = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data output = FirstOrderFunction(input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a function has function as input and output, it is a higher-order function:&lt;/p&gt;
&lt;p&gt;internal static void CallNamedHigherOrderFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function NamedHigherOrderFunction(Function value) { return value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function input = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function output = NamedHigherOrderFunction(input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Above example is a named higher-order function. Anonymous higher-order functions can also be easily defined with lambda expression:&lt;/p&gt;
&lt;p&gt;internal static void CallAnonymousHigherOrderFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action firstOrder1 = () =&amp;gt; nameof(firstOrder1).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; firstOrder2 = () =&amp;gt; 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (() -&amp;gt; void) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type () -&amp;gt; void. Output: void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;Action&amp;gt; higherOrder1 = action =&amp;gt; action();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;higherOrder1(firstOrder1); // firstOrder1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;higherOrder1(() =&amp;gt; nameof(higherOrder1).WriteLine()); // higherOrder1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; (() -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: none. Output: function of type () -&amp;gt; int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; higherOrder2 = () =&amp;gt; firstOrder2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; output2 = higherOrder2();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output2().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; (() -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: value of type int. Output: function of type () -&amp;gt; int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt; higherOrder3 = int32 =&amp;gt; new Func&amp;lt;int&amp;gt;(() =&amp;gt; int32 + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; output3 = higherOrder3(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output3().WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (() -&amp;gt; void, () -&amp;gt; int) -&amp;gt; (() -&amp;gt; bool)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type () -&amp;gt; void, function of type () -&amp;gt; int. Output: function of type () -&amp;gt; bool.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Action, Func&amp;lt;int&amp;gt;, Func&amp;lt;bool&amp;gt;&amp;gt; higherOrder4 = (action, int32Factory) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;action();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return () =&amp;gt; int32Factory() &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt; output4 = higherOrder4(firstOrder1, firstOrder2); // firstOrder1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output4().WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt; output5 = higherOrder4(() =&amp;gt; nameof(higherOrder4).WriteLine(), () =&amp;gt; 0); // higherOrder4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output5().WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These higher-order functions can be defined and called with IIFE syntax, without any function name or function variable name involved:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousHigherOrderIife()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (() -&amp;gt; void) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Action&amp;lt;Action&amp;gt;(action =&amp;gt; action())(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;() =&amp;gt; nameof(AnonymousHigherOrderIife).WriteLine()); // AnonymousHigherOrderIife
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; (() -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; output2 = new Func&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;(() =&amp;gt; (() =&amp;gt; 1))();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output2().WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; (() -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; output3 = new Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt;(int32 =&amp;gt; (() =&amp;gt; int32 + 1))(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output3().WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (() -&amp;gt; int, () -&amp;gt; string) -&amp;gt;(() -&amp;gt; bool)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;bool&amp;gt; output4 = new Func&amp;lt;Action, Func&amp;lt;int&amp;gt;, Func&amp;lt;bool&amp;gt;&amp;gt;((action, int32Factory) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;action();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return () =&amp;gt; int32Factory() &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})(arg1: () =&amp;gt; nameof(AnonymousHigherOrderIife).WriteLine(), arg2: () =&amp;gt; 0); // AnonymousHigherOrderIife
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;output4().WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET Standard has many built in higher-order functions, like Array.FindAll:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static T[] FindAll&amp;lt;T&amp;gt;(T[] array, Predicate&amp;lt;T&amp;gt;match);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It iterates all values in the input array, and call the match function for each value. If match function returns true, the value is added to the result array:&lt;/p&gt;
&lt;p&gt;internal static void FilterArray(Data[] array)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data[] filtered = Array.FindAll(array, data =&amp;gt; data != null);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Many LINQ query methods are higher-order functions, take the fore mentioned Where, OrderBy, Select as example:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The Where, OrderBy, Select query methods for local LINQ query are higher-order functions, since they accept an IEnumerable&amp;lt;T&amp;gt; local data source and a function as input. The query methods for remote LINQ query are first-order functions, since they accept an IQueryable&amp;lt;T&amp;gt; remote data source and an expression tree data structure. These LINQ query methods will be discussed in detail in the LINQ to Objects chapters and LINQ to Entities chapters.&lt;/p&gt;
&lt;h3&gt;Convert first-order function to higher-order function&lt;/h3&gt;
&lt;p&gt;It is possible to convert a first-order to higher-order function. In the following example, function add2Args and higherOrderAdd2Args do the same work – add 2 int values and output the sum:&lt;/p&gt;
&lt;p&gt;internal static void Add2ArgsFirstOrderToHigherOrder()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = add2Args(1, 2); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; (int -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: value of type int. output: function of type int -&amp;gt; int.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; higherOrderAdd2Args = a =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, int&amp;gt;(b =&amp;gt; a + b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; add1ArgAnd1Variable = higherOrderAdd2Args(1); // Equivalent to: b =&amp;gt; 1 + b.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int higherOrderResult = add1ArgAnd1Variable(2); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, add2Args is first-order function of type (int, int) –&amp;gt; int. It accepts the first and the second int values as input, and outputs their sum. In contrast, higherOrderAdd2Args is higher-order function of type int –&amp;gt; (int –&amp;gt; int). It accepts only the first int value as input, and outputs a function of type int –&amp;gt; int. This new function accepts the second int value as input, adds with the first int value as free variable captured by closure: b =&amp;gt; 1 + b, and outputs their sum. When using add2Args, there is 1 call, where both the first and second int values must be provided, and the result is directly returned. When using higherOrderAdd2Args, there are 2 calls and an intermediate function involved, where only 1 int value is required for each call.&lt;/p&gt;
&lt;p&gt;Similarly, a first-order function with 3 parameters can be converted to higher-order function with the same pattern:&lt;/p&gt;
&lt;p&gt;internal static void Add3ArgsFirstOrderToHigherOrder()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; a + b + c;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = add3Args(1, 2, 3); // 6
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt;(int -&amp;gt; (int -&amp;gt; int))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: value of type int. output: function of type int -&amp;gt; (int -&amp;gt; int), the same as above higherOrderSumOfTwoIntegers.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; higherOrderAdd3Args = a =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;(b =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, int&amp;gt;(c =&amp;gt; a + b + c));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; higherOrderAdd2ArgsAnd1Variable = higherOrderAdd3Args(1); // Equivalent to: b =&amp;gt; (c =&amp;gt; 1 + b + c).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; add1ArgAnd2Variables = higherOrderAdd2ArgsAnd1Variable(2); // Equivalent to: c =&amp;gt; 1 + 2 + c.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int higherOrderResult = add1ArgAnd2Variables(3); // 6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Again, when using first-order function, there is only 1 call, where all 3 arguments must be provided. This time, when using the higher-order function, there are 3 calls, and 2 intermediate functions, where only 1 argument is required for each call.&lt;/p&gt;
&lt;p&gt;In the above examples, since the higher-order functions’ type is provided, C# can infer the returned intermediate functions’ type information. So, the lambda expressions can be simplified:&lt;/p&gt;
&lt;p&gt;internal static void TypeInference()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; (int -&amp;gt; int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; higherOrderAdd2Args = a =&amp;gt; (b =&amp;gt; a + b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; (int -&amp;gt; (int -&amp;gt; int))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; higherOrderAdd3Args = a =&amp;gt; (b =&amp;gt; (c =&amp;gt; a + b + c));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Lambda operator associativity&lt;/h3&gt;
&lt;p&gt;In C#, the lambda operator can be viewed as right associative. For the above higher-order functions, the above parenthesis on the right side of lambda operator can be omitted. Now compare the first-order functions and the converted higher-order functions:&lt;/p&gt;
&lt;p&gt;internal static void LambdaOperatorAssociativity()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt;int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; higherOrderAdd2Args = a =&amp;gt; b =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; a + b + c;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt;int -&amp;gt; int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; higherOrderAdd3Args = a =&amp;gt; b =&amp;gt; c =&amp;gt; a + b + c;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In C#, for a function with 2 or more arguments, it is really easy to convert to equivalent higher-order function. Following this syntax, in this book, the function type notation’s -&amp;gt; operator is also right associative, parenthesis on the right side of -&amp;gt; can also be omitted. So int -&amp;gt; (int -&amp;gt; int) is identical to int -&amp;gt; int -&amp;gt; int. Since -&amp;gt;is not left associative, they are different from (int -&amp;gt; int) -&amp;gt; int, which accepts a function of int -&amp;gt; int as input, and outputs int. Similarly, int -&amp;gt; (int -&amp;gt; (int -&amp;gt; int)) is identical to int -&amp;gt; int -&amp;gt; int -&amp;gt; int.&lt;/p&gt;
&lt;h2&gt;Curry function&lt;/h2&gt;
&lt;p&gt;As demonstrated above, with higher-order function and closure, a function with 2 or more parameters can be easily converted to a sequence of nested single parameter functions, and single function call is also converted to a chain of function calls. This transformation is called currying. The term &quot;currying&quot; is introduced by Christopher Strachey in 1967, which is the last name of mathematician and logician Haskell Curry.&lt;/p&gt;
&lt;p&gt;Generally, a function with N parameters can be curried to a sequence of N nested functions with single parameter:&lt;/p&gt;
&lt;p&gt;internal static void CurryFunc&amp;lt;T1, T2, T3, TN, TResult&amp;gt;()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, T4, ... TN) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, T2, T3, /* T4, ... */ TN, TResult&amp;gt; function =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3, /* value4, ... */ valueN) =&amp;gt; default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; ... TN -&amp;gt;TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, /* Func&amp;lt;T4, ... */ Func&amp;lt;TN, TResult&amp;gt; /* ...&amp;gt; */&amp;gt;&amp;gt;&amp;gt; curriedFunction =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; /* value4 =&amp;gt; ... */ valueN =&amp;gt; default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above transformation can be implemented as the following Curry extension methods for Func generic delegate types:&lt;/p&gt;
&lt;p&gt;// Transform (T1, T2) -&amp;gt;TResult&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// to T1 -&amp;gt; T2 -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, TResult&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; function(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform (T1, T2, T3) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform (T1, T2, T3, T4) =&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;p&gt;Now function can be curried by just calling its Curry extension method:&lt;/p&gt;
&lt;p&gt;internal static void CurryFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int add2ArgsResult = add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2Args = add2Args.Curry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int curriedAdd2ArgsResult = curriedAdd2Args(1)(2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; a + b + c;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int add3ArgsResult = add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3Args = add3Args.Curry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int curriedAdd3ArgsResult = curriedAdd3Args(1)(2)(3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Function without output can be curried in the same way:&lt;/p&gt;
&lt;p&gt;internal static void CurryAction&amp;lt;T1, T2, T3, TN&amp;gt;()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, ... TN) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;T1, T2, T3, /* T4, ... */ TN&amp;gt; function =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3, /* value4, ... */ valueN) =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; ... TN -&amp;gt;void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, /* Func&amp;lt;T4, ... */ Action&amp;lt;TN&amp;gt;/* ...&amp;gt; */&amp;gt;&amp;gt;&amp;gt; curriedFunction =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; /* value4 =&amp;gt; ... */ valueN =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, the above transformation can be implemented as the following Curry extension methods for Action generic delegate types:&lt;/p&gt;
&lt;p&gt;// Transform (T1, T2) -&amp;gt;void&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// to T1 =&amp;gt; T2 -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Action&amp;lt;T2&amp;gt;&amp;gt; Curry&amp;lt;T1, T2&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; function(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform (T1, T2, T3) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Func&amp;lt;T2, Action&amp;lt;T3&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2, T3&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform (T1, T2, T3, T4) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Action&amp;lt;T4&amp;gt;&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, T4&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2, T3, T4&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;p&gt;Now function without output can also be curried by just calling its Curry extension method:&lt;/p&gt;
&lt;p&gt;Internal static void CurryAction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int&amp;gt; add2Args = (a, b) =&amp;gt; (a + b).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt; curriedAdd2Args = add2Args.Curry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;curriedAdd2Args(1)(2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; (a + b + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt;&amp;gt; curriedAdd3Args = add3Args.Curry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;curriedAdd3Args(1)(2)(3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Uncurry function&lt;/h3&gt;
&lt;p&gt;The opposite transformation from a sequence of nested single parameter functions to a function with multiple parameters is called uncurrying. Uncurry extension methods implemented for higher-order functions with a chain of calls:&lt;/p&gt;
&lt;p&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;TResult&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2) -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, T2, TResult&amp;gt; Uncurry&amp;lt;T1, T2, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2) =&amp;gt; function(value1)(value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;T3 -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2, T3) -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, T2, T3, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3) =&amp;gt; function(value1)(value2)(value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;T3 -&amp;gt; T4 -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2, T3, T4) -&amp;gt;TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3, value4) =&amp;gt; function(value1)(value2)(value3)(value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2) -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T1, T2&amp;gt; Uncurry&amp;lt;T1, T2&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Action&amp;lt;T2&amp;gt;&amp;gt; function) =&amp;gt; (value1, value2) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function(value1)(value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;T3 -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2, T3) -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T1, T2, T3&amp;gt; Uncurry&amp;lt;T1, T2, T3&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Func&amp;lt;T2, Action&amp;lt;T3&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3) =&amp;gt; function(value1)(value2)(value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Transform T1 -&amp;gt; T2 -&amp;gt;T3 -&amp;gt; T4 -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// to (T1, T2, T3, T4) -&amp;gt;void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T1, T2, T3, T4&amp;gt; Uncurry&amp;lt;T1, T2, T3, T4&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Action&amp;lt;T4&amp;gt;&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2, value3, value4) =&amp;gt; function(value1)(value2)(value3)(value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;p&gt;The usage of Uncurry is also straightforward:&lt;/p&gt;
&lt;p&gt;internal static void Uncurry()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt;int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2Args = a =&amp;gt; b =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int -&amp;gt;int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = curriedAdd2Args.Uncurry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int add2ArgsResult = add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt;int -&amp;gt; int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt;&amp;gt; curriedAdd3Args = a =&amp;gt; b =&amp;gt; c =&amp;gt; (a + b + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int -&amp;gt;int -&amp;gt; int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int, int&amp;gt; add3Args = curriedAdd3Args.Uncurry();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add3Args(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Partially apply function&lt;/h3&gt;
&lt;p&gt;Another function transformation similar to function currying is function partial application. Function application is just another word for function call. For function with multiple parameters, function partial application means to call that function with partial arguments (typically, a single argument) instead of all arguments. Similar to currying, the implementation of function partial application also involves higher-order function and closure. The difference is, partial application does not result a single function with fewer parameters, not a sequence of nested single parameter functions. For example, a first-order function of type (int, int) -&amp;gt; int can be partially applied with 1 argument and transformed to another first-order function of type int -&amp;gt;int, a first-order function of type (int, int, int) -&amp;gt; void can be partially applied with 1 argument and transformed to another first-order function of type (int, int) -&amp;gt; void:&lt;/p&gt;
&lt;p&gt;internal static void FirstOrderToFirstOrder()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; add1ArgAnd1Variable = b =&amp;gt; 1 + b; // Partially apply add2Args with a = 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; (a + b + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add2Args(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int&amp;gt; add2ArgsAnd1Variable = (b, c) =&amp;gt; (1 + b + c).WriteLine(); // Partially apply add2Args with a = 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// add2ArgsAnd1Variable can be called with 2 arguments, or be partially applied again with b = 2:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int&amp;gt; add1ArgsAnd2Variable = c =&amp;gt; (1 + 2 + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Generally, following Partial extension methods for Func and Action generic delegate types are higher-order functions. When Partial is used for a function with 2 or more parameters, it accepts the first parameter of that function, and outputs another function that accepts the rest of parameters of the original function:&lt;/p&gt;
&lt;p&gt;// Input: function of type (T1, T2) -&amp;gt; TResult, first parameter of type T1.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type T2 -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T2, TResult&amp;gt; Partial&amp;lt;T1, T2, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, TResult&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 =&amp;gt; function(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type (T1, T2, T3) -&amp;gt; TResult, first parameter of type T1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type (T2, T3) -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T2, T3, TResult&amp;gt; Partial&amp;lt;T1, T2, T3, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value2, value3) =&amp;gt; function(value1, value2, value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type (T1, T2, T3, T4) -&amp;gt; TResult, first parameter of type T1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type (T2, T3, T4) -&amp;gt; TResult.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;T2, T3, T4, TResult&amp;gt; Partial&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value2, value3, value4) =&amp;gt; function(value1, value2, value3, value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type (T1, T2) -&amp;gt; void, first parameter of type T1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type T2 -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T2&amp;gt; Partial&amp;lt;T1, T2&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 =&amp;gt; function(value1, value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type (T1, T2, T3) -&amp;gt; void, first parameter of type T1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type (T2, T3) -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T2, T3&amp;gt; Partial&amp;lt;T1, T2, T3&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2, T3&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value2, value3) =&amp;gt; function(value1, value2, value3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Input: function of type (T1, T2, T3, T4) -&amp;gt; void, first parameter of type T1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output: function of type (T2, T3, T4) -&amp;gt; void.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Action&amp;lt;T2, T3, T4&amp;gt; Partial&amp;lt;T1, T2, T3, T4&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this Action&amp;lt;T1, T2, T3, T4&amp;gt; function, T1 value1) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value2, value3, value4) =&amp;gt; function(value1, value2, value3, value4);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// ...&lt;/p&gt;
&lt;p&gt;The following example demonstrates how to call Partial for partial application of functions with multiple parameters:&lt;/p&gt;
&lt;p&gt;internal static void PartiallyApply()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add2Args = (a, b) =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; add1ArgAnd1Variable = add2Args.Partial(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int add1ArgAnd1VariableResult = add1ArgAnd1Variable(2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int, int&amp;gt; add3Args = (a, b, c) =&amp;gt; (a + b + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, int&amp;gt; add2ArgsAnd1Variable = add3Args.Partial(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add2ArgsAnd1Variable(2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For curried function, partial application means a chain of calls with fewer arguments than total:&lt;/p&gt;
&lt;p&gt;internal static void PartiallyApplyCurriedFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2Args = a =&amp;gt; b =&amp;gt; a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; partiallyAppliedCurriedAdd2Args = curriedAdd2Args(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; int -&amp;gt; int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt;&amp;gt; curriedAdd3Args = a =&amp;gt; b =&amp;gt; c =&amp;gt; (a + b + c).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// int -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int&amp;gt; partiallyAppliedCurriedAdd3Args = curriedAdd3Args(1)(2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;First-class function&lt;/h2&gt;
&lt;p&gt;Higher-order function enables function to be function’s input and output, which is an important aspect of be first-class citizenship in language. First-class function means in C# function supports all the generally available operations for other entities like object. These operations include being a variable, being a type’s field, being a function’s input, being a function’s output, being equality testable, etc. This can be demonstrated by comparing C# function with C# object side by side. First of all, with delegate type and delegate instance, function and object both have type and instance, and an instance can be variable, can have alias and immutable alias:&lt;/p&gt;
&lt;p&gt;internal static void Object()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data value = new Data(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref Data alias = ref value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly Data immutableAlias = ref value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Function()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function value1 = Function; // Named function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function value2 = () =&amp;gt; { }; // Anonymous function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref Function alias = ref value1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly Function immutableAlias = ref value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With delegate type and delegate instance, function and object can both be stored with static and instance field of type:&lt;/p&gt;
&lt;p&gt;internal class Fields&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static Data staticDataField = new Data(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static Function staticNamedFunctionField = Function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static Function staticAnonymousFunctionField = () =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Data instanceDataField = new Data(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Function instanceNamedFunctionField = Function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Function instanceAnonymousFunctionField = () =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With local function and lambda expression, function and object can both be nested:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Data Inner { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void NestedObject()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data outer = new Data(1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Inner = new Data(2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void NestedFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Outer()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Inner() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function outer = () =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function inner = () =&amp;gt; { };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With closure to capture free variable, function and object can both access data out of the scope:&lt;/p&gt;
&lt;p&gt;internal class OuterClass&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int Outer = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;class InnerClass
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int Inner = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = Inner + Outer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void OuterFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int Outer = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void InnerFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int Inner = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = Inner + Outer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Function(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const int Inner = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = Inner + Outer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With higher-order function, function and object can both be input and output of function:&lt;/p&gt;
&lt;p&gt;internal static Data Function(Data value) =&amp;gt; value;&lt;/p&gt;
&lt;p&gt;internal static Function Function(Function value) =&amp;gt; value;&lt;/p&gt;
&lt;p&gt;With delegate type and delegate instance, function and object can both be equality testable:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object obj) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(this, obj) || this.Value == (obj as Data)?.Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override int GetHashCode() =&amp;gt; this.Value.GetHashCode();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator ==(Data data1, Data data2) =&amp;gt; data1?.Value == data2?.Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator !=(Data data1, Data data2) =&amp;gt; !(data1 == data2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void ObjectEquality()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data value1 = new Data(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data value2 = new Data(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(value1, value2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.Equals(value1, value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1.Equals(value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1 == value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1.GetHashCode() == value2.GetHashCode()).WriteLine(); // True.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EqualityComparer&amp;lt;Data&amp;gt;.Default.Equals(value1, value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctionEquality()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function value1 = Function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Function value2 = Function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(value1, value2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.Equals(value1, value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value1.Equals(value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1 == value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1.GetHashCode() == value2.GetHashCode()).WriteLine(); // True.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EqualityComparer&amp;lt;Function&amp;gt;.Default.Equals(value1, value2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here Data type overrides object type’s Equals method as well as the == and != operators, so that, 2 Data instances considered logically equal if they encapsulate the same int value. It also overrides object type’s GetHashCode, so that 2 equal Data instances have the same hash code. If 2 variables are 2 Data instances encapsulating the same int value, apparently these 2 variables are not reference equal, but logically equal with the same hash code. C# provides these equality APIs through System.Delegate and System.MulticastDelegate. So similarly, if 2 variables are 2 delegate instances representing the same function, they are not reference equal, but logically equal with the same hash code as well.&lt;/p&gt;
&lt;p&gt;So, with rich functional features including delegate, local function, lambda expression, closure and higher-order function, C#’s named function and anonymous function are first-class citizens, and C# is a functional language. Besides these aspects, C# functions can be composed just like object composition. Function composition is discussed in the next chapter.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discussed higher-order function, and its related concepts, including first-order function, currying function, uncurrying function, partially applying function, and lambda operator’s associativity. Higher-order function works with other C# features, and enables first-class functions in C#.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (7) Expression Tree: Function as Data</title><link>https://dixin.github.io/posts/functional-csharp-function-as-data-and-expression-tree/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-as-data-and-expression-tree/</guid><description>C# lambda expression is a powerful syntactic sugar. Besides representing anonymous function, the same syntax can also represent expression tree. An expression tree is an immutable tree data structure</description><pubDate>Fri, 07 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Lambda expression as expression tree&lt;/h2&gt;
&lt;p&gt;C# lambda expression is a powerful syntactic sugar. Besides representing anonymous function, the same syntax can also represent expression tree. An expression tree is an immutable tree data structure that represents structure of code. For example:&lt;/p&gt;
&lt;p&gt;internal static void ExpressionLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compare to: Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This time, the expected type for the lambda expression is no longer a Func&amp;lt;int, bool&amp;gt; function type, but Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; data type. The lambda expression here is no longer compiled to executable anonymous function code, but an expression tree data structure representing that function’s code logic.&lt;/p&gt;
&lt;h3&gt;Metaprogramming: function as abstract syntax tree&lt;/h3&gt;
&lt;p&gt;The above lambda expression has exactly the same syntax as anonymous function, but it is compiled to code that builds expression tree:&lt;/p&gt;
&lt;p&gt;internal static void CompiledExpressionLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParameterExpression parameterExpression = Expression.Parameter(type: typeof(int), name: &quot;int32&quot;); // int32 parameter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConstantExpression constantExpression = Expression.Constant(value: 0, type: typeof(int)); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;BinaryExpression greaterThanExpression = Expression.GreaterThan(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;left: parameterExpression, right: constantExpression); // int32 &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;body: greaterThanExpression, // ... =&amp;gt; int32 &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters: parameterExpression); // int32 =&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the Expression&amp;lt;Func&amp;lt;int bool&amp;gt;&amp;gt; instance represents the entire tree, the ParameterExpression, ConstantExpression, BinaryExpression instances are nodes in that tree. And they are all derived from System.Linq.Expressions.Expression type:&lt;/p&gt;
&lt;p&gt;namespace System.Linq.Expressions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual ExpressionType NodeType { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Type Type { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class ParameterExpression : Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class ConstantExpression : Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public object Value { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class BinaryExpression : Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Expression Left { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Expression Right { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class LambdaExpression : Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Expression Body { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public ReadOnlyCollection&amp;lt;ParameterExpression&amp;gt; Parameters { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public sealed class Expression&amp;lt;TDelegate&amp;gt; : LambdaExpression
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TDelegate Compile();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above expression tree data structure can be visualized as:&lt;/p&gt;
&lt;p&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;int, bool&amp;gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;int32&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Body
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_BinaryExpression (NodeType = GreaterThan, Type = bool)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;int32&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ConstantExpression (NodeType = Constant, Type = int)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Value = 0&lt;/p&gt;
&lt;p&gt;So, this expression tree is an abstract syntax tree (AST), representing the abstract syntactic structure of C# function (int32 =&amp;gt; int32 &amp;gt; 0)’s source code. Notice each node has NodeType property and Type property. NodeType returns the syntax type in the tree, and Type returns the represented .NET type. For example, above ParameterExpression represents parameter node of int type in the source code, so its NodeType is Parameter and its Type is int.&lt;/p&gt;
&lt;p&gt;To summarize, the differences between&lt;/p&gt;
&lt;p&gt;Func&amp;lt;int, bool&amp;gt;isPositive = int32 =&amp;gt; int32 &amp;gt; 0;// Code.&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32&amp;gt; 0;// Data.&lt;/p&gt;
&lt;p&gt;are:&lt;/p&gt;
&lt;p&gt;· isPositive variable is a function represented by delegate instance, and can be called. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled to executable code. When isPositive is called, this code is executed.&lt;/p&gt;
&lt;p&gt;· isPositiveExpression variable is an abstract syntax tree data structure. So apparently it cannot be called like an executable function. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled to the building of an expression tree, where each node is an Expression instance. This entire tree represents the syntactic structure and logic of function int32 =&amp;gt; int32 &amp;gt; 0. This tree’s top node is an Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; instance, since this is a lambda expression. It has 2 child nodes:&lt;/p&gt;
&lt;p&gt;o A Parameters node which is a ParameterExpression collection, representing all the parameters of the lambda expression. The above lambda expression has 1 parameter, so this collection contains one node:&lt;/p&gt;
&lt;p&gt;§ A ParameterExpression instance, representing the int parameter named “int32”.&lt;/p&gt;
&lt;p&gt;o A Body node representing the lambda expression’s body, which is a BinaryExpression instance, representing the body is a “&amp;gt;” (greater than) comparison operation of 2 operands. So it has 2 child nodes:&lt;/p&gt;
&lt;p&gt;§ Its Left child node is a reference of above ParameterExpression instance, representing the left operand of &amp;gt; operator.&lt;/p&gt;
&lt;p&gt;§ Its Right child node is a ConstantExpression instance with value 0, representing the right operand of &amp;gt; operator.&lt;/p&gt;
&lt;p&gt;Automatically generating expression tree from function-like code provides great convenience for metaprogramming in C#. As mentioned in the introduction chapter, metaprogramming is to generate or manipulate program code as data. With the generated expression tree, since each node is strong typed with rich information, the nodes can be traversed to obtain the information of the represented function’s C# source code, and process the information, like generating code of the same logic in another language. Here isPositiveExpression represents the function logic to predicate whether an int value is greater than a constant 0, and it can be used to generate equivalent CIL code, or a WHERE clause with greater-than-0 predicate in SQL code, etc.&lt;/p&gt;
&lt;h3&gt;.NET expressions&lt;/h3&gt;
&lt;p&gt;Besides above ParameterExpression, ConstantExpression, BinaryExpression, LambdaExpression, .NET Standard provides a rich collection of expressions nodes. The following is their inheritance hierarchy:&lt;/p&gt;
&lt;p&gt;· Expression&lt;/p&gt;
&lt;p&gt;o BinaryExpression&lt;/p&gt;
&lt;p&gt;o BlockExpression&lt;/p&gt;
&lt;p&gt;o ConditionalExpression&lt;/p&gt;
&lt;p&gt;o ConstantExpression&lt;/p&gt;
&lt;p&gt;o DebugInfoExpression&lt;/p&gt;
&lt;p&gt;o DefaultExpression&lt;/p&gt;
&lt;p&gt;o DynamicExpression&lt;/p&gt;
&lt;p&gt;o GotoExpression&lt;/p&gt;
&lt;p&gt;o IndexExpression&lt;/p&gt;
&lt;p&gt;o InvocationExpression&lt;/p&gt;
&lt;p&gt;o LabelExpression&lt;/p&gt;
&lt;p&gt;o LambdaExpression&lt;/p&gt;
&lt;p&gt;§ Expression&amp;lt;TDelegate&amp;gt;&lt;/p&gt;
&lt;p&gt;o ListInitExpression&lt;/p&gt;
&lt;p&gt;o LoopExpression&lt;/p&gt;
&lt;p&gt;o MemberExpression&lt;/p&gt;
&lt;p&gt;o MemberInitExpression&lt;/p&gt;
&lt;p&gt;o MethodCallExpression&lt;/p&gt;
&lt;p&gt;o NewArrayExpression&lt;/p&gt;
&lt;p&gt;o NewExpression&lt;/p&gt;
&lt;p&gt;o ParameterExpression&lt;/p&gt;
&lt;p&gt;o RuntimeVariablesExpression&lt;/p&gt;
&lt;p&gt;o SwitchExpression&lt;/p&gt;
&lt;p&gt;o TryExpression&lt;/p&gt;
&lt;p&gt;o TypeBinaryExpression&lt;/p&gt;
&lt;p&gt;o UnaryExpression&lt;/p&gt;
&lt;p&gt;And, as demonstrated above, expression can be instantiated by calling the factory methods of Expression type:&lt;/p&gt;
&lt;p&gt;public abstract partial class Expression&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ParameterExpression Parameter(Type type, string name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ConstantExpression Constant(object value, Type type);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression GreaterThan(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Expression&amp;lt;TDelegate&amp;gt; Lambda&amp;lt;TDelegate&amp;gt;(Expression body, params ParameterExpression[] parameters);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Expression has many other factory methods to cover all the expression instantiation cases:&lt;/p&gt;
&lt;p&gt;public abstract partial class Expression&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression Add(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression Subtract(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression Multiply(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression Divide(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BinaryExpression Equal(Expression left, Expression right);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static UnaryExpression ArrayLength(Expression array);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static UnaryExpression Not(Expression expression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static NewExpression New(ConstructorInfo constructor, params Expression[] arguments);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static BlockExpression Block(params Expression[] expressions);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;One expression node type can have different possible NodeType values. For example:&lt;/p&gt;
&lt;p&gt;· UnaryExpression represents any unary operation with an operator and an operand. Its NodeType can be ArrayLength, Negate, Not, Convert, Decrement, Increment, Throw, UnaryPlus, etc.&lt;/p&gt;
&lt;p&gt;· BinaryExpression represents any binary operation with an operator, a left operand, and a right operand, its NodeType can be Add, And, Assign, Divide, Equal, .GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, Modulo, Multiply, NotEqual, Or, Power, Subtract, etc.&lt;/p&gt;
&lt;p&gt;So far C# compiler only implements this “function as data” syntactic sugar for expression lambda, and it is not available to statement lambda yet. The following code cannot be compiled:&lt;/p&gt;
&lt;p&gt;internal static void StatementLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;isPositiveExpression = int32 =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above expression tree has to be built manually:&lt;/p&gt;
&lt;p&gt;internal static void StatementLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParameterExpression parameterExpression = Expression.Parameter(type: typeof(int), name: &quot;int32&quot;); // int32 parameter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;body: Expression.Block( // ... =&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Console.WriteLine(int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg0: Expression.Call(method: new Action&amp;lt;int&amp;gt;(Console.WriteLine).Method, arg0: parameterExpression),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;arg1: Expression.GreaterThan(left: parameterExpression, right: Expression.Constant(value: 0, type: typeof(int)))), // }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameters: parameterExpression); // int32 =&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Compile expression tree to CIL&lt;/h2&gt;
&lt;p&gt;Expression tree is not executable code but data - abstract syntax tree. In C# and LINQ, expression tree is usually used to represent the abstract syntactic structure of function’s source code, so that it can be compiled or translated to other domain-specific languages, like SQL query, HTTP request, etc. To demonstrate this, take the following simple mathematics function as example, which accepts double parameters, then executes the 4 basic binary arithmetical calculation: add, subtract, multiply, divide, and returns double return:&lt;/p&gt;
&lt;p&gt;internal static void Infix()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt;expression =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The entire tree can be visualized as:&lt;/p&gt;
&lt;p&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;double, double, double, double, double, double&amp;gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;|_Parameters
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;a&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;b&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;c&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;d&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;e&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Body
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_BinaryExpression (NodeType = Add, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_BinaryExpression (NodeType = Subtract, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_BinaryExpression (NodeType = Add, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | | |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | | |_Name = &quot;a&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;b&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_BinaryExpression (NodeType = Divide, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_BinaryExpression (NodeType = Multiply, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | | |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | | |_Name = &quot;c&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| | |_Name = &quot;d&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ConstantExpression (NodeType = Constant, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Value = 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_BinaryExpression (NodeType = Multiply, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Left
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_ParameterExpression (NodeType = Parameter, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;| |_Name = &quot;e&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_Right
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;|_ConstantExpression (NodeType = Constant, Type = double)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;|_Value = 3&lt;/p&gt;
&lt;p&gt;This is a very simple syntax tree, where:&lt;/p&gt;
&lt;p&gt;· each internal node is a binary node (BinaryExpression instance) representing add, subtract, multiply, or divide binary operations;&lt;/p&gt;
&lt;p&gt;· each leaf node is either a parameter (ParameterExpression instance), or a constant (ConstantExpression instance).&lt;/p&gt;
&lt;p&gt;In total there are 6 kinds of nodes in this tree:&lt;/p&gt;
&lt;p&gt;· add: BinaryExpression { NodeType = ExpressionType.Add }&lt;/p&gt;
&lt;p&gt;· subtract: BinaryExpression { NodeType = ExpressionType.Subtract }&lt;/p&gt;
&lt;p&gt;· multiply: BinaryExpression { NodeType = ExpressionType.Multiply }&lt;/p&gt;
&lt;p&gt;· divide: BinaryExpression { NodeType = ExpressionType.Divide}&lt;/p&gt;
&lt;p&gt;· constant: ParameterExpression { NodeType = ExpressionType.Constant }&lt;/p&gt;
&lt;p&gt;· parameter: ConstantExpression { NodeType = ExpressionType.Parameter }&lt;/p&gt;
&lt;h3&gt;Traverse expression tree&lt;/h3&gt;
&lt;p&gt;The above expression is an infix expression, where each operator is in the middle of its 2 operands. It is very easy to traverse the expression tree and convert it to a prefix form (also called Polish notation), where each operator precedes its operands, just like a function to be called:&lt;/p&gt;
&lt;p&gt;internal static string PreOrderOutput(this LambdaExpression expression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string VisitNode(Expression node)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (node.NodeType)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Add:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Subtract:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Multiply:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Divide:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;BinaryExpression binary = (BinaryExpression)node;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Pre-order output: current node, left child, right child.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return $&quot;{binary.NodeType}({VisitNode(binary.Left)}, {VisitNode(binary.Right)})&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Constant:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ((ConstantExpression)node).Value.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Parameter:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ((ParameterExpression)node).Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;default:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(expression));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitNode(expression.Body);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It calls a local function to recursively visit each node in lambda expression’s body. If the current node is a BinaryExpression, it recursively visits the Left and Right child nodes, and outputs string representation in pre-order: Operator(Left, Right). If the current node is a ConstantExpression or ParameterExpression, it output the string representation of current node, and terminates the recursion. The above function can convert the infix expression to a prefix expression in function call style:&lt;/p&gt;
&lt;p&gt;internal static void Prefix()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string prefix = infix.PreOrderOutput();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;prefix.WriteLine(); // Add(Subtract(Add(a, b), Divide(Multiply(c, d), 2)), Multiply(e, 3))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Actually, .NET Standard provides a built-in System.Linq.Expressions.ExpressionVisitor type with an object-oriented design to traverse general expression trees. This book traverses expression tree in functional paradigm because it is very intuitive for simple arithmetic expression with small code.&lt;/p&gt;
&lt;h3&gt;Expression tree to CIL at runtime&lt;/h3&gt;
&lt;p&gt;If the output is in post-order, where operands are followed by operator, then it can be viewed as the stack operations: push operands to stack, then execute the operator with the operands and push the result on the stack. This is how the evaluation stack based CIL language works. So, a different traversal output in post-order can represent executable CIL instructions. An CIL instruction can be represented by System.Reflection.Emit.OpCode structures with optional argument. So, the output can be a list of instruction-argument pairs (Here a pair is represented by a 2-tuple of OpCode and object. C#’s tuple is discussed in detail in the immutability chapter):&lt;/p&gt;
&lt;p&gt;internal static List&amp;lt;(OpCode, object)&amp;gt; PostOrderOutput(this LambdaExpression expression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;(OpCode, object)&amp;gt; VisitNode(Expression node)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;switch (node.NodeType)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Add:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitBinary((BinaryExpression)node, OpCodes.Add);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Subtract:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitBinary((BinaryExpression)node, OpCodes.Sub);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Multiply:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitBinary((BinaryExpression)node, OpCodes.Mul);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Divide:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitBinary((BinaryExpression)node, OpCodes.Div);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Constant:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new List&amp;lt;(OpCode, object)&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(OpCodes.Ldc_R8, ((ConstantExpression)node).Value) // Push constant to stack.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;case ExpressionType.Parameter:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int parameterIndex = expression.Parameters.IndexOf((ParameterExpression)node);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new List&amp;lt;(OpCode, object)&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(OpCodes.Ldarg_S, parameterIndex) // Push parameter of the specified index to stack.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;default:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(expression));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;(OpCode, object)&amp;gt; VisitBinary(BinaryExpression binary, OpCode postfix)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Post-order output: left child, right child, current node.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;(OpCode, object)&amp;gt; instructions = VisitNode(binary.Left);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;instructions.AddRange(VisitNode(binary.Right));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;instructions.Add((postfix, null)); // Operate and push the result to stack.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return instructions;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return VisitNode(expression.Body);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following code outputs a list of converted CIL instruction:&lt;/p&gt;
&lt;p&gt;internal static void Postfix()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;(OpCode, object)&amp;gt; postfix = infix.PostOrderOutput();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach ((OpCode instruction, object argument) in postfix)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{instruction} {argument}&quot;.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldarg.s 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldarg.s 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// add
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldarg.s 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldarg.s 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// mul
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldc.r8 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// div
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// sub
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldarg.s 4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ldc.r8 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// mul
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// add
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, the source code in C# language represented by this expression tree is successfully converted to instructions CIL language. In another word, C# is compiled to CIL with the help of expression tree.&lt;/p&gt;
&lt;h3&gt;Expression tree to function at runtime&lt;/h3&gt;
&lt;p&gt;The above compiled CIL code is executable. With C#’s metaprogramming capability, a function can be generated at runtime (instead of compiled time), where the compiled CIL code can be emitted into:&lt;/p&gt;
&lt;p&gt;internal static TDelegate CompileToCil&amp;lt;TDelegate&amp;gt;(this Expression&amp;lt;TDelegate&amp;gt; expression)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DynamicMethod dynamicFunction = new DynamicMethod(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;name: string.Empty,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;returnType: expression.ReturnType,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameterTypes: expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;m: MethodBase.GetCurrentMethod().Module);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EmitCil(dynamicFunction.GetILGenerator(), expression.PostOrderOutput());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (TDelegate)(object)dynamicFunction.CreateDelegate(typeof(TDelegate));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void EmitCil(ILGenerator generator, List&amp;lt;(OpCode, object)&amp;gt; cil)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach ((OpCode instruction, object argument) in cil)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (argument == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(instruction); // add, sub, mul, div has no argument.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else if (argument is int)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(instruction, (int)argument); // ldarg.s has int argument of parameter index.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else if (argument is double)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(instruction, (double)argument); // ldc.r8 has double argument of constant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;generator.Emit(OpCodes.Ret); // Return the result.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following code demonstrate how to use it to compile C# expression tree of C# code into CIL code encapsulated by a function, then call the function to execute the compiled CIL code, and finally get the result:&lt;/p&gt;
&lt;p&gt;internal static void CompileAndRun()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double, double, double, double, double&amp;gt; function = expression.CompileToCil();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double result = function(1D, 2D, 3D, 4D, 5D);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.WriteLine(); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;.NET provides a built-in API, System.Linq.Expressions.Expression&amp;lt;TDelegate&amp;gt;’s Compile method, for this purpose - compile expression tree to executable function at runtime:&lt;/p&gt;
&lt;p&gt;internal static void BuiltInCompile()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt;infix =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(a, b, c, d, e) =&amp;gt; a + b - c * d / 2D + e * 3D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double, double, double, double, double&amp;gt; function = infix.Compile();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double result = function(1D, 2D, 3D, 4D, 5D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Internally, Expression&amp;lt;TDelegate&amp;gt;.Compile calls APIs of System.Linq.Expressions.Compiler.LambdaCompile, which is a complete compiler implementation for general expression tree to CIL (not just for simple expression in the above example).&lt;/p&gt;
&lt;h2&gt;Lambda expression and LINQ query&lt;/h2&gt;
&lt;p&gt;As such a powerful syntactic sugar, lambda expression is very important in LINQ query. In local LINQ query for data in memory, lambda expression is compiled as anonymous function. In remote LINQ query for data in a different data domain, lambda expression is compiled as expression tree, which can be compiled or translated from C# language to that domain’s specific language. In above examples, expression tree is compiled to executable CIL. In other scenarios of LINQ remote query, like LINQ to Entities, expression tree can be translated to a part of SQL query that can be executed in database The following examples are a typical LINQ to Objects query (for local data in-memory) and a similar LINQ to Entities query (for remote data in database):&lt;/p&gt;
&lt;p&gt;internal static void LocalLinqToObjectsQuery(IEnumerable&amp;lt;Product&amp;gt; source) // Get source.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; query = source.Where(product =&amp;gt; product.ListPrice &amp;gt; 0M); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Product result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void RemoteLinqToEntitiesQuery(IQueryable&amp;lt;Product&amp;gt; source) // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; query = source.Where(product =&amp;gt; product.ListPrice &amp;gt; 0M); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Product result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As mentioned in the introduction chapter, local LINQ query is represented by IEnumerable&amp;lt;T&amp;gt;, and remote LINQ query is represented by IQueryable&amp;lt;T&amp;gt;. They have different LINQ query methods, take above Where as example:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Where query filters the local/remote data source with the specified predicate as anonymous function/expression tree. For each value in the data source, if the predicate evaluates to true, the data value should be in the query results; otherwise, the data value should be ignored. In the above LINQ to Object/LINQ to Entities queries, the Where query and predicate has exactly the same logic and syntax (filter the source of products, and only keep the products with list price greater than 0), but they are compiled totally differently:&lt;/p&gt;
&lt;p&gt;internal static void EquivalentLinqToObjectsQuery(IEnumerable&amp;lt;Product&amp;gt; source) // Get source.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Product, bool&amp;gt; predicateFunction = product =&amp;gt; product.ListPrice &amp;gt; 0M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to named function with cache field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; query = Enumerable.Where(source, predicateFunction); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Product result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void EquivalentLinqToEntitiesQuery(IQueryable&amp;lt;Product&amp;gt; source) // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = product =&amp;gt; product.ListPrice &amp;gt; 0M;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ParameterExpression productParameter = Expression.Parameter(type: typeof(Product), name: &quot;product&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// body: Expression.GreaterThan(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// left: Expression.Property(expression: productParameter, propertyName: nameof(Product.ListPrice)),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// right: Expression.Constant(value: 0M, type: typeof(decimal))),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// productParameter);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; query = Queryable.Where(source, predicateExpression); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Product result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;At runtime, when the local query executes, the anonymous function is called to predict each local value in the local data source, and the remote query is translated to a WHERE clause in SQL query, then submit to the remote data source and execute. The local query’s usage, execution, and implementation is discussed in the LINQ to Objects chapters. The remote query’s usage, execution and the translation from expression tree to SQL will be discussed in LINQ to Entities chapters.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses C#’s lambda expression, a very powerful syntactic sugar that is very useful in functional programming and LINQ. Lambda expression can be used to define anonymous function. C# implements this by compiling lambda expression to named function. C# also implements lambda expression’s expression body syntax for all kinds of named functions. Lambda expression can also be used to build expression tree, which is a data structure of abstract syntax tree. This chapter also demonstrates how to traverse expression tree and convert C# code to another language, as well as how LINQ implement local query and remote query with one syntax for different query methods and lambda expressions.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (6) Anonymous Function and Lambda Expression</title><link>https://dixin.github.io/posts/functional-csharp-anonymous-function-and-lambda-expression/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-anonymous-function-and-lambda-expression/</guid><description>Besides named function, C# also supports anonymous function, represented by anonymous method or lambda expression with no function name at design time. Lambda expression can also represent expression</description><pubDate>Thu, 06 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Besides named function, C# also supports anonymous function, represented by anonymous method or lambda expression with no function name at design time. Lambda expression can also represent expression tree, This chapter discusses lambda expression as a functional feature of C# language. Lambda expression is also the core concept of lambda calculus, where functional programming originates. It is revisited in the Lambda Calculus chapters.&lt;/p&gt;
&lt;h2&gt;Anonymous method&lt;/h2&gt;
&lt;p&gt;As discussed in the delegate chapter, a function can be represented by a delegate instance, and delegate instance can be initialized with a named function:&lt;/p&gt;
&lt;p&gt;internal static bool IsPositive(int int32) { return int32 &amp;gt; 0; }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NamedFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = IsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 2.0 introduces a syntactic sugar called anonymous method, enabling function to be defined inline with the delegate keyword. The above function can be inline as:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousMethod()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = delegate (int int32) { return int32 &amp;gt; 0; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This time delegate instance is initialized with an anonymous function, which does not have function name at design time. At compile time, a named function is generated. The above example is compiled to:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Func&amp;lt;int, bool&amp;gt; cachedIsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static bool CompiledIsPositive(int int32) { return int32 &amp;gt; 0; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledAnonymousMethod()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (cachedIsPositive == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cachedIsPositive = new Func&amp;lt;int, bool&amp;gt;(CompiledIsPositive);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isPositive = cachedIsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive.Invoke(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides named function, C# compiler also generates a cache field for performance. As discussed in the delegate chapter, a delegate instance is actually an object with an Invoke method. When AnonymousMethod is called for the first time, the delegate instance is constructed with the generated named function, and stored in the static cache fieled forever. When AnonymousMethod is called again, the cached delegate instance is reused.&lt;/p&gt;
&lt;h2&gt;Lambda expression as anonymous function&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces lambda expression syntactic sugar, which can define anonymous function with a lambda operator instead of delegate keyword:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = (int int32) =&amp;gt; { return int32 &amp;gt; 0; };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to: Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is identical to above anonymous method example. The =&amp;gt; operator is called lambda operator and reads “go to”. Lambda expression can be further shortened:&lt;/p&gt;
&lt;p&gt;· if the type of parameter can be inferred (for example, from the specified function type), the type of parameter can be omitted. In above example, the lambda expression’s parameter type can be inferred to be int from the provided function type int –&amp;gt; bool, so it can be simplified to (int32) =&amp;gt; { return int32 &amp;gt; 0; }.&lt;/p&gt;
&lt;p&gt;· if lambda expression has one parameter, the parentheses for the parameter can be omitted. So, the above lambda expression can be simplified to int32 =&amp;gt; { return int32 &amp;gt; 0; }.&lt;/p&gt;
&lt;p&gt;· if the body of the lambda expression has only one statement, the curly brackets for the body and the return keyword can be omitted, which is call expression body syntax. So, the above lambda expression can be just int32 =&amp;gt; int32 &amp;gt; 0.&lt;/p&gt;
&lt;p&gt;Lambda expression with expression body are called expression lambda, for example:&lt;/p&gt;
&lt;p&gt;internal static void ExpressionLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add = (int32A, int32B) =&amp;gt; int32A + int32B;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt;isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int&amp;gt; traceLine = int32 =&amp;gt; int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When a lambda expression having more than one statements in the body, its body has to be a block with curly brackets. It is called statement lambda:&lt;/p&gt;
&lt;p&gt;internal static void StatementLambda()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add = (int32A, int32B) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = int32A + int32B;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt;isPositive = int32 =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32&amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int&amp;gt; traceLine = int32 =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Flush();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For delegate instantiation, lambda expression (both expression lambda and statement lambda) can also be used with the constructor call syntax and type conversion syntax, which is similar to using named function discussed in the delegate chapter:&lt;/p&gt;
&lt;p&gt;internal static void Constructor()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Conversion()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = (Func&amp;lt;int, bool&amp;gt;)(int32 =&amp;gt; int32 &amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Simplified()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These 3 syntaxes are compiled identically.&lt;/p&gt;
&lt;h3&gt;Immediately-invoked function expression&lt;/h3&gt;
&lt;p&gt;An anonymous function is not required to be assigned to a function variable. It can be used directly. The following example directly calls an anonymous function definition. Unfortunately, it cannot be compiled:&lt;/p&gt;
&lt;p&gt;internal static void CallAnonymousFunction(int arg)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(int32 =&amp;gt; int32 &amp;gt; 0)(arg); // Cannot be compiled..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The reason is, C# compiler cannot inter the type information of the lambda expression. The type information can be provided with the constructor call or type conversion syntax above code cannot be compiled because C# compiler cannot infer any type for the lambda expression. For this kind of IIFE (), the above constructor call syntax, or type conversion syntax can be used to provide type information to compiler:&lt;/p&gt;
&lt;p&gt;internal static void CallLambdaExpressionWithConstructor(int arg)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0)(arg);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallLambdaExpressionWithConversion(int arg)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = ((Func&amp;lt;int, bool&amp;gt;)(int32 =&amp;gt; int32 &amp;gt; 0))(arg);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In functional programming, this pattern is called immediately-invoked function expression (IIFE). There is no function name or function variable (delegate instance) name involved at design time. At compile time, C# compiler generates identical code of named function for the above 2 syntaxes:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private sealed class Functions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static readonly Functions Singleton = new Functions();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;int, bool&amp;gt; cachedIsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal bool IsPositive(int int32) { return int32 &amp;gt; 0; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCallLambdaExpressionWithConstructor()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (Functions.cachedIsPositive == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Functions.cachedIsPositive = new Func&amp;lt;int, bool&amp;gt;(Functions.Singleton.IsPositive);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;isPositive = Functions.cachedIsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = isPositive.Invoke(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here are a few more examples of IIFE:&lt;/p&gt;
&lt;p&gt;internal static void ImmediatelyInvokedFunctionExpression()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, int, int&amp;gt;((int32A, int32B) =&amp;gt; int32A + int32B)(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Action&amp;lt;int&amp;gt;(int32 =&amp;gt; int32.WriteLine())(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, int, int&amp;gt;((int32A, int32B) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = int32A + int32B;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return int32&amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Action&amp;lt;int&amp;gt;(int32 =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Flush();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In some other strongly-typed functional languages, like F#, Haskell, etc. the type information can be omitted at design time and inferred at compile time the type information is also not needed for dynamic functional languages, like JavaScript. IIFE was commonly used in JavaScript to modularize or isolate code in the function scope, until the ECMAScript 2015 standard introduces module and block scope to JavaScript.&lt;/p&gt;
&lt;h3&gt;Closure&lt;/h3&gt;
&lt;p&gt;Similar to local function, anonymous function also supports closure for capturing free variable:&lt;/p&gt;
&lt;p&gt;internal static void AnonymousFunctionWithClosure()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int free = 1; // Outside anonynmous function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Action(() =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2; // Inside anonymous function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + free).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;})(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Its compilation is also similar to local function. The difference is, C# compiler generates closure structure for local function, while it generates closure class for anonymous function, which requires heap allocation and can be a performance overhead. The above code is compiled to:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private sealed class Closure1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Free;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Add()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + this.Free).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledAnonymousFunctionWithClosure()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int free = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure1 closure = new Closure1() { Free = free };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.Add(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similar to local function, the closure of anonymous function may also introduce the same performance pitfall of memory leak. Closure must be used with caution for anonymous function too, whenever an anonymous function may live longer than the execution of outer function.&lt;/p&gt;
&lt;h2&gt;Expression bodied function member&lt;/h2&gt;
&lt;p&gt;C# 6.0 and 7.0 introduce expression bodied function member of type. It enables anonymous function’s lambda operator and expression body syntactic sugar to simplify all kinds of named functions, including instance method, static method, extension method, as well as static constructor, constructor, conversion operator, operator overload, getter only property, property getter, property setter, getter only indexer, indexer getter, indexer setter. It also works for local function:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private int value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;static Data() =&amp;gt; MethodBase.GetCurrentMethod().Name.WriteLine(); // Static constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Data(int value) =&amp;gt; this.value = value; // Constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;~Data() =&amp;gt; MethodBase.GetCurrentMethod().Name.WriteLine(); // Finalizer.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal bool InstanceEquals(Data other) =&amp;gt; this.value == other?.value; // Instance method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool StaticEquals(Data @this, Data other) =&amp;gt; @this?.value == other?.value; // Static method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Data operator +(Data data1, Data data2) =&amp;gt; new Data(data1.value + data2.value); // Operator overload.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static explicit operator int(Data value) =&amp;gt; value.value; // Explicit conversion operator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static implicit operator Data(int value) =&amp;gt; new Data(value); // Implicit conversion operator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int ReadOnlyValue =&amp;gt; this.value; // Getter only property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int ReadWriteValue
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get =&amp;gt; this.value; // Property getter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set =&amp;gt; this.value = value; // Property setter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int this[long index] =&amp;gt; throw new NotImplementedException(); // Getter only indexer.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int this[int index]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get =&amp;gt; throw new NotImplementedException(); // Indexer getter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set =&amp;gt; throw new NotImplementedException(); // Indexer setter.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal event EventHandler Created
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add =&amp;gt; MethodBase.GetCurrentMethod().Name.WriteLine(); // Event accessor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remove =&amp;gt; MethodBase.GetCurrentMethod().Name.WriteLine(); // Event accessor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int GetValue()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int LocalFunction() =&amp;gt; this.value; // Local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return LocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This syntax works for extension method and interface explicit implementation too:&lt;/p&gt;
&lt;p&gt;internal internal static partial class DataExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool ExtensionEquals(Data @this, Data other) =&amp;gt; @this?.ReadOnlyValue == other?.ReadOnlyValue; // Extension method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data : IEquatable&amp;lt;Data&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool IEquatable&amp;lt;Data&amp;gt;.Equals(Data other) =&amp;gt; this.value == other?.value; // Explicit interface implementation.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The expression body is just a syntactic sugar. Its compilation has no difference from the statement body with curly bracket.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (5) Delegate: Function type, instance and group</title><link>https://dixin.github.io/posts/functional-csharp-function-type-and-delegate/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-type-and-delegate/</guid><description>C#’s delegate is an important feature to make function first class citizen just like object. C# is a strongly-typed language, where any value and any expression that evaluates to a value has a type. I</description><pubDate>Wed, 05 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;C#’s delegate is an important feature to make function first class citizen just like object. C# is a strongly-typed language, where any value and any expression that evaluates to a value has a type. In C#, a value can be an object, which has type represented by class; a value can also be a function, which has type represented by delegate type. Delegate type can be instantiated to represent a single function instance, or a group of functions.&lt;/p&gt;
&lt;h2&gt;Delegate type as function type&lt;/h2&gt;
&lt;p&gt;C# supports delegate since the beginning to represent function. In many C# documents, the term “a delegate” could be confusing. It can refer to a delegate type, or an instance of some delegate type. So, this book always uses specific term “delegate type” or “delegate instance” when mentioning a delegate.&lt;/p&gt;
&lt;h3&gt;Function type&lt;/h3&gt;
&lt;p&gt;Function’s type can be determined by its input types (0, 1, or more types in specific order) and an output type (void which can be represented by System.Void structure, or another type). This book uses notation input types –&amp;gt; output type for function type. For example, the simplest function type has no input and no output. In another word, it is parameterless, and it returns void. Such function type is denoted () –&amp;gt; void. In C#, a delegate type is defined like a method signature with the delegate keyword prepended:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; void&lt;/p&gt;
&lt;p&gt;internal delegate void FuncToVoid();&lt;/p&gt;
&lt;p&gt;FuncToVoid can be viewed as an alias of function type () –&amp;gt; void. The following functions are all parameterless, and returning void:&lt;/p&gt;
&lt;p&gt;namespace System.Diagnostics&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public sealed class Trace
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void Close();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void Flush();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void Indent();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These functions are all of function type () –&amp;gt; void; in another word, these functions are all of FuncToVoid type.&lt;/p&gt;
&lt;p&gt;The following delegate type represents the string –&amp;gt; void function type, which accepts a string parameter, and returns void:&lt;/p&gt;
&lt;p&gt;// string -&amp;gt; void&lt;/p&gt;
&lt;p&gt;internal delegate void FuncStringToVoid(string @string);&lt;/p&gt;
&lt;p&gt;The following functions are all of FuncStringToVoid type:&lt;/p&gt;
&lt;p&gt;namespace System.Diagnostics&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public sealed class Trace
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void TraceInformation(string message);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void Write(string message);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void WriteLine(string message);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These functions’ parameter names are different from the delegate type definition. In C#/.NET, parameter names are ignored when the compiler identifies function types, only parameter types, their order, and return type matter.&lt;/p&gt;
&lt;p&gt;The following delegate type represents the () –&amp;gt; int function type that is parameterless, and returns int:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; int&lt;/p&gt;
&lt;p&gt;internal delegate int FuncToInt32();&lt;/p&gt;
&lt;p&gt;The following functions are all of FuncToInt32 type:&lt;/p&gt;
&lt;p&gt;namespace System.Runtime.InteropServices&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Marshal
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int GetExceptionCode();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int GetHRForLastWin32Error();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int GetLastWin32Error();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following delegate type represents the (string, int) –&amp;gt; int function type that accepts a string parameter, then an int parameter, and returns int:&lt;/p&gt;
&lt;p&gt;// (string, int) -&amp;gt; int&lt;/p&gt;
&lt;p&gt;internal delegate int FuncStringInt32ToInt32(string @string, int int32);&lt;/p&gt;
&lt;p&gt;It is the type of the following functions (Again, the parameter names are ignored.):&lt;/p&gt;
&lt;p&gt;namespace System.Globalization&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class CharUnicodeInfo
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int GetDecimalDigitValue(string s, int index);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int GetDigitValue(string s, int index);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following delegate type represents the string –&amp;gt; bool function type that accepts a string parameter, and returns bool:&lt;/p&gt;
&lt;p&gt;// string –&amp;gt; bool&lt;/p&gt;
&lt;p&gt;internal delegate bool FuncStringToBoolean(string @string);&lt;/p&gt;
&lt;p&gt;The following functions are all of FuncStringToBoolean type:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DefaultMember(&quot;Chars&quot;)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public sealed class String : IEnumerable&amp;lt;char&amp;gt;, IEnumerable, IComparable, IComparable&amp;lt;String&amp;gt;, IConvertible, IEquatable&amp;lt;String&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool IsNullOrEmpty(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool IsNullOrWhiteSpace(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Contains(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Equals(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool StartsWith(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool EndsWith(String value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Generic delegate type&lt;/h3&gt;
&lt;p&gt;Above FuncToInt32 represents the () –&amp;gt; int function type that is parameterless and return int. Similarly, for parameterless functions returning bool, string, or object result, the following delegate types can be defined:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; bool&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate bool FuncToBoolean();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; string
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate string FuncToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; object
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal delegate object FuncToObject();&lt;/p&gt;
&lt;p&gt;More similar function type definitions can go forever for functions parameterless with different output types. Since C# 2.0 introduces generics, these types can be represented with one single generic delegate type with a type parameter of any name, like TResult:&lt;/p&gt;
&lt;p&gt;// () -&amp;gt; TResult&lt;/p&gt;
&lt;p&gt;internal delegate TResult Func&amp;lt;TResult&amp;gt;();&lt;/p&gt;
&lt;p&gt;Similar to generic interface/class/structure/method syntax, here type parameter TResult is defined in angle brackets following type name, and it is used as the return type. It is just a placeholder to be specified with concrete type argument later. When TResult is int, Func&amp;lt;int&amp;gt; represents the () –&amp;gt; int function type, which is equivalent to FuncToInt32, and Func&amp;lt;bool&amp;gt; is equivalent to FuncToBoolean, Func&amp;lt;string&amp;gt; is equivalent to FuncToString, Func&amp;lt;object&amp;gt; is equivalent to FuncToObject, etc. All the parameterless function types with an output can be represented by Func&amp;lt;TResult&amp;gt;.&lt;/p&gt;
&lt;p&gt;Here is another example of generic delegate type:&lt;/p&gt;
&lt;p&gt;// (T1, T2) -&amp;gt; TResult&lt;/p&gt;
&lt;p&gt;internal delegate TResult Func&amp;lt;T1, T2, TResult&amp;gt;(T1 value1, T2 value2);&lt;/p&gt;
&lt;p&gt;The above generic delegate type can represent any function type with 2 parameters and a return result. For example, Func&amp;lt;string, int, int&amp;gt; is equivalent to above FuncStringInt32ToInt32, so the above CharUnicodeInfo.GetDecimalDigitValue and CharUnicodeInfo.GetDigitalValue functions are of Func&amp;lt;string, int, int&amp;gt; type too. The following are more functions with 2 parameters and a return result:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Math
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (double, double) -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double Log(double a, double newBase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (int, int) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static int Max(int val1, int val2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (double, int) -&amp;gt; double
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static double Round(double value, int digits);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (decimal, MidpointRounding) -&amp;gt; decimal
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Round(decimal d, MidpointRounding mode);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These functions’ types can be represented with Func&amp;lt;double, double, double&amp;gt;, Func&amp;lt;int, int, int&amp;gt;, Func&amp;lt;double, int, double&amp;gt; and Func&amp;lt;decimal, MidpointRounding, decimal&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Unified built-in delegate types&lt;/h3&gt;
&lt;p&gt;As fore mentioned, delegate types can be defined with duplicate, like Func&amp;lt;int&amp;gt; and FuncToInt32 are equivalent, Func&amp;lt;string, int, int&amp;gt; and FuncStringInt32ToInt32 are equivalent, etc. For example, since .NET Framework 2.0, the following delegate type is provided:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T, T) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate int Comparison&amp;lt;in T&amp;gt;(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following custom delegate types can be defined too:&lt;/p&gt;
&lt;p&gt;// (T, T) -&amp;gt; int&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate int NewComparison&amp;lt;in T&amp;gt;(T x, T y);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (string, string) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate TResult FuncStringString&amp;lt;TResult&amp;gt;(string value1, string value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal delegate int FuncToInt32&amp;lt;T1, T2&amp;gt;(T1 value1, T2 value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (string, string) -&amp;gt; int
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal delegate int FuncStringStringToInt32(string value1, string value2);&lt;/p&gt;
&lt;p&gt;As a result, Func&amp;lt;string, string, int&amp;gt;, Comparison&amp;lt;string&amp;gt;, NewComparison&amp;lt;int&amp;gt;, FuncStringString&amp;lt;int&amp;gt;, FuncToInt32&amp;lt;string, string&amp;gt;, FuncStringStringToInt32 all represent (string, string) –&amp;gt; int function type. They are all equivalent.&lt;/p&gt;
&lt;p&gt;Even .NET built-in delegate types can duplicate. For example, .NET Framework 2.0 also provides the following delegate types, which all represent object –&amp;gt; void function type, and are now in .NET Standard:&lt;/p&gt;
&lt;p&gt;namespace System.Threading&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// object -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void SendOrPostCallback(object state);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// object -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void ContextCallback(object state);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// object -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void ParameterizedThreadStart(object obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// object -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void WaitCallback(object state);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// object -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void TimerCallback(object state);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To avoid this kind of duplication, since .NET Framework 3.5, 2 series of built-in delegate types are provided to unify all the function types. The following generic Func delegate types can represent any function type with 0 ~ 16 parameters and a return result:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;out TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// T -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T1, in T2, out TResult&amp;gt;(T1 arg1, T2 arg2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T1, in T2, in T3, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, T4) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T1, in T2, in T3, in T4, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -&amp;gt; TResult
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate TResult Func&amp;lt;in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The in/out modifiers for the type parameter specifies that type parameter is variant, which are discussed in detail in the covariant and contravariant chapter. Unfortunately, above Func types cannot represent any function types returning void. Function type Func&amp;lt;void&amp;gt; or Func&amp;lt;System.Void&amp;gt; cannot be compiled, because C# complier does not allow generic’s type argument to be the void keyword or the System.Void type. So, the following generic Action delegate types are provided to represent all function types with 0 ~ 16 parameters, and no return result:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// T -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T&amp;gt;(T obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T1, in T2&amp;gt;(T1 arg1, T2 arg2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T1, in T2, in T3&amp;gt;(T1 arg1, T2 arg2, T3 arg3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, T4) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T1, in T2, in T3, in T4&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action&amp;lt;in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For consistency, this book always uses the above Func and Action delegate types to represent function types.&lt;/p&gt;
&lt;h2&gt;Delegate instance as function instance&lt;/h2&gt;
&lt;p&gt;Just like object can be instantiated from class, delegate instance can be instantiated from delegate type too. A delegate instance can represent a function, or a group of functions of the same function type.&lt;/p&gt;
&lt;p&gt;To represent a single function, a delegate instance can be constructed by passing the specified function to constructor call syntax, which is similar to the syntax of constructing an object:&lt;/p&gt;
&lt;p&gt;internal static void InstantiationWithConstructor()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func = new Func&amp;lt;int, int, int&amp;gt;(Math.Max);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result1 = func(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The constructor call syntax can be omitted:&lt;/p&gt;
&lt;p&gt;internal static void Instantiation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func = Math.Max;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = func(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With this syntax, above paradigm looks functional. Func&amp;lt;int, int, int&amp;gt; is the function type, func variable is the function (instance), and func variable’s value is initialized with the Math.Max function. And naturally, function func can be called. When func is called, Math.Max executes and returns the result.&lt;/p&gt;
&lt;p&gt;The above functional paradigm is actually implemented by wrapping imperative object-oriented programming. For each delegate type definition, C# compiler generates a class definition. For example, System.Func&amp;lt;T1, T2, TResult&amp;gt; delegate type is compiled to the following class derived from System.MulticastDelegate class:&lt;/p&gt;
&lt;p&gt;public sealed class CompiledFunc&amp;lt;in T1, in T2, out TResult&amp;gt; : MulticastDelegate&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public CompiledFunc(object @object, IntPtr method);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual TResult Invoke(T1 arg1, T2 arg2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual IAsyncResult BeginInvoke(T1 arg1, T2 arg2, AsyncCallback callback, object @object);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void EndInvoke(IAsyncResult result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And MulticastDelegate derives System.Delegate class:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Delegate
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public object Target { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public MethodInfo Method { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Delegate Combine(params Delegate[] delegates);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Delegate Combine(Delegate a, Delegate b);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Delegate Remove(Delegate source, Delegate value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator ==(Delegate d1, Delegate d2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator !=(Delegate d1, Delegate d2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class MulticastDelegate : Delegate
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The generated delegate class has an Invoke method, with the same signature as the delegate type itself. The above delegate instantiation code is a syntactic sugar compiled to normal object instantiation, and the function call is also a syntactic sugar compiled to above Invoke method call:&lt;/p&gt;
&lt;p&gt;internal static void CompiledInstantiation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CompiledFunc&amp;lt;int, int, int&amp;gt;func = new CompiledFunc&amp;lt;int, int, int&amp;gt;(null, Math.Max); // object is null for static method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = func.Invoke(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result.WriteLine(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The generated Invoke method can be useful along with null conditional operator to call a delegate instance if it is not null:&lt;/p&gt;
&lt;p&gt;internal static void Invoke&amp;lt;T&amp;gt;(Action&amp;lt;T&amp;gt; action, T arg)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;action?.Invoke(arg); // if (action != null) { action(arg); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Each delegate instance inherits Target/Method properties, and ==/!= operators from Delegate and MulticastDelegate. The following example demonstrates these members work for delegate instance representing static method:&lt;/p&gt;
&lt;p&gt;internal static void StaticMethod()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func1 = Math.Max;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result1 = func1(1, 2); // func1.Invoke(1, 2);;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1.Target is null).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodInfo method1 = func1.Method;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{method1.DeclaringType}: {method1}&quot;.WriteLine(); // System.Math: Int32 Max(Int32, Int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; func2 = Math.Max;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(func1, func2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1 == func2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, delegate instance func1 looks like a function and works like a function with syntactic sugar, but it is essentially an instance of a generated delegate class. It has an Invoke method accepting 2 int parameters and returning int. Its Target property returns the underlying object which has the represented method. When the underlying method is a static method, Target returns null. Its Method property returns a MethodInfo instance that represents the underlying method, Math.Max. Then delegate instance func2 is instantiated with the same static method, and apparently it is another different instance from func1, so object.ReferenceEquals returns false. However, func1 and func2 wraps the same underlying static method, and the == operator returns true.&lt;/p&gt;
&lt;p&gt;In contrast, the following delegate instances represent instance methods:&lt;/p&gt;
&lt;p&gt;internal static void InstanceMethod()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object instance1 = new object();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;object, bool&amp;gt; func1 = instance1.Equals;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(func1.Target, instance1).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodInfo method2 = func1.Method;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$&quot;{method2.DeclaringType}: {method2}&quot;.WriteLine(); // System.Object: Boolean Equals(System.Object)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object instance2 = new object();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;object, bool&amp;gt; func2 = instance2.Equals;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(func2.Target, instance2).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(func1, func2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1 == func2).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;object, bool&amp;gt; func3 = instance1.Equals;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;object.ReferenceEquals(func1, func3).WriteLine(); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(func1 == func3).WriteLine(); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here func1’s Target property returns instance1, which has the underlying instance method. When 2 delegate instance have the same underlying instance method from the same target, the == operator returns true.&lt;/p&gt;
&lt;p&gt;The BeginInvoke and EndInvoke methods are provided for asynchrony:&lt;/p&gt;
&lt;p&gt;internal static void TraceAllTextAsync(string path)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, string&amp;gt; func = File.ReadAllText;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;func.BeginInvoke(path, TraceAllTextCallback, func);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceAllTextCallback(IAsyncResult asyncResult)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, string&amp;gt; func = (Func&amp;lt;string, string&amp;gt;)asyncResult.AsyncState;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string allText = func.EndInvoke(asyncResult);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;allText.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# asynchronous programming should follow the async/await pattern introduced in C# 5.0 instead of the above BeginInvoke/EndInvoke pattern. The async/await pattern is discussed in the asynchronous function chapter.&lt;/p&gt;
&lt;h2&gt;Delegate instance as function group&lt;/h2&gt;
&lt;p&gt;Besides a single function, delegate instance can also represent a group of function of the same type. The following functions are all of () –&amp;gt; string type:&lt;/p&gt;
&lt;p&gt;internal static string A() { return MethodBase.GetCurrentMethod().Name.WriteLine(); }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static string B() { return MethodBase.GetCurrentMethod().Name.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static string C() { return MethodBase.GetCurrentMethod().Name.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal static string D() { return MethodBase.GetCurrentMethod().Name.WriteLine(); }&lt;/p&gt;
&lt;p&gt;Functions can be combined to a group with + operator, and function can be removed from a group with - operator:&lt;/p&gt;
&lt;p&gt;internal static void FunctionGroup()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; a = A;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; b = B;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup1 = a + b;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup1 += C;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup1 += D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult1 = functionGroup1(); // A B C D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult1.WriteLine(); // D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup2 = functionGroup1 - a;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup2 -= D;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult2 = functionGroup2(); // B C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult2.WriteLine(); // C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup3 = functionGroup1 - functionGroup2 + a + A;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult3 = functionGroup3(); // A D A A
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult3.WriteLine(); // A
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here functionGroup1 is combination of A + B + C + D. When functionGroup1 is called, the 4 internal functions are called one by one, and functionGroup1’s returns the last combined function’s result “D”. functionGroup2 is functionGroup1 – A – D, which is B + C, so functionGroup2’s return value is “C”. functionGroup3 is functionGroup1 – functionGroup2 + a + A, which is A + B + A + A, so its return result is “A”. Actually, + is compiled to Delegate.Combine call and – is compiled to Delegate.Remove call:&lt;/p&gt;
&lt;p&gt;internal static void CompiledFunctionGroup()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; a = A;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; b = B;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(a, b); // = A + B
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(functionGroup1, new Func&amp;lt;string&amp;gt;(C)); // += C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(functionGroup1, new Func&amp;lt;string&amp;gt;(D)); // += D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult1 = functionGroup1.Invoke(); // A B C D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult1.WriteLine(); // D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup2 = (Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup1, a); // = functionGroup1 - A
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup2 = (Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup2, new Func&amp;lt;string&amp;gt;(D)); // -= D
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult2 = functionGroup2.Invoke(); // B C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult2.WriteLine(); // C
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string&amp;gt; functionGroup3 = (Func&amp;lt;string&amp;gt;)Delegate.Combine((Func&amp;lt;string&amp;gt;)Delegate.Combine((Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup1, functionGroup2), a), new Func&amp;lt;string&amp;gt;(A)); // = functionGroup1 - functionGroup2 + a + A
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string lastResult3 = functionGroup3(); // A D A A
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;lastResult3.WriteLine(); // A
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# language implements event with delegate instance as function. To keep it simple and consistent, this book always use delegate instance to represent single function in all non-event scenarios.&lt;/p&gt;
&lt;h3&gt;Event and event handler&lt;/h3&gt;
&lt;p&gt;C# event implements the observer pattern of object-oriented programming. After learning how delegate instance as group works, it is very easy to understand event from a functional programming perspective – an event member is virtually a delegate instance as function group. The following Downloader type can download string from the specified URI, with a Completed event defined:&lt;/p&gt;
&lt;p&gt;internal class DownloadEventArgs : EventArgs&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal DownloadEventArgs(string content) { this.Content = content; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Content { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class Downloader
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal event EventHandler&amp;lt;DownloadEventArgs&amp;gt; Completed;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private void OnCompleted(DownloadEventArgs args)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; functionGroup = this.Completed;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup?.Invoke(this, args);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Start(string uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (WebClient webClient = new WebClient())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string content = webClient.DownloadString(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.OnCompleted(new DownloadEventArgs(content));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It has a Start method to start downloading. When the downloading is done, Start calls OnCompleted, and OnCompleted raises the Completed event member by calling the Completed event as if it is a delegate instance. The type of event member is EventHandler&amp;lt;TEventArgs&amp;gt; generic delegate type:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (object, TEventArgs) -&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void EventHandler&amp;lt;TEventArgs&amp;gt;(object sender, TEventArgs e);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So EventHandler&amp;lt;DownloadEventArgs&amp;gt; represents (object, DownloadEventArgs) –&amp;gt; void function type, where the object argument is the Downloader instance which raises the event, and the DownloadEventArgs argument is the event data, which wraps the downloaded string. The Completed event’s handler must be function of the same (object, DownloadEventArgs) –&amp;gt; void type. The following are 2 examples:&lt;/p&gt;
&lt;p&gt;// (object, DownloadEventArgs) -&amp;gt; void: EventHandler&amp;lt;DownloadEventArgs&amp;gt; or Action&amp;lt;object, DownloadEventArgs&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceContent(object sender, DownloadEventArgs args)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;args.Content.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// (object, DownloadEventArgs) -&amp;gt; void: EventHandler&amp;lt;DownloadEventArgs&amp;gt; or Action&amp;lt;object, DownloadEventArgs&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveContent(object sender, DownloadEventArgs args)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;File.WriteAllText(Path.GetTempFileName(), args.Content);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the += operator can be used to add an event handler function to the event function group, and –= operator can be used to remove the event handler function from the event function group:&lt;/p&gt;
&lt;p&gt;internal static void Event()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Downloader downloader = new Downloader();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.Completed += SaveContent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.Completed += TraceContent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.Completed -= SaveContent;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.Start(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the Start method is called, it downloads the string. Once the download is completed, it raises the Completed event, which is virtually calling a function group. So that the event handler function in the group is called. To be accurately understand this mechanism, the Completed event member of type (object, DownloadEventArgs) –&amp;gt; void is compiled to 3 members: a delegate instance field, an add_Completed method, and a remove_Completed method:&lt;/p&gt;
&lt;p&gt;internal class CompiledDownloader&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private EventHandler&amp;lt;DownloadEventArgs&amp;gt; completedGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void add_Completed(EventHandler&amp;lt;DownloadEventArgs&amp;gt; function)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; oldGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; group = this.completedGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;oldGroup = group;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; newGroup = (EventHandler&amp;lt;DownloadEventArgs&amp;gt;)Delegate.Combine(oldGroup, function);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group = Interlocked.CompareExchange(ref this.completedGroup, newGroup, oldGroup);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} while (group != oldGroup);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void remove_Completed(EventHandler&amp;lt;DownloadEventArgs&amp;gt; function)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; oldGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; group = this.completedGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;do
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;oldGroup = group;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EventHandler&amp;lt;DownloadEventArgs&amp;gt; newGroup = (EventHandler&amp;lt;DownloadEventArgs&amp;gt;)Delegate.Remove(oldGroup, function);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group = Interlocked.CompareExchange(ref this.completedGroup, newGroup, oldGroup);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} while (group != oldGroup);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The generated delegate instance field is the function group to store the event handler functions. The add_Completed and remove_Completed methods adds and removes event handler functions by calling Delegate.Combine and Delegate.Remove, in a in a thread safe approach. It can be simplified by deleting the Interlocked method calls for thread safety, and representing the (object, DownloadEventArgs) –&amp;gt; void delegate type with the normal unified delegate type Action&amp;lt;object, DownloadEventArgs&amp;gt;. The following code shows the essentials after compilation:&lt;/p&gt;
&lt;p&gt;internal class SimplifiedDownloader&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Action&amp;lt;object, DownloadEventArgs&amp;gt; completedGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void add_Completed(Action&amp;lt;object, DownloadEventArgs&amp;gt; function)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.completedGroup += function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void remove_Completed(Action&amp;lt;object, DownloadEventArgs&amp;gt; function)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.completedGroup -= function;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private void OnCompleted(DownloadEventArgs args)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;object, DownloadEventArgs&amp;gt; functionGroup = this.completedGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;functionGroup?.Invoke(this, args);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Start(string uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (WebClient webClient = new WebClient())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string content = webClient.DownloadString(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.OnCompleted(new DownloadEventArgs(content));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledHandleEvent()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SimplifiedDownloader downloader = new SimplifiedDownloader();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.add_Completed(SaveContent);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.add_Completed(TraceContent);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.remove_Completed(SaveContent);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;downloader.Start(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, the C# event/event handler model is quite straightforward from functional programming perspective. It is all about function type, function, and function group:&lt;/p&gt;
&lt;p&gt;· An event is a member of class or structure, as a C#/.NET programming convention, it should be of function type (object, TEventArgs) –&amp;gt; void. If the event is an instance member of a class or structure, the object parameter is the instance of that class or structure which raises the event; if the event is static member, the object parameter should be null. The other TEventArgs parameter should derive from System.EventArgs class, and wraps the information of the event, like the downloaded content of a download complete event, the cursor’s position for a mouse click event, etc.&lt;/p&gt;
&lt;p&gt;· As a convention, event member’s type is usually represented by EventHandler&amp;lt;TEventArgs&amp;gt; delegate type, which is equivalent to Action&amp;lt;object, TEventArgs&amp;gt;.&lt;/p&gt;
&lt;p&gt;· Compiler generates 3 members for an event member: a field member, which is a delegate instance as function group to store event handler function, along with 2 helper method members to add/remove event handler function.&lt;/p&gt;
&lt;p&gt;· An event’s event handler is a function of the same (object, TEventArgs) –&amp;gt; void type.&lt;/p&gt;
&lt;p&gt;· To handle an event, use the += operator to add the event handler function to the event function group.&lt;/p&gt;
&lt;p&gt;· To raise an event, just call the function group, as a result, all the event handler functions stored in the group are called to handle the event.&lt;/p&gt;
&lt;p&gt;This compilation of event member is similar to an auto property member, which can be compiled to a backing field, a getter and a setter. Actually, C# has an event add/remove accessor syntax similar to property getter/setter:&lt;/p&gt;
&lt;p&gt;internal class DownloaderWithEventAccessor&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal event EventHandler&amp;lt;DownloadEventArgs&amp;gt; Completed
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add { this.Completed += value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remove { this.Completed -= value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The add/remove accessors are compiled to above add_Event/remove_Event helper methods.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter discusses delegate, an important functional feature of C#. Delegate type represents function type, and .NET Standard provides unified delegate types. Delegate type can be instantiated to represent a single function, or a function group. C#’s event is implemented by delegate instance as function group. Delegate is the foundation of C# functional programming to enable first class function.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (4) Function input and output</title><link>https://dixin.github.io/posts/functional-csharp-function-parameter-and-return-value/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-parameter-and-return-value/</guid><description>The previous 2 chapters discuss all the named functions in C#. This chapter looks into the input and output features of C# function.</description><pubDate>Tue, 04 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous 2 chapters discuss all the named functions in C#. This chapter looks into the input and output features of C# function.&lt;/p&gt;
&lt;h2&gt;Input by copy vs. input by alias (ref parameter)&lt;/h2&gt;
&lt;p&gt;In C#, by default, arguments are passed to parameters by making a copy (also called passing by value). In the following example, the InputByCopy function has a Uri parameter and an int parameter. System.Uri is class so it is reference type, and int (System.Int32) is structure so it is value type:&lt;/p&gt;
&lt;p&gt;internal static void InputByCopy(Uri reference, int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference = new Uri(&quot;https://flickr.com/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallInputByCopy()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(reference, value); // Copied.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.WriteLine(); // https://weblogs.asp.net/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here a reference type variable and a value type variable are initialized and passed to InputByCopy as arguments. With the default behaviour, the reference and the value are both copied. Similar to local variable discussed in the C# language basics chapter, for reference type, another reference is created to point to the same instance, while for value type, another instance is allocated with copied data. Then the copied reference and value are passed into InputByCopy function, and mutated by the function. So, the original variables are not impacted.&lt;/p&gt;
&lt;p&gt;Similar to ref local variable, parameter with a ref modifier means input by alias without copying (also called passing by reference):&lt;/p&gt;
&lt;p&gt;internal static void InputByAlias(ref Uri reference, ref int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference = new Uri(&quot;https://flickr.com/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallInputByAlias()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByAlias(ref reference, ref value); // Not copied.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.WriteLine(); // https://flickr.com/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This time, a reference type variable and a value type variable are initialized and passed to InputByAlias. InputByAlias’s arguments are just aliases of the original variables. When InputByAlias is called to mutate the aliases, the original variables are mutated as well.&lt;/p&gt;
&lt;h3&gt;Input by immutable alias (in parameter)&lt;/h3&gt;
&lt;p&gt;To prevent function from mutating the input by alias, in modifier can be used for the parameter since C# 7.2:&lt;/p&gt;
&lt;p&gt;internal static void InputByImmutableAlias(in Uri reference, in int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference = new Uri(&quot;https://flickr.com/dixin&quot;); // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = 10; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The in modifier for parameter is similar to the ref readonly modifiers for the local variable. Similarly, inside the function, trying to mutate the immutable alias causes compile time error.&lt;/p&gt;
&lt;h2&gt;Output parameter (out parameter) and out variable&lt;/h2&gt;
&lt;p&gt;C# also supports output parameter, which has a out modifier. The output parameter is also input by alias just like ref parameter:&lt;/p&gt;
&lt;p&gt;internal static bool OutputParameter(out Uri reference, out int value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference = new Uri(&quot;https://flickr.com/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallOutputParameter()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri reference;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OutputParameter(out reference, out value); // Not copied.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.WriteLine(); // https://flickr.com/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The difference is, the ref parameter is input of the function, so a variable must be initialized before passed to the ref parameter. The out parameter can be viewed as output of the function, so a variable is not required to be initialized before being passed to the out parameter. Instead, out parameter must be initialized inside the function.&lt;/p&gt;
&lt;p&gt;C# 7.0 introduces a convenient syntactic sugar called out variable, so that a variable can be declared inline without initialization when it is passed to an out parameter. The above example can be simplified as:&lt;/p&gt;
&lt;p&gt;internal static void OutVariable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OutputParameter(out Uri reference, out int value); // Not copied.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference.WriteLine(); // https://flickr.com/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The out variable declaration is compiled to normal variable declaration&lt;/p&gt;
&lt;h3&gt;Discard out variable&lt;/h3&gt;
&lt;p&gt;Since C# 7.0, if a out argument is not needed, it can be simply discarded with special character _. This syntax works with local variable too.&lt;/p&gt;
&lt;p&gt;internal static void Discard()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = OutputParameter(out _, out _);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OutputParameter(out _, out _);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;_ = OutputParameter(out _, out _);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Parameter array&lt;/h2&gt;
&lt;p&gt;Array parameter with params modifier is called parameter array:&lt;/p&gt;
&lt;p&gt;internal static int Sum(params int[] values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: Sum([ParamArray] int[] values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum = 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (int value in values)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sum += value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The params modifier is compiled to System.ParamArrayAttribute. When calling above function, any number of arguments can be passed to its parameter array, and, of course, array can be passed to parameter array too:&lt;/p&gt;
&lt;p&gt;internal static void CallSum()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum1 = Sum();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum2 = Sum(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum3 = Sum(0, 1, 2, 3, 4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum4 = Sum(new[] { 0, 1, 2, 3, 4 });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When passing argument list to parameter array, the argument list is always compiled to non-null array:&lt;/p&gt;
&lt;p&gt;internal static void CompiledCallSum()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum1 = Sum(Array.Empty&amp;lt;int&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum2 = Sum(new int[] { 0 });
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum3 = Sum(new int[] { 0, 1, 2, 3, 4 });
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int sum4 = Sum(new int[] { 0, 1, 2, 3, 4 });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When function has multiple parameters, the parameter array must be the last:&lt;/p&gt;
&lt;p&gt;internal static void MultipleParameters(bool required1, int required2, params string[] optional) { }&lt;/p&gt;
&lt;h2&gt;Positional argument vs. named argument&lt;/h2&gt;
&lt;p&gt;By default, when calling a function, each argument must align with the parameter’s position. C# 4.0 introduces named argument, which enables specifying parameter name when passing an argument. Both positional argument and named argument can be used to call function:&lt;/p&gt;
&lt;p&gt;internal static void PositionalArgumentAndNamedArgument()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 0); // Positional arguments.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(reference: null, value: 0); // Named arguments.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(value: 0, reference: null); // Named arguments.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, value: 0); // Positional argument followed by named argument.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(reference: null, 0); // Named argument followed by positional argument.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When a function is called with positional arguments, the arguments must align with the parameters. When a function is called with named arguments, the named arguments can be in arbitrary order. And when using positional and named arguments together, before C# 7.2, positional arguments must be followed by named arguments. Since C# 7.2, when all arguments are in correct position, then named argument can precede positional argument. At compile time, all named arguments are compiled to positional arguments. The above InputByCopy calls are compiled to:&lt;/p&gt;
&lt;p&gt;internal static void CompiledPositionalArgumentAndNamedArgument()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(null, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If the named arguments are evaluated with inline function call, the order of evaluation is the same as their appearance:&lt;/p&gt;
&lt;p&gt;internal static void NamedArgumentEvaluation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(reference: GetUri(), value: GetInt32()); // Call GetUri then GetInt32.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(value: GetInt32(), reference: GetUri()); // Call GetInt32 then GetUri.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Uri GetUri() { return default; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;internal static int GetInt32() { return default; }&lt;/p&gt;
&lt;p&gt;When the above InputByCopy calls are compiled, local variable is generated to ensure the arguments are evaluated in the specified order:&lt;/p&gt;
&lt;p&gt;internal static void CompiledNamedArgumentEvaluation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(GetUri(), GetInt32()); // Call GetUri then GetInt32.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = GetInt32(); // Call GetInt32 then GetUri.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;InputByCopy(GetUri(), value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In practice, this syntax should be used with cautious because it can generate local variable, which can be slight performance hit. This tutorial uses named argument syntax frequently for readability:&lt;/p&gt;
&lt;p&gt;internal static void NamedArgument()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UnicodeEncoding unicodeEncoding1 = new UnicodeEncoding(true, true, true);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UnicodeEncoding unicodeEncoding2 = new UnicodeEncoding(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bigEndian: true, byteOrderMark: true, throwOnInvalidBytes: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Required parameter vs. optional parameter&lt;/h2&gt;
&lt;p&gt;By default, function parameters require arguments. C# 4.0 also introduces optional parameter, with a default value specified:&lt;/p&gt;
&lt;p&gt;internal static void OptionalParameter(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool required1, char required2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int optional1 = int.MaxValue, string optional2 = &quot;Default value.&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri optional3 = null, Guid optional4 = new Guid(),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uri optional5 = default, Guid optional6 = default) { }&lt;/p&gt;
&lt;p&gt;The default value for optional parameter must be compile time constant, or default value of the type (null for reference type, or default constructor call for value type, or default expression). If a function has both required parameters and optional parameters, the required parameters must be followed by optional parameters. Optional parameter is not a syntactic sugar. The above function is compiled as the following CIL:&lt;/p&gt;
&lt;p&gt;.method assembly hidebysig static&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void OptionalParameter(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool required1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;char required2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] int32 optional1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] string optional2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] class [System]System.Uri optional3,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] valuetype [mscorlib]System.Guid optional4,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] class [System]System.Uri optional5,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[opt] valuetype [mscorlib]System.Guid optional6
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;) cil managed
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [3] = int32(2147483647) // optional1 = int.MaxValue
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [4] = &quot;Default value.&quot; // optional2 = &quot;Default value.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [5] = nullref // optional3 = null
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [6] = nullref // optional4 = new Guid()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [7] = nullref // optional5 = default
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.param [8] = nullref // optional6 = default
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.maxstack 8
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0000: nop
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0001: ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And function with optional parameters can be called with the named argument syntax too:&lt;/p&gt;
&lt;p&gt;internal static void CallOptionalParameter()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1, string.Empty);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, optional2: string.Empty);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;optional6: Guid.NewGuid(), optional3: GetUri(), required1: false, optional1: GetInt32(),
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;required2: Convert.ToChar(64)); // Call Guid.NewGuid, then GetUri, then GetInt32, then Convert.ToChar.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When calling function with optional parameter, if the argument is not provided, the specified default value is used. Also, local variables can be generated to ensure the argument evaluation order. The above Optional calls are compiled to:&lt;/p&gt;
&lt;p&gt;internal static void CompiledCallOptionalParameter()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1, &quot;Default value.&quot;, null, new Guid(), null, new Guid());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1, &quot;Default value.&quot;, null, new Guid(), null, new Guid());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1, string.Empty, null, new Guid(), null, new Guid());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(true, &apos;@&apos;, 1, string.Empty, null, new Guid(), null, new Guid());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Guid optional6 = Guid.NewGuid(); // Call Guid.NewGuid, then GetUri, then GetInt32, then Convert.ToChar.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri optional3 = GetUri();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int optional1 = GetInt32();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OptionalParameter(false, Convert.ToChar(64), optional1, &quot;Default value.&quot;, optional3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Caller information parameter&lt;/h2&gt;
&lt;p&gt;C# 5.0 introduces caller information parameters. System.Runtime.CompilerServices.CallerMemberNameAttribute, System.Runtime.CompilerServices.CallerFilePathAttribute, System.Runtime.CompilerServices.CallerLineNumberAttribute can be used for optional parameters to obtain the caller function name, caller function file name, and line number:&lt;/p&gt;
&lt;p&gt;internal static void TraceWithCaller(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string message,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CallerMemberName] string callerMemberName = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CallerFilePath] string callerFilePath = null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CallerLineNumber] int callerLineNumber = 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine($&quot;[{callerMemberName}, {callerFilePath}, {callerLineNumber}]: {message}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When calling function with caller information parameters, just omit those arguments:&lt;/p&gt;
&lt;p&gt;internal static void CallTraceWithCaller()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;TraceWithCaller(&quot;Message.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// TraceWithCaller(&quot;Message.&quot;, &quot;CompiledCallTraceWithCaller&quot;, @&quot;D:\Data\GitHub\Tutorial\Tutorial.Shared\Functional\InputOutput.cs,&quot;, 219);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;At compile time, these omitted arguments are generated for the caller.&lt;/p&gt;
&lt;h2&gt;Output by copy vs. output by alias&lt;/h2&gt;
&lt;p&gt;By default, function return result by making a copy (also called returning by value). Which is similar to input by copy by default. The following functions retrieve the first item from the specified array:&lt;/p&gt;
&lt;p&gt;internal static int FirstValueByCopy(int[] values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return values[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Uri FirstReferenceByCopy(Uri[] references)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return references[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When they return the first item to the caller, they return a copied of the reference or value. When the returned item mutates, the item in the array is not impacted:&lt;/p&gt;
&lt;p&gt;internal static void OutputByCopy()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] values = new int[] { 0, 1, 2, 3, 4 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int firstValue = FirstValueByCopy(values); // Copy of values[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstValue = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;values[0].WriteLine(); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri firstReference = FirstReferenceByCopy(references); // Copy of references[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstReference = new Uri(&quot;https://flickr.com/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;references[0].WriteLine(); // https://weblogs.asp.net/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 7.0 introduces output by alias (also called returning by reference). Similar to input by alias, returned result with a ref modifier is not copied:&lt;/p&gt;
&lt;p&gt;internal static ref int FirstValueByAlias(int[] values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ref values[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static ref Uri FirstReferenceByAlias(Uri[] references)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ref references[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above functions can be called with the ref modifier to avoid copying. This time, when the returned alias mutates, the item in the array mutates too:&lt;/p&gt;
&lt;p&gt;internal static void OutputByAlias()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] values = new int[] { 0, 1, 2, 3, 4 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref int firstValue = ref FirstValueByAlias(values); // Alias of values[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstValue = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;values[0].WriteLine(); // 10
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref Uri firstReference = ref FirstReferenceByAlias(references); // Alias of references[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstReference = new Uri(&quot;https://flickr.com/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;references[0].WriteLine(); // https://flickr.com/dixin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Output by immutable alias&lt;/h3&gt;
&lt;p&gt;To prevent caller from modifying the returned alias, ref can be used with the readonly modifier since C# 7.2:&lt;/p&gt;
&lt;p&gt;internal static ref readonly int FirstValueByImmutableAlias(int[] values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ref values[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static ref readonly Uri FirstReferenceByImmutableAlias(Uri[] references)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return ref references[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the above functions can be called with ref modifier, and the readonly modifier is required for the returned alias. Apparently, trying to mutate the returned immutable alias causes error at compile time:&lt;/p&gt;
&lt;p&gt;internal static void OutputByImmutableAlias()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] values = new int[] { 0, 1, 2, 3, 4 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly int firstValue = ref FirstValueByImmutableAlias(values); // Immutable alias of values[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#if DEMO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstValue = 10; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly Uri firstReference = ref FirstReferenceByImmutableAlias(references); // Immutable alias of references[0].
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#if DEMO
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstReference = new Uri(&quot;https://flickr.com/dixin&quot;); // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}}&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter dicusses many input and output features of C# functions, including input by copy, input by alias (ref parameter), input by immutable alias (in parameter), output parameter, out variable, parameter array, named argument, optonal parameter, caller ingormation parameter, output by copy, output by alias, and output by immutable alias.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (3) Local Function and Closure</title><link>https://dixin.github.io/posts/functional-csharp-local-function-and-closure/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-local-function-and-closure/</guid><description>The previous chapter discussed named function. There is one more special kind of named function. local function. Local function can be nested in another function, and it supports an important feature</description><pubDate>Mon, 03 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous chapter discussed named function. There is one more special kind of named function. local function. Local function can be nested in another function, and it supports an important feature closure, the ability access variable outside the local function itself.&lt;/p&gt;
&lt;h2&gt;Local function&lt;/h2&gt;
&lt;p&gt;C# 7.0 introduces local function, which allows defining and calling a named, nested function inside a function. Unlike a local variable, which has to be used after being defined, a local function can be called before or after it is defined:&lt;/p&gt;
&lt;p&gt;internal static void MethodWithLocalFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() // Define local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodBase.GetCurrentMethod().Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction(); // Call local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int PropertyWithLocalFunction
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction(); // Call local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() // Define local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodBase.GetCurrentMethod().Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction(); // Call local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Local function is a syntactic sugar. Its definition is compiled to normal method definition, and its call is compiled to method call. For example, the above method with local function is compiled to:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLocalFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;MethodBase.GetCurrentMethod().Name.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledMethodWithLocalFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CompiledLocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Besides method members, local function can also be nested inside local function:&lt;/p&gt;
&lt;p&gt;internal static void LocalFunctionWithLocalFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void NestedLocalFunction() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;NestedLocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Anonymous function can have local function as well (Anonymous function is discussed in an individual chapter):&lt;/p&gt;
&lt;p&gt;internal static Action AnonymousFunctionWithLocalFunction()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return () =&amp;gt; // Return an anonymous function of type Action.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Unlike other named functions, local function does not support ad hoc polymorphism (overload). The following code cannot be compiled:&lt;/p&gt;
&lt;p&gt;internal static void LocalFunctionOverload()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction(int int32) { } // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Local function is useful to encapsulate code execution in a function. For example, the following binary search function encapsulate the main algorithm in a local function, and execute it recursively:&lt;/p&gt;
&lt;p&gt;internal static int BinarySearchWithLocalFunction&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int BinarySearch(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IList&amp;lt;T&amp;gt;localSource, T localValue, IComparer&amp;lt;T&amp;gt;localComparer, int startIndex, int endIndex)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (startIndex &amp;gt; endIndex) { return -1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int middleIndex = startIndex + (endIndex - startIndex) / 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compare = localComparer.Compare(localSource[middleIndex], localValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (compare == 0) { return middleIndex; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return compare &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? BinarySearch(localSource, localValue, localComparer, startIndex, middleIndex - 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: BinarySearch(localSource, localValue, localComparer, middleIndex + 1, endIndex);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return BinarySearch(source, value, comparer ?? Comparer&amp;lt;T&amp;gt;.Default, 0, source.Count - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# local function supports closure, so above local function can be further simplified, which is discussed later in this chapter.&lt;/p&gt;
&lt;p&gt;Local function is also useful with asynchronous function and generator function to isolate the asynchronous execution and deferred execution, which are discussed in the asynchronous function and LINQ to Objects chapters.&lt;/p&gt;
&lt;h2&gt;Closure&lt;/h2&gt;
&lt;p&gt;In object-oriented programming, it is “perfectly nature normal thing” for a type’s method member to use local variable and field member:&lt;/p&gt;
&lt;p&gt;internal class Closure&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int field = 1; // Outside function Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Add()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2; // Inside function Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + field).WriteLine(); // local + this.field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here in Closure type, its method accesses data inside and outside its definition. Similarly, local function can access variable inside and outside its definition as well:&lt;/p&gt;
&lt;p&gt;internal static void LocalFunctionWithClosure()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int free = 1; // Outside local function Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Add()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2; // Inside local function Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + free).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Add();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here free is a variable defined by outer function and is outside the local function. In C# it can be accessed by both the outer function and the local function. It is the local variable of the outer function, and it is called free variable of the local function. In another word, for a local function, if a variable is neither its local variable, nor its parameter, then this variable is its free variable. Free variable is also called outer variable, non-local variable, or captured variable. This capability for local function to access a free variable, is called closure. C# closure is also a syntactic sugar. The above example is compiled to a closure structure:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[StructLayout(LayoutKind.Auto)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private struct Closure1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Free;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static void CompiledAdd(ref Closure1 closure)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + closure.Free).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLocalFunctionWithClosure()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int free = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure1 closure = new Closure1() { Free = free };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CompiledAdd(ref closure);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# compiler generates:&lt;/p&gt;
&lt;p&gt;· A closure structure to capture the free variable as field.&lt;/p&gt;
&lt;p&gt;· A normal method member definition to represent the local function, with a closure parameter. In its body, the reference to free variable is compiled to reference to closure’s field.&lt;/p&gt;
&lt;p&gt;· A normal method member call with a closure argument, whose field is initialized with the free variable. The instantiated closure is passed to the generated method member as alias to avoid copying the closure instance, since it is a structure. Function input as alias is discussed in the function input and output chapter.&lt;/p&gt;
&lt;p&gt;So, C# compiler implements closure, a functional feature, by generating object-oriented code.&lt;/p&gt;
&lt;p&gt;The above binary search function’s local function accesses the source to search, target value, and comparer through parameter. With closure, the local function does not need these parameters. It can directly access them as free variable:&lt;/p&gt;
&lt;p&gt;internal static int BinarySearchWithClosure&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int BinarySearch(int startIndex, int endIndex)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (startIndex &amp;gt; endIndex) { return -1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int middleIndex = startIndex + (endIndex - startIndex) / 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compare = comparer.Compare(source[middleIndex], value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (compare == 0) { return middleIndex; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return compare &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? BinarySearch(startIndex, middleIndex - 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: BinarySearch(middleIndex + 1, endIndex);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;comparer = comparer ?? Comparer&amp;lt;T&amp;gt;.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return BinarySearch(0, source.Count - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is compiled to the same closure structure and method member pattern:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[StructLayout(LayoutKind.Auto)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private struct Closure2&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IComparer&amp;lt;T&amp;gt; Comparer;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IList&amp;lt;T&amp;gt; Source;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static int CompiledLocalBinarySearch&amp;lt;T&amp;gt;(int startIndex, int endIndex, ref Closure2&amp;lt;T&amp;gt; closure)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (startIndex &amp;gt; endIndex) { return -1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int middleIndex = startIndex + (endIndex - startIndex) / 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compare = closure.Comparer.Compare(closure.Source[middleIndex], closure.Value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (compare == 0) { return middleIndex; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return compare &amp;lt;= 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;? CompiledLocalBinarySearch(middleIndex + 1, endIndex, ref closure)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;: CompiledLocalBinarySearch(startIndex, middleIndex - 1, ref closure);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int CompiledBinarySearchWithClosure&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure2&amp;lt;T&amp;gt; closure = new Closure2&amp;lt;T&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Source = source,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Value = value,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Comparer = comparer
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return CompiledLocalBinarySearch(0, source.Count - 1, ref closure);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As demonstrated above, when the local function has multiple free variables, it still has 1 closure parameter. The closure structure defines multiple fields to capture all free variable and pass to the local function as parameter.&lt;/p&gt;
&lt;h3&gt;Free variable mutation&lt;/h3&gt;
&lt;p&gt;Apparently, free variable is variable and it can mutate. When mutation happens, the accessing local functions can be impacted. In the previous example, if the free variable mutates, the local function apparently outputs different sum of local variable and free variable:&lt;/p&gt;
&lt;p&gt;internal static void FreeVariableMutation()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int free = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Add()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int local = 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(local + free).WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Add(); // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;free = 3; // Free variable mutates.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Add(); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Sometimes, this can be source of problems.&lt;/p&gt;
&lt;p&gt;internal static void FreeVariableReference()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int free = 0; free &amp;lt; 3; free++) // free is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() { free.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunctions.Add(LocalFunction);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // free is 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Action localFunction in localFunctions)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunction(); // 3 3 3 (instead of 0 1 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In this case, the for loop has 3 iterations. In the first iteration, free is 0, a local function is defined to output free’s value, and the local function is stored to a function list. In the second iteration, free becomes 1, a local function is repeatedly defined to write free’s value, and stored in function list, and so on. Later, when calling these stored local functions, they do not output 0, 1, 2, but 3, 3, 3. The reason is, the 3 iterations of for loop share the same free variable, when the for loop is done, the free’s value becomes 3. Then, calling these 3 functions outputs the latest value of outer for 3 times, so it is 3, 3, 3. The compiled code is more intuitive. Notice the local function is compiled to a method member of closure structure, since it is stored:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private struct Closure3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Free;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void LocalFunction() { this.Free.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledFreeVariableReference()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure3 closure = new Closure3();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (closure.Free = 0; closure.Free &amp;lt; 3; closure.Free++) // free is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunctions.Add(closure.LocalFunction);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // closure.Free is 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Action localFunction in localFunctions)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunction(); // 3 3 3 (instead of 0 1 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This can be resolved by capture a snapshot of shared free’s current value in each iteration, and store it in another variable that does not mutate:&lt;/p&gt;
&lt;p&gt;internal static void CopyFreeVariableReference()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int free = 0; free &amp;lt; 3; free++) // free is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int copyOfFree = free;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When free mutates, copyOfFree does not mutate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction() { copyOfFree.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunctions.Add(LocalFunction);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // free is 3. copyOfFree is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Action localFunction in localFunctions)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunction(); // 0 1 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In each iteration of for loop, free is copied to copyOfFree. copyOfFree is not shared cross the iterations and does not mutate. When the for loop is done, 3 local function calls output the values of 3 snapshot values 0, 1, 2.. Above code is compiled to:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private sealed class Closure4
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int CopyOfFree;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void LocalFunction() { this.CopyOfFree.WriteLine(); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCopyFreeVariableReference()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int free = 0; free &amp;lt; 3; free++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure4 closure = new Closure4() { CopyOfFree = free }; // free is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// When free changes, closure.CopyOfFree does not change.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunctions.Add(closure.LocalFunction);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;} // free is 3. closure.CopyOfFree is 0, 1, 2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Action localFunction in localFunctions)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;localFunction(); // 0 1 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Each iteration of the for loop instantiate an independent closure, which captures copyOfFree instead of free. When the for loop is done, each closure’s instance method is called to output its own captured value.&lt;/p&gt;
&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;C# closure provides great convenience to enable local function to directly access free variable. Besides allocating structure on stack, closure may also lead to performance pitfall, because it generates closure structure with reference to the accessed free variable, and that reference is not intuitive at all for developers at design time. The following is a closure example with large free variable:&lt;/p&gt;
&lt;p&gt;internal static partial class LocalFunctions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private static Action persisted;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void FreeVariableLifetime()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;byte[] tempLargeInstance = new byte[0x_7FFF_FFC7]; // Temp variable of large instance, Array.MaxByteArrayLength is 0x_7FFF_FFC7.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int length = tempLargeInstance.Length; // Reference to free variable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;length.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// …
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;persisted = LocalFunction; // Reference to local function.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here temp is a large instance of byte array. It is a temporary local variable of the outer function, and free variable of the local function. It is not explicitly stored to any other variable or field, and supposed to have a short lifetime along with the execution of outer function. However, this temporary variable cannot be garbage collected after the execution of outer function and local function. The reason is, the local function is stored to a static field, and persisted to a long lifetime, so that its free variable should has the same lifetime. The problem is not intuitive at design time. At compile time, the following closure is generated:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private sealed class Closure5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public byte[] TempLargeInstance;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void LocalFunction()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int length = this.TempLargeInstance.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;length.WriteLine();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledFreeVariableLifetime()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;byte[] tempLargeInstance = new byte[0X7FFFFFC7];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure5 closure = new Closure5() { TempLargeInstance = tempLargeInstance };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.LocalFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;persisted = closure.LocalFunction;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// closure&apos;s lifetime is bound to persisted, so is closure.TempLargeInstance.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The large array is captured as a field of the closure structure, which is expected since it is the free variable of the local function. Since the local function is stored, it is also compiled to be a method member of the closure structure. Here comes the problem. When the outer function stores the local function to the static field, it actually instantiates the closure, and stores closure’s instance method to the static field. Since the instance method’s lifetime is persisted, the entire closure instance is persisted with a long lifetime. after the execution of outer function and local function, the closure along cannot be deallocated, with its field of large array not able to be garbage collected, which causes memory leak issue. To fix the issue, consider a different design where local function is not persisted, or local function does not access large instance through free variable.&lt;/p&gt;
&lt;p&gt;Multiple local functions in one function may share the same closure, which may also lead to memory leak. The following example’s problem is even more obscure:&lt;/p&gt;
&lt;p&gt;internal static Action SharedClosure()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;byte[] tempLargeInstance = new byte[0x_7FFF_FFC7];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction1() { int length = tempLargeInstance.Length; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction1();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool tempSmallInstance = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction2() { tempSmallInstance = true; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction2();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return LocalFunction2; // Return a function of Action type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallSharedClosure()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;persisted = SharedClosure(); // Returned LocalFunction2 is persisted.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here LocalFunction2 only accesses free variable tempSmallInstance, and has nothing to do with tempLargeInstance. However, if SharedClosure is called and the returned LocalFunction2 is persisted, tempLargeInstance is still leaked and cannot be garbage collected. Again, the problem is invisible at design time, but intuitive at compile time:&lt;/p&gt;
&lt;p&gt;[CompilerGenerated]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private struct Closure6
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public byte[] TempLargeInstance;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void LocalFunction1() { int length = this.TempLargeInstance.Length; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool TempSmallInstance;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void LocalFunction2() { this.TempSmallInstance = true; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Action CompiledSharedClosure()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Closure6 closure = new Closure6();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.TempLargeInstance = new byte[0x_7FFF_FFC7];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.LocalFunction1();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.TempSmallInstance = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closure.LocalFunction2();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return closure.LocalFunction2; // Return a function of Action type.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# compiler can generate one shared closure structure for multiple local functions and their free variables. If one local function is persisted, the shared closure is persisted, along with all captured free variables of all local functions. Besides a different design not persisting local function or not accessing large free variable, another possible improvement is to separate local functions to different lexical scopes:&lt;/p&gt;
&lt;p&gt;internal static Action SeparatedClosures()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{ // Lexical scope has its own closure.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;byte[] tempLargeInstance = new byte[0x_7FFF_FFC7];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction1() { int length = tempLargeInstance.Length; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction1();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool tempSmallInstance = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void LocalFunction2() { tempSmallInstance = true; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LocalFunction2();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return LocalFunction2; // Return a function of Action type.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# compiler generates an individual closure for each lexical scopes, so the above 2 local function are compiled to 2 separated closures. If the returned LocalFunction2 is persisted, only tempSmallInstance is persisted along with LocalFunction2’s closure.&lt;/p&gt;
&lt;p&gt;So, whenever a local function may live longer than the execution of outer function, free variable must be used with caution. Other languages supporting closure in similar way, like JavaScript, etc., has the same pitfall.&lt;/p&gt;
&lt;h2&gt;Static local function&lt;/h2&gt;
&lt;p&gt;C# 8.0 introduces static local function. Closure is disabled when static keyword is used to define local function.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter explains what is local function, how to define and use it, and its underlying compilation. This chapter also discusses local function’s important feature closure, including the concept, usage, compilation, and analyzed possible performance pitfall of memory leak.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (2) Named function and function polymorphism</title><link>https://dixin.github.io/posts/functional-csharp-named-function-and-static-instance-extension-method/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-named-function-and-static-instance-extension-method/</guid><description>This chapter starts the deep dive in functional programming with C#. C# has named function and anonymous function. In C#, the most intuitive functions are method members of class and structure, includ</description><pubDate>Sun, 02 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;This chapter starts the deep dive in functional programming with C#. C# has named function and anonymous function. In C#, the most intuitive functions are method members of class and structure, including static method, instance method, and extension method, etc. These method members are defined with names at design time and can be called by name, so they are named functions. Some other method-like members, including static constructor, constructor, finalizer, conversion operator, operator overload, property, indexer, event accessor, are also named functions, with function name generated at compiled time. This chapter discusses named functions in C#, how these named functions are defined compiled, and called, as well as their polymorphisms. A special named function, local function, is discussed in next chapter.&lt;/p&gt;
&lt;h2&gt;Constructor, static constructor and finalizer&lt;/h2&gt;
&lt;p&gt;Class and structure can have constructor, static constructor, and finalizer. Constructor can access static and instance members, and is usually used to initialize instance members. Static constructor can only access static members, and is called only once automatically at runtime before the first instance is constructed, or before any static member is accessed. Class can also have finalizer, which usually cleanup unmanaged resources, which is called automatically before the instance is garbage collected at runtime. The following simple type Data is a simple wrapper of an int value:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;static Data() // Static constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // .cctor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Data(int value) // Constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // .ctor
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.value = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Value
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;~Data() // Finalizer.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // Finalize
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// protected override void Finalize()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Trace.WriteLine(MethodBase.GetCurrentMethod().Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// base.Finalize();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here System.Reflection.MethodBase’s static GetCurrentMethod method returns a System.Reflection.MethodInfo instance to represent the current executing function member. MethodInfo’s Name property returns the actual function name at runtime. The static constructor is compiled to a static method like member, which is parameterless and returns void, and has a special name .cctor (class constructor). The constructor is compiled to an instance method like member, with special name .ctor (constructor). And finalizer is compiled to a protected instance method Finalize, which also calls base type’s Finalize method.&lt;/p&gt;
&lt;h2&gt;Static method and instance method&lt;/h2&gt;
&lt;p&gt;Still take above Data type as example. instance method and static method and be defined in the type:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int InstanceAdd(int value1, int value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.value + value1 + value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int StaticAdd(Data @this, int value1, int value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return @this.value + value1 + value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These 2 method both add a Data instance’s value field with other integers. The difference is, the static method cannot use this keyword to access the Data instance, so a Data instance is passed to the static method as the first parameter. These 2 methods are compiled to different signature, but identical CIL in their bodies:&lt;/p&gt;
&lt;p&gt;.method assembly hidebysig instance int32 InstanceAdd (&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int32 value1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 value2) cil managed
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.maxstack 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.locals init ([0] int32 V_0) // Local int variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0000: nop // Do nothing.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0001: ldarg.0 // Load first argument this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0002: ldfld int32 Data::&apos;value&apos; // Load field this.value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0007: ldarg.1 // Load second argument value1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0008: add // Add this.value and value1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0009: ldarg.2 // Load third argument value2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000a: add // Add value2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000b: stloc.0 // Set result to first local variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000c: br.s IL_000e // Transfer control to IL_000e.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000e: ldloc.0 // Load first local variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000f: ret // Return V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.method assembly hidebysig static int32 StaticAdd (
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;class Data this,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 value1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int32 value2) cil managed
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.maxstack 2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.locals init ([0] int32 V_0) // Local int variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0000: nop // Do nothing.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0001: ldarg.0 // Load first argument this.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0002: ldfld int32 Data::&apos;value&apos; // Load field this.value.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0007: ldarg.1 // Load second argument value1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0008: add // Add this.value and value1.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_0009: ldarg.2 // Load third argument value2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000a: add // Add value2.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000b: stloc.0 // Set result to first local variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000c: br.s IL_000e // Transfer control to IL_000e.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000e: ldloc.0 // Load first local variable V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IL_000f: ret // Return V_0.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So internally, instance method works similarly to static method. The different is, in an instance method, the current instance, which can be referred by this keyword, becomes the first actual argument, the first declared argument from the method signature becomes the second actual argument, the second declared argument becomes the third actual argument, and so on. The similarity of above instance and static methods can be viewed as:&lt;/p&gt;
&lt;p&gt;internal int CompiledInstanceAdd(int value1, int value2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data arg0 = this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int arg1 = value1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int arg2 = value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return arg0.value + arg1 + arg2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int CompiledStaticAdd(Data @this, int value1, int value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data arg0 = @this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int arg1 = value1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int arg2 = value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return arg0.value + arg1 + arg2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Extension method&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces extension method syntactic sugar. An extension method is a static method defined in a static non-generic class, with this keyword proceeding the first parameter:&lt;/p&gt;
&lt;p&gt;internal static partial class DataExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int ExtensionAdd(this Data @this, int value1, int value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return @this.Value + value1 + value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above method is called an extension method for Data type. It can be called like an instance method of Data type:&lt;/p&gt;
&lt;p&gt;internal static void CallExtensionMethod(Data data)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = data.ExtensionAdd(1, 2L);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, extension method’s first declared argument becomes the current instance, the second declared argument becomes the first calling argument, the third declared argument becomes the second calling argument, and so on. This syntax design is easy to understand based on the nature of instance and static methods. Actually, the extension method definition is compiled to a normal static method with System.Runtime.CompilerServices.ExtensionAttribute:&lt;/p&gt;
&lt;p&gt;internal static partial class DataExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Extension]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static int CompiledExtensionAdd(Data @this, int value1, int value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return @this.Value + value1 + value2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the extension method call is compiled to normal static method call:&lt;/p&gt;
&lt;p&gt;internal static void CompiledCallExtensionMethod(Data data)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int result = DataExtensions.ExtensionAdd(data, 1, 2L);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a real instance method and an extension name are both defined for the same type with equivalent signature:&lt;/p&gt;
&lt;p&gt;internal partial class Data : IEquatable&amp;lt;Data&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override bool Equals(object obj)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return obj is Data &amp;amp;&amp;amp; this.Equals((Data)obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool Equals(Data other) // Member of IEquatable&amp;lt;T&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.value == other.value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DataExtensions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool Equals(Data @this, Data other)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return @this.Value == other.Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The instance style method call is compiled to instance method call; In order to call the extension method, use the static method call syntax:&lt;/p&gt;
&lt;p&gt;internal static partial class Functions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallMethods(Data data1, Data data2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result1 = data1.Equals(string.Empty); // object.Equals.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result2 = data1.Equals(data2); // Data.Equals.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result3 = DataExtensions.Equals(data1, data2); // DataExtensions.Equals.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When compiling instance style method call, C# compiler looks up methods in the following order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;instance method defined in the type&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;extension method defined in the current namespace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;extension method defined in the current namespace’s parent namespaces&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;extension method defined in the other namespaces imported by using directives&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Extension method can be viewed as if instance method “added” to the specified type. For example, as fore mentioned, enumeration types cannot have method member. However, extension method can be defined for enumeration type:&lt;/p&gt;
&lt;p&gt;internal static class DayOfWeekExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static bool IsWeekend(this DayOfWeek dayOfWeek)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return dayOfWeek == DayOfWeek.Sunday || dayOfWeek == DayOfWeek.Saturday;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the above extension method can be called as if it is the enumeration type’s instance method:&lt;/p&gt;
&lt;p&gt;internal static void CallEnumerationExtensionMethod(DayOfWeek dayOfWeek)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool result = dayOfWeek.IsWeekend();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Most of the LINQ query methods are extension methods, like the Where, OrderBy, Select methods demonstrated previously:&lt;/p&gt;
&lt;p&gt;namespace System.Linq&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These methods’ usage and implementation will be discussed in detail in the LINQ to Objects chapter.&lt;/p&gt;
&lt;p&gt;This book uses the following extension methods to simplify the tracing of single value and values in sequence:&lt;/p&gt;
&lt;p&gt;public static class TraceExtensions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static T WriteLine&amp;lt;T&amp;gt;(this T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static T Write&amp;lt;T&amp;gt;(this T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The WriteLine and Write extension methods are available for any value, and WriteLines is available for any IEnumerable&amp;lt;T&amp;gt; sequence:&lt;/p&gt;
&lt;p&gt;internal static void TraceValueAndSequence(Uri value, IEnumerable&amp;lt;Uri&amp;gt; values)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.WriteLine(); // Equivalent to: Trace.WriteLine(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value.Write(); // Equivalent to: Trace.Write(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;More named functions&lt;/h2&gt;
&lt;p&gt;C# supports operator overload and type conversion operator are defined, they are compiled to static methods. For example:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static Data operator +(Data data1, Data data2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: public static Data op_Addition(Data data1, Data data2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Addition
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Data(data1.value + data2.value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static explicit operator string(Data value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: public static string op_Explicit(Data data)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Explicit
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value.value.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static implicit operator Data(int value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: public static Data op_Implicit(int data)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Implicit
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Data(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The + operator overload is compiled to static method with name op_Addition, the explicit/implicit type conversions are compiled to static op_Explicit/op_Implicit methods. These operators’ usage is compiled to static method calls:&lt;/p&gt;
&lt;p&gt;internal static void Operators(Data data1, Data data2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data result = data1 + data2; // Compiled to: Data.op_Addition(data1, data2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int int32 = (int)data1; // Compiled to: Data.op_Explicit(data1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string @string = (string)data1; // Compiled to: Data.op_Explicit(data1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Data data = 1; // Compiled to: Data.op_Implicit(1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Property member’s getter and setter are also compiled to named methods. For example:&lt;/p&gt;
&lt;p&gt;internal partial class Device&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private string description;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Description
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get // Compiled to: internal string get_Description()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // get_Description
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.description;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set // Compiled to: internal void set_Description(string value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // set_Description
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.description = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The property getter and setter calls are compiled to method calls:&lt;/p&gt;
&lt;p&gt;internal static void Property(Device device)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string description = device.Description; // Compiled to: device.get_Description()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;device.Description = string.Empty; // Compiled to: device.set_Description(string.Empty)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Indexer member can be viewed as parameterized property. The indexer getter/setter are always compiled to get_Item/set_Item methods:&lt;/p&gt;
&lt;p&gt;internal partial class Category&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Subcategory[] subcategories;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Category(Subcategory[] subcategories)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.subcategories = subcategories;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Subcategory this[int index]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get // Compiled to: internal Uri get_Item(int index)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // get_Item
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.subcategories[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set // Compiled to: internal Uri set_Item(int index, Subcategory subcategory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // set_Item
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.subcategories[index] = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Indexer(Category category)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Subcategory subcategory = category[0]; // Compiled to: category.get_Item(0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;category[0] = subcategory; // Compiled to: category.set_Item(0, subcategory)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, an event has an add accessor and a remove accessor, which are either custom defined, or generated by compiler. They are compiled to named methods as well:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal event EventHandler Saved
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add // Compiled to: internal void add_Saved(EventHandler value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // add_Saved
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remove // Compiled to: internal void remove_Saved(EventHandler value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // remove_Saved
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Event is a function group. The +=/-= operators adds remove event handler function to the event, and –= operator removes event handler function from the event. They are compiled to the calls to above named methods:&lt;/p&gt;
&lt;p&gt;internal static void DataSaved(object sender, EventArgs args) { }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EventAccessor(Data data)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;data.Saved += DataSaved; // Compiled to: data.add_Saved(DataSaved)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;data.Saved -= DataSaved; // Compiled to: data.remove_Saved(DataSaved)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C#’s event is discussed in detail in the delegate chapter.&lt;/p&gt;
&lt;h2&gt;Function polymorphisms&lt;/h2&gt;
&lt;p&gt;The word “Polymorphism” comes from Greek, means “many shapes”. In programming, there are several kinds of polymorphisms. In object-oriented programming, a derived type can override base type’s methods to provide. For example, System.IO.FileStream type and System.IO.MemoryStream type derives from System.IO.Stream type:&lt;/p&gt;
&lt;p&gt;namespace System.IO&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Stream : MarshalByRefObject, IDisposable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual void WriteByte(byte value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class FileStream : Stream
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override void WriteByte(byte value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class MemoryStream : Stream
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public override void WriteByte(byte value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;FileStream.WriteByte overrides Stream.WriteByte to implement writing to file system, and MemoryStream.WriteByte overrides Stream.WriteByte to implement writing to memory. This is called subtype polymorphism or inclusion polymorphism. There are also ad hoc polymorphism and parametric polymorphism. In object-oriented programming, the term polymorphism usually refers to subtype polymorphism. In functional programming, the term polymorphism usually refers to parametric polymorphism.&lt;/p&gt;
&lt;h3&gt;Ad hoc polymorphism: method overload&lt;/h3&gt;
&lt;p&gt;Method overloading is supported in C# 1.0, and got improved in 7.3. It allows multiple named functions to share the same name, with different parameter numbers and/or types. For example:&lt;/p&gt;
&lt;p&gt;namespace System.Diagnostics&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public sealed class Trace
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void WriteLine(string message);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static void WriteLine(object value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, the WriteLine overload for string writes the string message. If this is the only method provided, then all the non-string values have to be manually converted to string representation:&lt;/p&gt;
&lt;p&gt;internal partial class Functions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceString(Uri uri, FileInfo file, int int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(uri?.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(file?.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(int32.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The WriteLine overload for object provides convenience for values of arbitrary types. The above code can be simplified to:&lt;/p&gt;
&lt;p&gt;internal static void TraceObject(Uri uri, FileInfo file, int int32)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(file);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;With multiple overloads, WriteLine method is polymorphic and can be called with different arguments. This is called ad hoc polymorphism. In the .NET core library, the most ad hoc polymorphic method is System.Convert’s ToString method. It has 36 overloads to convert values of different types to string representation, in different ways:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Convert
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(bool value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(int value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(long value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(decimal value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(DateTime value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(object value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(int value, IFormatProvider provider);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static string ToString(int value, int toBase);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// More overloads and other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In C#/.NET, constructors can have parameters too, so they can also be overloaded. For example:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct DateTime : IComparable, IFormattable, IConvertible, IComparable&amp;lt;DateTime&amp;gt;, IEquatable&amp;lt;DateTime&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime(long ticks);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime(int year, int month, int day);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime(int year, int month, int day, int hour, int minute, int second);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other constructor overloads and other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Indexers are essentially get_Item/set_Item methods with parameters, so they can be overloaded as well. Take System.Data.DataRow as example:&lt;/p&gt;
&lt;p&gt;namespace System.Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class DataRow
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public object this[DataColumn column] { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public object this[string columnName] { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public object this[int columnIndex] { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other indexer overloads and other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# does not allow method overload with only different return type. The following example cannot be compiled:&lt;/p&gt;
&lt;p&gt;internal static string FromInt64(long value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static DateTime FromInt64(long value) // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new DateTime(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The only exception for this is fore mentioned explicit/implicit type conversion operators, for example:&lt;/p&gt;
&lt;p&gt;internal partial class Data&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static explicit operator long(Data value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: public static long op_Explicit(Data data)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value.value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static explicit operator decimal(Data value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Compiled to: public static decimal op_Explicit(Data data)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value.value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the above example, 2 explicit type conversion operators are both compiled to op_Explicit methods with a single Data parameter. One op_Explicit method returns long, the other op_Explicit method returns decimal. This is the only case where C# allows method overload with only different return type.&lt;/p&gt;
&lt;h3&gt;Parametric polymorphism: generic method&lt;/h3&gt;
&lt;p&gt;Besides ad hoc polymorphism, C# also supports parametric polymorphism for methods since 2.0. The following is a normal method that swaps 2 int values:&lt;/p&gt;
&lt;p&gt;internal static void SwapInt32(ref int value1, ref int value2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2) = (value2, value1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above syntax is called tuple assignment, which is a new feature of C# 7.0, and is discussed in the tuple chapter. To reuse this code for values of any other type, just define a generic method, by replacing int with a type parameter. Similar to generic types, generic method’s type parameters are also declared in angle brackets following the method name:&lt;/p&gt;
&lt;p&gt;internal static void Swap&amp;lt;T&amp;gt;(ref T value1, ref T value2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(value1, value2) = (value2, value1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Generic type parameter’s constraints syntax also works for generic method. For example:&lt;/p&gt;
&lt;p&gt;internal static IStack&amp;lt;T&amp;gt; PushValue&amp;lt;T&amp;gt;(IStack&amp;lt;T&amp;gt; stack) where T : new()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stack.Push(new T());
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return stack;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Generic types and generic methods are heavily used in C# programming. For example, almost every LINQ query API is parametric polymorphic.&lt;/p&gt;
&lt;h3&gt;Type argument inference&lt;/h3&gt;
&lt;p&gt;When calling generic method, if C# compiler can infer generic method’s all type arguments, then the type arguments can be omitted at design time. For example,&lt;/p&gt;
&lt;p&gt;internal static void TypeArgumentInference(string value1, string value2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Swap&amp;lt;string&amp;gt;(ref value1, ref value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Swap(ref value1, ref value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Swap is called with string values, so C# compiler infers type argument string is passed to the method’s type parameter T. C# compiler can only infer type arguments from type of arguments, not from type of return value. Take the following generic methods as example:&lt;/p&gt;
&lt;p&gt;internal static T Generic1&amp;lt;T&amp;gt;(T value)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default(T);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static TResult Generic2&amp;lt;T, TResult&amp;gt;(T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return default(TResult);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When calling them, Generic1’s type argument can be omitted, but Generic2’s type arguments cannot:&lt;/p&gt;
&lt;p&gt;internal static void ReturnTypeInference()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value1 = Generic1(0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string value2 = Generic2&amp;lt;int, string&amp;gt;(0); // Generic2&amp;lt;int&amp;gt;(0) cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For Generic1, T is used as return type, but it can be inferred from the argument type. So, type argument can be omitted for Generic1. For Generic2, T can be inferred from argument type too, but TResult can only possibly be inferred from type of return value, which is not supported by C# compiler. As a result, type arguments cannot be omitted when calling Generic2. Otherwise, C# compiler gives error CS0411: The type arguments for method &apos;Functions.Generic2&amp;lt;T, TResult&amp;gt;(T)&apos; cannot be inferred from the usage. Try specifying the type arguments explicitly.&lt;/p&gt;
&lt;p&gt;Type cannot be inferred from null because null can be of any reference type or nullable value type. For example, when calling above Generic1 with null:&lt;/p&gt;
&lt;p&gt;internal static void NullArgumentType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Generic1&amp;lt;FileInfo&amp;gt;(null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Generic1((FileInfo)null);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo file = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Generic1(file);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;there are some options:&lt;/p&gt;
&lt;p&gt;· Provide the type argument&lt;/p&gt;
&lt;p&gt;· Explicitly convert null to the expected argument type&lt;/p&gt;
&lt;p&gt;· Create a temporary variable of the expected argument type, pass the value to the generic method&lt;/p&gt;
&lt;p&gt;Type argument inference is not supported for generic type’s constructor. Take the following generic type as example:&lt;/p&gt;
&lt;p&gt;internal class Generic&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Generic(T input) { } // T cannot be inferred.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When calling above constructor, type arguments must be provided:&lt;/p&gt;
&lt;p&gt;internal static Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;GenericConstructor(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;input)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return new Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;(input);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// return new Generic(input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A solution is to wrap the constructor call in a static factory method, where type parameter can be inferred:&lt;/p&gt;
&lt;p&gt;internal class Generic // Not Generic&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Generic&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(T input) =&amp;gt; new Generic&amp;lt;T&amp;gt;(input); // T can be inferred.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Now the instance can be constructed without type argument:&lt;/p&gt;
&lt;p&gt;internal static Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;GenericCreate(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;input)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return Generic.Create(input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;Static import&lt;/h2&gt;
&lt;p&gt;C# 6.0 introduces using static directive, a syntactic sugar, to enable accessing static member of the specified type, so that a static method can be called without type name as if it is a function on the fly. Since extension method is essentially static method, this syntax can also import extension methods from the specified type. It also enables accessing enumeration member without enumeration type name.&lt;/p&gt;
&lt;p&gt;using static System.DayOfWeek;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static System.Diagnostics.Trace;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using static System.Linq.Enumerable;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using static System.Math;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void UsingStatic(int value, int[] array)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int abs = Abs(value); // Compiled to: Math.Abs(value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WriteLine(Monday); // Compiled to: Trace.WriteLine(DayOfWeek.Monday)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;int&amp;gt; list = array.ToList(); // Compiled to: Enumerable.ToList(array)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The using directive imports the specified all types’ extension methods under the specified namespace, while the using static directive only import the specified type’s extension methods.&lt;/p&gt;
&lt;h2&gt;Partial method&lt;/h2&gt;
&lt;p&gt;Partial methods can be defined in partial class or partial structure. One part of the type can have the partial method signature, and the partial method can be optionally implemented in another part of the type. This syntactic sugar is useful for code generation. For example, LINQ to SQL can generate entity type in the following pattern:&lt;/p&gt;
&lt;p&gt;[Table(Name = &quot;Production.Product&quot;)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Product()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.OnCreated(); // Call.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partial void OnCreated(); // Signature.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The constructor calls partial method OnCreate, which is a hook. If needed, developer can provide another part of the entity type to implement OnCreate:&lt;/p&gt;
&lt;p&gt;public partial class Product&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;partial void OnCreated() // Optional implementation.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine($&quot;{nameof(Product)} is created.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;If a partial method is implemented, it is compiled to a normal private method. If a partial method is not implemented, the compiler ignores the method signature, and remove all the method calls. For this reason, access modifiers (like public, etc.), attributes, non-void return value are not allowed for partial method.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;As part of the discussion of what are C# functions, this chapter explains what are named functions, how to define and use them, their underlying compilation, and their polymorphisms. The other functions are local function as a special named function, and anonymous function, are discussed in individual chapters.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (1) C# language basics</title><link>https://dixin.github.io/posts/functional-csharp-fundamentals/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-fundamentals/</guid><description>The previous chapter demonstrates that C# is a standardized, cross-platform, and multi-paradigm language, and gives an overview that C# is very functional with rich features, including LINQ, a unified</description><pubDate>Sat, 01 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;The previous chapter demonstrates that C# is a standardized, cross-platform, and multi-paradigm language, and gives an overview that C# is very functional with rich features, including LINQ, a unified functional programming model to work with different data domains. Since this chapter, we dive into C# coding.&lt;/p&gt;
&lt;p&gt;This chapter introduces the basic concepts and some basic syntax of C# programming for readers who are new to C# programming and who want to catch up with the latest status of C# 7.3. These concepts and language elements are used through this book. Understanding these basics, you should be ready for the following chapters of functional programming aspects and LINQ technologies, which covers the functional features of C# and all the relevant features in great detail. Some C# features out of the scope of functional programming and LINQ are not discussed in this book, like inheritance of object-oriented programming, pointer in unsafe code, interop with other unmanaged code, dynamic programming, etc.&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;C#&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Basic features covered in this chapter&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Functional and relevant features covered in later chapters&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Features out of scope&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Class Structure Interface Enumeration Attribute&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Delegate Event Function member ref parameter out parameter Parameter array foreach statement&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Inheritance Pointer Interop&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;pragma directive&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;foreach for IDisposable&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;2.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Static class Partial type Generic type Nullable value type Null coalescing operator&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Anonymous method Generator Covariance and contravariance Generic method&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;3.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Auto property Object initializer Collection initializer&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Anonymous type Implicitly typed local variable Query expression Lambda expression Extension method Partial method&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Named argument Optional argument Generic covariance and contravariance&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Dynamic type&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;5.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Asynchronous function Caller info argument&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;6.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Property initializer Dictionary initializer Null propagation operator Exception filter String interpolation nameof operator&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Static import Expression bodied member await in catch/finally block&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;7.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;throw expression Digit separator&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Out variable Tuple and deconstruction Local function Expanded expression bodied member ref return and local Discard Generalized asynchronous return throw expression Pattern matching&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;7.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;default literal expression&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Async Main method Inferred tuple element name&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;7.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;ref structure Leading underscores in numeric literals&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Non-trailing named arguments in parameter ref readonly return and local Readonly structure&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;private protected modifier&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 12;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span style=&quot;mso-ascii-theme-font: minor-fareast; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast; mso-fareast-language: zh-cn;&quot;&amp;gt;7.3&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;ref local reassignment&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;stackalloc initializer&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Attributes on backing fields&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Expression variables in initializers and queries&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Tuple comparison&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Indexing movable fixed buffers&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Custom fixed statement&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 13; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span style=&quot;mso-ascii-theme-font: minor-fareast; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast; mso-fareast-language: zh-cn;&quot;&amp;gt;8.0&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;using declaration&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Static local function&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;switch expressin&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;pattern match&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Asynchronous stream&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;Type system&lt;/h2&gt;
&lt;p&gt;.NET Standard specification is a list of types and their members, which should be implemented by all frameworks in .NET family and used by .NET languages. C# is a strongly typed language. In C#, any value and any expression that evaluates to a value has a type, any function has a type as well. C# compiler checks all type information to ensure C# program is type safe, unless dynamic type is used.&lt;/p&gt;
&lt;h3&gt;Types and members&lt;/h3&gt;
&lt;p&gt;C# and .NET Standard support 5 kinds of types: class, structure, enumeration, delegate, and interface.&lt;/p&gt;
&lt;p&gt;A class is a reference type defined with the class keyword. It can have fields, properties, methods, events, operators, indexers, constructors, destructor, and nested class, structure, enumeration, delegate, and interface types. A class is always derived from System.Object class.&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Object
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Object();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Equals(Object objA, Object objB);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool ReferenceEquals(Object objA, Object objB);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual bool Equals(Object obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual int GetHashCode();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Type GetType();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual string ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected virtual void Finalize();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Object has a static Equals method to test whether 2 instances are considered equal, an instance Equals method to test whether the current instance and the other instance are considered equal, and a static ReferenceEquals method to test whether 2 instances are the same instance. It has a GetHashCode method as the default hash function to return a hash code number for quick test of instances. It also has a GetType method to return the type of current instance, and a ToString method to return the text representation of the current instance. And finally, it has a virtual Finalize method, which can be overridden by derived types to free and cleanup resources.&lt;/p&gt;
&lt;p&gt;The following example is a part of System.Exception class implementation in .NET Framework. It demonstrates the syntax to define a class and different kinds of members. This class implements the System.ISerializable interface, and derives the System._Exception class. When defining a class, base class System.Object can be omitted.&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Exception : ISerializable, _Exception // , System.Object
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string _message; // Field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Exception _innerException; // Field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[OptionalField(VersionAdded = 4)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private SafeSerializationManager _safeSerializationManager; // Field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Exception InnerException { get { return this._innerException; } } // Property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Exception(string message, Exception innerException) // Constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Init();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this._message = message;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this._innerException = innerException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public virtual Exception GetBaseException() // Method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Exception innerException = this.InnerException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Exception result = this;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (innerException != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;result = innerException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;innerException = innerException.InnerException;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;protected event EventHandler&amp;lt;SafeSerializationEventArgs&amp;gt; SerializeObjectState // Event.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;add
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this._safeSerializationManager.SerializeObjectState += value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;remove
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this._safeSerializationManager.SerializeObjectState -= value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal enum ExceptionMessageKind // Nested enumeration type.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ThreadAbort = 1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ThreadInterrupted = 2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OutOfMemory = 3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here Exception class is tagged as Serializable, and its _safeSerializationManager filed is tagged as OptionalField with additional information. These declarative tags are called attribute in C#. Attribute is a special class derived from System.Attribute class, used like a tag to associate declarative information with C# code elements, including assembly, module, type, type member, function parameter and return value.&lt;/p&gt;
&lt;p&gt;A structure is value type defined with the struct keyword, which is then derived from System.Object class. It can have all kinds of members of class except destructor. A structure always derives from System.ValueType class, and interestingly, System.ValueType is a reference type derived from System.Object. In practice, a structure is usually defined to represent very small and immutable data structure, in order to improve the performance of memory allocation/deallocation. The following example is a part of the implementation of System.TimeSpan structure:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct TimeSpan : IComparable, IComparable&amp;lt;TimeSpan&amp;gt;, IEquatable&amp;lt;TimeSpan&amp;gt;, IFormattable // , System.ValueType
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public const long TicksPerMillisecond = 10000; // Constant.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static readonly TimeSpan Zero = new TimeSpan(0); // Field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal long _ticks; // Field.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public TimeSpan(long ticks) // Constructor.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this._ticks = ticks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public long Ticks { get { return _ticks; } } // Property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Milliseconds // Property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return (int)((_ticks / TicksPerMillisecond) % 1000); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool Equals(TimeSpan t1, TimeSpan t2) // Method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return t1._ticks == t2._ticks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static bool operator ==(TimeSpan t1, TimeSpan t2) // Operator.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return t1._ticks == t2._ticks;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;An enumeration is a value type derived from System.Enum class, which is derived from System.ValueType class. It can only have constant fields of the specified underlying integral type (int by default). For example:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[Serializable]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public enum DayOfWeek // : int
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Sunday = 0,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Monday = 1,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Tuesday = 2,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Wednesday = 3,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Thursday = 4,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Friday = 5,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Saturday = 6,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A delegate is a reference type derived from System.MulticastDelegate class, which is derived from System.Delegate class. Delegate type represents function type, and is discussed in detail in the delegate chapter.&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public delegate void Action();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;An interface is a contract to be implemented by class or structure. Interface can only have public and abstract properties, methods, and events without implementation. For example:&lt;/p&gt;
&lt;p&gt;namespace System.ComponentModel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface INotifyDataErrorInfo
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;event EventHandler&amp;lt;DataErrorsChangedEventArgs&amp;gt; ErrorsChanged; // Event.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bool HasErrors { get; } // Property.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable GetErrors(string propertyName); // Method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Any class or structure implementing the above interface must have the specified 3 members as public.&lt;/p&gt;
&lt;h3&gt;Built-in types&lt;/h3&gt;
&lt;p&gt;There are basic. NET types most commonly used in C# programming, so C# provides language keywords as aliases of those types, which are called built-in types of C#:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;C# keyword&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET type&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;bool&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Boolean&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;sbyte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.SByte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;byte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Byte&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;char&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Char&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;short&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Init16&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;ushort&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.UInit16&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;int&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Init32&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;uint&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.UInit32&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;long&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Init54&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;ulong&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.UInit54&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;float&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Single&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 12;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;double&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Double&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 13;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;decimal&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Decimal&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 14;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;object&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Object&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 15; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;string&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.String&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;Reference type vs. value type&lt;/h3&gt;
&lt;p&gt;In C#, classes are reference types, including object, string, array, etc. Delegates is also reference type, which is discussed later. Structures are value types, including primitive types (bool, sbyte, byte, char, short, ushort, int, uint, long, ulong, float, double), decimal, System.DateTime, System.DateTimeOffset, System.TimeSpan, System.Guid, System.Nullable&amp;lt;T&amp;gt;, enumeration (since enumeration’s underlying type is always a numeric primitive type), etc. The following example defines a reference type and a value type, which look similar to each other:&lt;/p&gt;
&lt;p&gt;internal class Point&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int x;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int y;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Point(int x, int y)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.x = x;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.y = y;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int X { get { return this.x; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Y { get { return this.y; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal readonly struct ValuePoint
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int x;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly int y;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal ValuePoint(int x, int y)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.x = x;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.y = y;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int X { get { return this.x; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal int Y { get { return this.y; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Instances of reference type and value type are allocated differently. Reference type is always allocated on the managed heap, and deallocated by garbage collection. Value type is either allocated on the stack and deallocated by stack unwinding, or is allocated and deallocated inline with the container. So generally, value type may have better performance for allocation and deallocation. Usually, a type can be designed as value type if it is small, immutable, and logically similar to a primitive type. The above System.TimeSpan type structure represents a duration of time, it is designed to be value type, because it is just an immutable wrapper of a long value, which represents ticks. The following example demonstrates this difference:&lt;/p&gt;
&lt;p&gt;internal static void LocalVariable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point reference1 = new Point(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point reference2 = reference1; // Copy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference2 = new Point(3, 4); // reference1 is not impacted.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint value1 = new ValuePoint(5, 6);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint value2 = value1; // Copy.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 = new ValuePoint(7, 8); // value1 is not impacted.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When a Point instance is constructed as a local variable, since it is reference type, it is allocated in the managed heap. Its fields are value types, so the fields are allocated inline on the managed heap too. The local variable reference1 can be viewed as a pointer, pointing to managed heap location that holds the data. When assigning reference1 to reference2, the pointer is copied. So reference1 and reference2 both point to the same Point instance in the managed heap. When ValuePoint is constructed as a local variable, since it is value type. it is allocated in the stack. Its fields are also allocated inline in the stack. The local variable value1 holds the actual data. When assigning value1 to value2, the entire instance is copied, so value1 and value2 are 2 different ValuePoint instances in stack.&lt;/p&gt;
&lt;h3&gt;ref local variable and immutable ref local variable&lt;/h3&gt;
&lt;p&gt;In C#, ref modifier can be used for local variable to avoid copying the reference or the value. ref can be read as “alias” or “no copy”:&lt;/p&gt;
&lt;p&gt;internal static void RefLocalVariable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point reference1 = new Point(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref Point reference2 = ref reference1; // Alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference2 = new Point(3, 4); // reference1 is not reassigned.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint value1 = new ValuePoint(5, 6);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref ValuePoint value2 = ref value1; // Alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 = new ValuePoint(7, 8); // value1 is not reassigned.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point reference3 = new Point(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference2 = ref reference3; // Alias of something else.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint value3 = new ValuePoint(5, 6);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 = ref value3; // Alias of something else.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here reference2 is declared with ref and initialized with reference1. It can be viewed as an alias of reference1. If reference2 mutates, reference1 mutates in sync, and vice versa. C# 7.3 allows ref local variable to be reassigned with ref modifier. After reassigning reference3 to reference2 with ref modifier, reference2 becomes the alias of reference3. Similarly, value2 is an alias of value1. After reassignment with ref modifier, value2 becomes the alias of value3.&lt;/p&gt;
&lt;p&gt;Since C# 7.2, the readonly modifier can be used with ref for immutable alias:&lt;/p&gt;
&lt;p&gt;internal static void ImmutableRefLocalVariable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point reference1 = new Point(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly Point reference2 = ref reference1; // Immutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;reference2 = new Point(3, 4); // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint value1 = new ValuePoint(3, 4);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ref readonly ValuePoint value2 = ref value1; // Immutable alias.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;value2 = new ValuePoint(7, 8); // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The immutability is checked by compiler. Here trying to mutate reference2 and value2 causes compile time error.&lt;/p&gt;
&lt;h3&gt;Array and stack-allocated array&lt;/h3&gt;
&lt;p&gt;In C#, array always derives from System.Array class and is reference type.&lt;/p&gt;
&lt;p&gt;internal static void Array()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point[] referenceArray = new Point[] { new Point(5, 6) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint[] valueArray = new ValuePoint[] { new ValuePoint(7, 8) };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Span&amp;lt;ValuePoint&amp;gt; valueArrayOnStack = stackalloc ValuePoint[] { new ValuePoint(9, 10) };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So referenceArray and valueArray are both allocated on heap, and their items are both on heap too. Since C# 7.3, the new keyword can be replaced by stackalloc keyword to allocate a value type array on stack, with its items on stack too. Stack-allocated array is represented by System.Span&amp;lt;T&amp;gt; structure.&lt;/p&gt;
&lt;h3&gt;Default value&lt;/h3&gt;
&lt;p&gt;Reference type can be null and value type cannot:&lt;/p&gt;
&lt;p&gt;internal static void Default()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point defaultReference = default(Point);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(defaultReference is null); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint defaultValue = default(ValuePoint);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(defaultValue.X); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(defaultValue.Y); // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The default value of reference type is simply null. The default of value type is an actual instance, with all fields initialized to their default values. Actually, the above local variables’ initialization is compiled to:&lt;/p&gt;
&lt;p&gt;internal static void CompiledDefault()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point defaultReference = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint defaultValue = new ValuePoint();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A structure always virtually has a parameterless default constructor. Calling this default constructor instantiates the structure and sets all its fields to default values. Here defaultValue’s int fields are initialized to 0. If ValuePoint has a reference type field, the reference type field is initialized to null.&lt;/p&gt;
&lt;p&gt;Since C# 7.1, the type in the default value expression can be omitted, if the type can be inferred. So the above default value syntax can be simplified to:&lt;/p&gt;
&lt;p&gt;internal static void DefaultLiteralExpression()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point defaultReference = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint defaultValue = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;ref structure&lt;/h3&gt;
&lt;p&gt;C# 7.2 enables the ref modifier for structure definition, so that the structure can be only allocated on stack. This can be helpful for performance critical scenarios, where memory allocation/deallocation on heap can be performance overhead.&lt;/p&gt;
&lt;p&gt;internal ref struct OnStackOnly { }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Allocation()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OnStackOnly valueOnStack = new OnStackOnly();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OnStackOnly[] arrayOnHeap = new OnStackOnly[10]; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class OnHeapOnly
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private OnStackOnly fieldOnHeap; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal struct OnStackOrHeap
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private OnStackOnly fieldOnStackOrHeap; // Cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As fore mentioned, array is reference type allocated on heap, so the compiler does not allow an array of ref structure. An instance of class is always allocated on heap, so ref structure cannot be its field. An instance of normal structure can be on stack or heap, so ref structure cannot be its field either.&lt;/p&gt;
&lt;h3&gt;Static class&lt;/h3&gt;
&lt;p&gt;C# 2.0 enables static modifier for class definition. Take System.Math as example:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public static class Math
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Static members only.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A static class can only have static members, and cannot be instantiated. Static class is compiled to abstract sealed class. In C#, a static class consisting of static methods is equivalent to a module of functions.&lt;/p&gt;
&lt;h3&gt;Partial type&lt;/h3&gt;
&lt;p&gt;C# 2.0 introduces the partial keyword to split the definition of class, structure, or interface at design time.&lt;/p&gt;
&lt;p&gt;internal partial class Device&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private string name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.name; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set { this.name = value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public string FormattedName
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.name.ToUpperInvariant (); }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is good for managing large type by splitting it into multiple smaller files. Partial type is also frequently used in code generation, so that user can append custom code to types generated by tool. At compile time, the multiple parts of a type are merged.&lt;/p&gt;
&lt;h3&gt;Interface and implementation&lt;/h3&gt;
&lt;p&gt;When a type implements an interface, this type can implement each interface member either implicitly or explicitly. The following interface has 2 member methods:&lt;/p&gt;
&lt;p&gt;internal interface IInterface&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Implicit();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Explicit();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And the following type implementing this interface:&lt;/p&gt;
&lt;p&gt;internal class Implementation : IInterface&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Implicit() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void IInterface.Explicit() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This Implementations type has a public Implicit method with the same signature as the IInterface’s Implicit method, so C# compiler takes Implementations.Implicit method as the implementation of IInterface.Implicit method. This syntax is called implicit interface implementation. The other method Explicit, is implemented explicitly as an interface member, not as a member method of Implementations type. The following example demonstrates how to use these interface members:&lt;/p&gt;
&lt;p&gt;internal static void InterfaceMembers()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Implementation @object = new Implementation();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@object.Implicit(); // @object.Explicit(); cannot be compiled.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IInterface @interface = @object;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@interface.Implicit();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@interface.Explicit();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;An implicitly implemented interface member can be accessed from the instance of the implementation type and interface type, but an explicitly implemented interface member can only be accessed from the instance of the interface type. Here the variable name @object and @interface are prefixed with special character @, because object and interface are C# language keywords, and cannot be directly used as identifier.&lt;/p&gt;
&lt;h3&gt;IDisposable interface and using declaration&lt;/h3&gt;
&lt;p&gt;The .NET runtime (CLR, CoreCLR, MonoCLR, etc.) manages memory automatically. It allocates memory for .NET objects and release the memory with garbage collector. A .NET object can also allocate other resources unmanaged by .NET runtime, like opened files, window handles, database connections, etc. .NET provides a standard contract for these types:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public interface IDisposable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;A type implementing the above System.IDisposable interface must have a Dispose method, which explicitly releases its unmanaged resources when called. For example, System.Data.SqlClient.SqlConnection represents a connection to a SQL database, it implements IDisposable and provides Dispose method to release the underlying database connection. The following example is the standard try-finally pattern to use IDisposable object and call Dispose method:&lt;/p&gt;
&lt;p&gt;internal static void Dispose(string connectionString)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SqlConnection connection = new SqlConnection(connectionString);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(connection.ServerVersion);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Work with connection.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;finally
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if ((object)connection != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;((IDisposable)connection).Dispose();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The Dispose method is called in finally block, so it is ensured to be called, even if exception is thrown from the operations in the try block, or if the current thread is aborted. IDisposable is widely used, so C# introduces a using statement syntactic sugar since 1.0. The above code is equivalent to:&lt;/p&gt;
&lt;p&gt;internal static void Using(string connectionString)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using SqlConnection connection = new SqlConnection(connectionString);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(connection.ServerVersion);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Work with connection.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is more declarative at design time, and the try-finally is generated at compile time. Disposable instances should be always used with this syntax, to ensure its Dispose method is called in the right way.&lt;/p&gt;
&lt;h3&gt;Generic type&lt;/h3&gt;
&lt;p&gt;C# 2.0 introduces generic programming. Generic programming is a paradigm that supports type parameters, so that type information are allowed to be provided later. The following stack data structure of int values is non generic:&lt;/p&gt;
&lt;p&gt;internal interface IInt32Stack&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Push(int value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int Pop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class Int32Stack : IInt32Stack
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private int[] values = new int[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Push(int value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref this.values, this.values.Length + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.values[this.values.Length - 1] = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public int Pop()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.values.Length == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Stack empty.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = this.values[this.values.Length - 1];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref this.values, this.values.Length - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This code is not very reusable. Later, if stacks are needed for values of other data types, like string, decimal, etc., then there are some options:&lt;/p&gt;
&lt;p&gt;· For each new data type, make a copy of above code and modify the int type information. So IStringStack and StringStack can be defined for string, IDecimalStack and DecimalStack for decimal, and so on and on. Apparently this way is not feasible.&lt;/p&gt;
&lt;p&gt;· Since every type is derived from object, a general stack for object can be defined, which is IObjectStack and ObjectStack. The Push method accepts object, and Pop method returns object, so the stack can be used for values of any data type. However, this design loses the compile time type checking. Calling Push with any argument can be compiled. Also, at runtime, whenever Pop is called, the returned object has to be casted to the expected type, which is a performance overhead and a chance to fail.&lt;/p&gt;
&lt;h3&gt;Type parameter&lt;/h3&gt;
&lt;p&gt;With generics, a much better option is to replace the concrete type int with a type parameter T, which is declared in angle brackets following the stack type name:&lt;/p&gt;
&lt;p&gt;internal interface IStack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;void Push(T value);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T Pop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class Stack&amp;lt;T&amp;gt;: IStack&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private T[] values = new T[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public void Push(T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref this.values, this.values.Length + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.values[this.values.Length - 1] = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T Pop()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (this.values.Length == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Stack empty.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value = this.values[this.values.Length - 1];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref this.values, this.values.Length - 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When using this generic stack, specify a concrete type for parameter T:&lt;/p&gt;
&lt;p&gt;internal static void Stack()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stack&amp;lt;int&amp;gt;stack1 = new Stack&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stack1.Push(int.MaxValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value1 = stack1.Pop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stack&amp;lt;string&amp;gt;stack2 = new Stack&amp;lt;string&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stack2.Push(Environment.MachineName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string value2 = stack2.Pop();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Stack&amp;lt;Uri&amp;gt;stack3 = new Stack&amp;lt;Uri&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;stack3.Push(new Uri(&quot;https://weblogs.asp.net/dixin&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Uri value3 = stack3.Pop();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So, generics enables code reuse with type safety. IStack&amp;lt;T&amp;gt; and Stack&amp;lt;T&amp;gt; are strong typed, where IStack&amp;lt;T&amp;gt;.Push/Stack&amp;lt;T&amp;gt;.Push accept a value of type T, and IStack&amp;lt;T&amp;gt;Pop/IStack&amp;lt;T&amp;gt;.Pop return a value of type T. For example, When T is int, IStack&amp;lt;int&amp;gt;.Push/Stack&amp;lt;int&amp;gt;.Push accept an int value; When T is string, IStack&amp;lt;string&amp;gt;.Pop/Stack&amp;lt;int&amp;gt;.Pop returns a string value; etc. So IStack&amp;lt;T&amp;gt; and Stack&amp;lt;T&amp;gt; are polymorphic types, and this is called parametric polymorphism.&lt;/p&gt;
&lt;p&gt;In .NET, a generic type with type parameters are called open type (or open constructed type). If generic type’s all type parameters are specified with concrete types, then it is called closed type (or closed constructed type). Here Stack&amp;lt;T&amp;gt; is open type, and Stack&amp;lt;int&amp;gt;, Stack&amp;lt;string&amp;gt;, Stack&amp;lt;Uri&amp;gt; are closed types.&lt;/p&gt;
&lt;p&gt;The syntax for generic structure is the same as above generic class. Generic delegate and generic method will be discussed later.&lt;/p&gt;
&lt;h3&gt;Type parameter constraints&lt;/h3&gt;
&lt;p&gt;For above generic types and the following generic type, the type parameter can be arbitrary value:&lt;/p&gt;
&lt;p&gt;internal class Constraint&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Method()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Above code cannot be compiled, with error CS0403: Cannot convert null to type parameter &apos;T&apos; because it could be a non-nullable value type. The reason is, as fore mentioned, only values of reference types (instances of classes) can be null, but here T is allowed be structure type too. For this kind of scenario, C# supports constraints for type parameters, with the where keyword:&lt;/p&gt;
&lt;p&gt;internal class Constraint&amp;lt;T&amp;gt; where T: class&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Method()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;T value1 = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here T must be reference type, for example, Constraint&amp;lt;string&amp;gt; is allowed by compiler, and Constraint&amp;lt;int&amp;gt; causes a compiler error. Here are some more examples of constraints syntax:&lt;/p&gt;
&lt;p&gt;internal partial class Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;where T1 : struct
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where T2 : class
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where T3 : DbConnection
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where T4 : IDisposable
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where T5 : struct, IComparable, IComparable&amp;lt;T5&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where T6 : new()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where T7 : T2, T3, T4, IDisposable, new() { }&lt;/p&gt;
&lt;p&gt;The above generic type has 7 type parameters:&lt;/p&gt;
&lt;p&gt;· T1 must be value type (structure)&lt;/p&gt;
&lt;p&gt;· T2 must be reference type (class)&lt;/p&gt;
&lt;p&gt;· T3 must be the specified type, or derive from the specified type&lt;/p&gt;
&lt;p&gt;· T4 must be the specified interface, or implement the specified interface&lt;/p&gt;
&lt;p&gt;· T5 must be value type (structure), and must implement all the specified interfaces&lt;/p&gt;
&lt;p&gt;· T6 must have a public parameterless constructor&lt;/p&gt;
&lt;p&gt;· T7 must be or derive from or implement T2, T3, T4, and must implement the specified interface, and must have a public parameterless constructor&lt;/p&gt;
&lt;p&gt;Take T3 as example:&lt;/p&gt;
&lt;p&gt;internal partial class Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void Method(T3 connection)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (connection) // DbConnection implements IDisposable.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open(); // DbConnection has Open method.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Regarding System.Data.Common.DbConnection implements System.IDisposable, and has a CreateCommand method, so the above t3 object can be used with using statement, and the CreateCommand call can be compiled too.&lt;/p&gt;
&lt;p&gt;The following is an example closed type of Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;:&lt;/p&gt;
&lt;p&gt;internal static void CloseType()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Constraints&amp;lt;bool, object, DbConnection, IDbConnection, int, Exception, SqlConnection&amp;gt;closed = default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here:&lt;/p&gt;
&lt;p&gt;· bool is value type&lt;/p&gt;
&lt;p&gt;· object is reference type&lt;/p&gt;
&lt;p&gt;· DbConnection is DbConnection&lt;/p&gt;
&lt;p&gt;· System.Data.Common.IDbConnection implements IDisposable&lt;/p&gt;
&lt;p&gt;· int is value type, implements System.IComparable, and implements System.IComparable&amp;lt;int&amp;gt; too&lt;/p&gt;
&lt;p&gt;· System.Exception has a public parameterless constructor&lt;/p&gt;
&lt;p&gt;· System.Data.SqlClient.SqlConnection derives from object, derives from DbConnection, implements IDbConnection, and has a public parameterless constructor&lt;/p&gt;
&lt;h3&gt;Nullable value type&lt;/h3&gt;
&lt;p&gt;As fore mentioned, In C#/.NET, instance of type cannot be null. However, there are still some scenarios for value type to represent logical null. A typical example is database table. A value retrieved from a nullable integer column can be either integer value, or null. C# 2.0 introduces a nullable value type syntax T?, for example int? reads nullable int. T? is just a shortcut of the System.Nullable&amp;lt;T&amp;gt; generic structure:&lt;/p&gt;
&lt;p&gt;namespace System&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public struct Nullable&amp;lt;T&amp;gt; where T : struct
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private bool hasValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal T value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public Nullable(T value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.value = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.hasValue = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public bool HasValue
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.hasValue; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public T Value
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!this.hasValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new InvalidOperationException(&quot;Nullable object must have a value.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example demonstrates how to use nullable int:&lt;/p&gt;
&lt;p&gt;internal static void Nullable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int? nullable = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nullable = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (nullable != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = (int)nullable;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Apparently, int? is the Nullable&amp;lt;int&amp;gt; structure, and cannot be real null. Above code is syntactic sugar and compiled to normal structure usage:&lt;/p&gt;
&lt;p&gt;internal static void CompiledNullable()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Nullable&amp;lt;int&amp;gt;nullable = new Nullable&amp;lt;int&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nullable = new Nullable&amp;lt;int&amp;gt;(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (nullable.HasValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value = nullable.Value;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When nullable is assigned with null, it is actually assigned with an instance of Nullable&amp;lt;int&amp;gt; instance. Here the structure’s default parameterless constructor is called, so a Nullable&amp;lt;int&amp;gt; instance is initialized, with each data field is initialized with its default value. So nullable’s hasValue field is false, indicating this instance logically represents null. Then nullable is reassigned with normal int value, it is actually assigned with another Nullable&amp;lt;int&amp;gt; instance, where hasValue field is set to true and value field is set to the specified int value. The non null check is compiled to HasValue property call. And the type conversion from int? to int is compiled to the Value property call.&lt;/p&gt;
&lt;h2&gt;Declarative C#&lt;/h2&gt;
&lt;p&gt;C# supports declarative attribute since 1.0. A lot of features are added to C# since 3.0 make it more declarative and less imperative. Most of these features are syntactic sugar.&lt;/p&gt;
&lt;h3&gt;Auto property&lt;/h3&gt;
&lt;p&gt;A property is essentially a getter with body and/or a setter with body. In many cases, a property’s setter and getter just wraps a data field, like the above Device type’s Name property. This pattern can be annoying when a type has many properties for wrapping data fields, so C# 3.0 introduces auto property syntactic sugar:&lt;/p&gt;
&lt;p&gt;internal partial class Device&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal decimal Price { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The backing field definition and the body of getter/setter are generated by compiler:&lt;/p&gt;
&lt;p&gt;internal class CompiledDevice&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private decimal priceBackingField;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal decimal Price
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.priceBackingField; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set { this.priceBackingField = value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Other members.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since C# 6.0, auto property can be getter only. And C# 7.3 allows field-targeted attribute declared on auto property:&lt;/p&gt;
&lt;p&gt;[Serializable]&lt;/p&gt;
&lt;p&gt;internal partial class Category&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;internal Category(string name)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;this.Name = name;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;[field: NonSerialized]&lt;/p&gt;
&lt;p&gt;internal string Name { get; /* private set; */ }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above Name property is compiled to be getter only with read only backing field, and the field-targeted NonSerialized attribute is compiled to the generated backing field:&lt;/p&gt;
&lt;p&gt;[Serializable]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class CompiledCategory
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerBrowsable(DebuggerBrowsableState.Never)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[NonSerialized]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly string nameBackingField;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal CompiledCategory(string name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.nameBackingField = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.nameBackingField; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Property initializer&lt;/h3&gt;
&lt;p&gt;C# 6.0 introduces property initializer syntactic sugar, so that property’s initial value can be provided inline as an expression:&lt;/p&gt;
&lt;p&gt;internal partial class Category&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Guid Id { get; } = Guid.NewGuid();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Description { get; set; } = string.Empty;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The property initializer is compiled to backing field initializer:&lt;/p&gt;
&lt;p&gt;internal partial class CompiledCategory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerBrowsable(DebuggerBrowsableState.Never)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Guid idBackingField = Guid.NewGuid();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerBrowsable(DebuggerBrowsableState.Never)]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private string descriptionBackingField = string.Empty;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Guid Id
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.idBackingField; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Description
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;get { return this.descriptionBackingField; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;set { this.descriptionBackingField = value; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Object initializer&lt;/h3&gt;
&lt;p&gt;A Device instance can be initialized with a sequence of imperative property assignment statements:&lt;/p&gt;
&lt;p&gt;internal static void SetProperties()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Device device = new Device();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;device.Name = &quot;Surface Book&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;device.Price = 1349M;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 3.0 introduces object initializer syntactic sugar to merge constructor call and property setting in a declarative style:&lt;/p&gt;
&lt;p&gt;internal static void ObjectInitializer()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Device device = new Device() { Name = &quot;Surface Book&quot;, Price = 1349M };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The object initializer syntax in the second example is compiled to the code in the first example.&lt;/p&gt;
&lt;h3&gt;Collection initializer&lt;/h3&gt;
&lt;p&gt;Similarly, C# 3.0 also introduces collection initializer syntactic sugar for type that implements System.Collections.IEnumerable interface and has a parameterized Add method. Take the following device collection as example:&lt;/p&gt;
&lt;p&gt;internal class DeviceCollection : IEnumerable&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private Device[] devices = new Device[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal void Add(Device device)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array.Resize(ref this.devices, this.devices.Length + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.devices[this.devices.Length - 1] = device;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public IEnumerator GetEnumerator() // IEnumerable member.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.devices.GetEnumerator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It can be initialized declaratively:&lt;/p&gt;
&lt;p&gt;internal static void CollectionInitializer(Device device1, Device device2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DeviceCollection devices = new DeviceCollection() { device1, device2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above code is compiled to a normal constructor call followed by a sequence of Add method calls:&lt;/p&gt;
&lt;p&gt;internal static void CompiledCollectionInitializer(Device device1, Device device2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DeviceCollection devices = new DeviceCollection();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;devices.Add(device1);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;devices.Add(device2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Index initializer&lt;/h3&gt;
&lt;p&gt;C# 6.0 introduces index initializer for type with indexer setter:&lt;/p&gt;
&lt;p&gt;internal class DeviceDictionary&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Device this[int id] { set { } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It is another declarative syntactic sugar:&lt;/p&gt;
&lt;p&gt;internal static void IndexInitializer(Device device1, Device device2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DeviceDictionary devices = new DeviceDictionary { [10] = device1, [11] = device2 };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above syntax is compiled to normal constructor call followed by a sequence of indexer calls:&lt;/p&gt;
&lt;p&gt;internal static void CompiledIndexInitializer(Device device1, Device device2)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DeviceDictionary devices = new DeviceDictionary();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;devices[0] = device1;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;devices[1] = device2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Null coalescing operator&lt;/h3&gt;
&lt;p&gt;C# 2.0 introduces a null coalescing operator ??. It works with 2 operands as left ?? right. If the left operand is not null, it returns the left operand, otherwise, it returns the right operand. For example, when working with reference or nullable value, it is very common to have null check at runtime, and have null replaced:&lt;/p&gt;
&lt;p&gt;internal partial class Point&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Point Default { get; } = new Point(0, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal partial struct ValuePoint
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static ValuePoint Default { get; } = new ValuePoint(0, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultValueForNull(Point reference, ValuePoint? nullableValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point point;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;If (reference!=null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;point = reference;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;point = reference;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint valuePoint = nullableValue != null ? (ValuePoint)nullableValue : ValuePoint.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This above if statement and ternary operator can be simplified by an expression with the null coalescing operator:&lt;/p&gt;
&lt;p&gt;internal static void DefaultValueForNullWithNullCoalescing(Point reference, ValuePoint? nullableValue)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Point point = reference ?? Point.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ValuePoint valuePoint = nullableValue ?? ValuePoint.Default;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Null conditional operators&lt;/h3&gt;
&lt;p&gt;It is also very common to check null before member or indexer access:&lt;/p&gt;
&lt;p&gt;internal static void NullCheck(Category category, Device[] devices)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string categoryText = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (category != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;categoryText = category.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string firstDeviceName;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (devices != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Device firstDevice = devices[0];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (first != null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;firstDeviceName = firstDevice.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;To simplify the nested if statement for null check with an expression, C# 6.0 introduces null conditional operators (also called null propagation operators), including ?. for member access and ?[] for indexer access:&lt;/p&gt;
&lt;p&gt;internal static void NullCheckWithNullConditional(Category category, Device[] devices)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string categoryText = category?.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string firstDeviceName = devices?[0]?.Name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;throw expression&lt;/h3&gt;
&lt;p&gt;Since C# 7.0, throw statement can be used as expression. The throw expression is frequently used with the conditional operator and null coalescing operator to simplify argument check:&lt;/p&gt;
&lt;p&gt;internal partial class Subcategory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Subcategory(string name, Category category)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Name = !string.IsNullOrWhiteSpace(name) ? name : throw new ArgumentNullException(&quot;name&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Category = category ?? throw new ArgumentNullException(&quot;category&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Category Category { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above throw expressions are compiled to if control flows:&lt;/p&gt;
&lt;p&gt;internal partial class CompiledSubcategory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal CompiledSubcategory(string name, Category category)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;If (string.IsNullOrWhiteSpace(name))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(&quot;name&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Name = name;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (category == null)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentNullException(&quot;category&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.Category = category;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Category Category { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal string Name { get; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Exception filter&lt;/h3&gt;
&lt;p&gt;In C#, it used to be common to catch an exception, filter, and then handle/rethrow. The following example tries to download HTML string from the specified URI, and it can handle the download failure if the response status is bad request. So, it catches the exception to check with an if statement. If the exception has expected info, it handles the exception; otherwise, it rethrows the exception.&lt;/p&gt;
&lt;p&gt;internal static void CatchFilterRethrow(WebClient webClient)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (WebException exception)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Handle exception.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;else
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 6.0 introduces exception filter at the language level. the catch block can have an expression to filter the specified exception before catching. If the expression returns true, the catch block is executed:&lt;/p&gt;
&lt;p&gt;internal static void ExceptionFilter(WebClient webClient)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;catch (WebException exception) when ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Handle exception.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Exception filter is not a syntactic sugar to replace if statement with declarative expression, but a .NET runtime feature. The above exception filter expression is compiled to filter clause in CIL. The following cleaned CIL virtually demonstrates the compilation result:&lt;/p&gt;
&lt;p&gt;.method assembly hidebysig static void ExceptionFilter(class [System]System.Net.WebClient webClient) cil managed&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.try
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;filter
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// when ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Handle exception.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;When the filter expression returns false, the catch clause is never executed, so there is no need to rethrow exception. Rethrowing exception causes stack unwinding, as if the exception is from the throw statement, and the original call stack and other info is lost. So this feature is very helpful for diagnostics and debugging.&lt;/p&gt;
&lt;h3&gt;String interpolation&lt;/h3&gt;
&lt;p&gt;For many years, string composite formatting is widely used in C#. It inserts values to indexed placeholders in string format:&lt;/p&gt;
&lt;p&gt;internal static void Log(Device device)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string message = string.Format(&quot;{0}: {1}, {2}&quot;, DateTime.Now.ToString(&quot;o&quot;), device.Name, device.Price);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(message);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;C# 6.0 introduces string interpolation syntactic sugar to declare the values in place, with no need to maintaining the indexes:&lt;/p&gt;
&lt;p&gt;internal static void LogWithStringInterpolation(Device device)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string message = string.Format($&quot;{DateTime.Now.ToString(&quot;o&quot;)}: {device.Name}, {device.Price}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(message);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The second interpolation version is more declarative and productive, without maintaining a series of indexes. This syntax is actually compiled to the first composite formatting.&lt;/p&gt;
&lt;h3&gt;nameof operator&lt;/h3&gt;
&lt;p&gt;C# 6.0 introduces a nameof operator to obtain the string name of variable, type, or member. Take argument check as example:&lt;/p&gt;
&lt;p&gt;internal static void ArgumentCheck(int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(&quot;count&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The parameter name is a hard coded string, and cannot be checked by compiler. Now with nameof operator, the compiler can generated the above parameter name string constant:&lt;/p&gt;
&lt;p&gt;internal static void NameOf(int count)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (count &amp;lt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new ArgumentOutOfRangeException(nameof(count));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h3&gt;Digit separator and leading underscore&lt;/h3&gt;
&lt;p&gt;C# 7.0 introduces underscore as the digit separator, as well as the 0b prefix for binary number. C# 7.1 supports an optional underscore at the beginning of the number.&lt;/p&gt;
&lt;p&gt;internal static void DigitSeparator()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value1 = 10_000_000;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;double value2 = 0.123_456_789;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value3 = 0b0001_0000; // Binary.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int value4 = 0b_0000_1000; // Binary.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These small features greatly improve the readability of long numbers and binary numbers at design time.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter demonstrates the syntax of C# class, structure, enumeration, interface, as well as their members. It also discusses the concepts of built-in types, reference type, value type, generic type, nullable value type, etc. It then introduces some basic declarative syntax of C#, including initializers, operators, expressions, etc., and how they are implemented by compiler. The declarative syntax in recent C# releases 7.0, 7.1, 7.2, 7.3 are also covered. After getting familiar with these basics, the next chapter starts to discuss more in-depth knowledge of C# functional programming aspects.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (3) LINQ to Data Sources</title><link>https://dixin.github.io/posts/introducing-linq-2-what-is-linq/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-2-what-is-linq/</guid><description>As fore mentioned, LINQ is a functional programming model, consists of syntax in languages and APIs in libraries:</description><pubDate>Thu, 30 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ is a functional programming model, consists of syntax in languages and APIs in libraries:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image002%5B4%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image002%5B4%5D_thumb.gif&quot; alt=&quot;clip_image002[4]&quot; title=&quot;clip_image002[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For a certain language, like C#, there is only 1 set of LINQ query syntax working with many LINQ API sets, and each API set works with a specific data domain. Here are examples of these API sets:&lt;/p&gt;
&lt;p&gt;· In .NET Standard, Microsoft provides:&lt;/p&gt;
&lt;p&gt;o LINQ to Objects: a set of LINQ APIs for .NET objects in memory&lt;/p&gt;
&lt;p&gt;o Parallel LINQ: another set of LINQ APIs also for .NET objects in memory, with parallel query capability&lt;/p&gt;
&lt;p&gt;o LINQ to XML: a set of LINQ APIs for XML data objects in memory&lt;/p&gt;
&lt;p&gt;· Microsoft also provides other libraries based on .NET Standard:&lt;/p&gt;
&lt;p&gt;o LINQ to Entities: a set of LINQ APIs in Entity Framework Core (EF Core) library for databases, including Microsoft SQL Server, Microsoft Azure SQL Database (aka SQL Azure), as well as SQLite, Oracle, MySQL, PostgreSQL, etc.&lt;/p&gt;
&lt;p&gt;o LINQ to NoSQL: a set of LINQ APIs for Azure CosmosDB, the Microsoft NoSQL database service. For convenience these APIs are called LINQ to NoSQL in this book.&lt;/p&gt;
&lt;p&gt;· In .NET Framework for Windows, Microsoft provides:&lt;/p&gt;
&lt;p&gt;o LINQ to DataSets: a set of LINQ APIs for data cached in data sets&lt;/p&gt;
&lt;p&gt;o LINQ to SQL: a set of LINQ APIs for relational data in Microsoft SQL Server&lt;/p&gt;
&lt;p&gt;· There are also third-party LINQ libraries, for example:&lt;/p&gt;
&lt;p&gt;o LINQ to JSON, s set of LINQ APIs for JSON data in memory&lt;/p&gt;
&lt;p&gt;o LINQ to Twitter, a set of LINQ APIs for Twitter data in Twitter’s services.&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-padding-alt: 0in 0in 0in 0in; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium 1pt; border-style: solid none none solid; border-color: windowtext currentcolor currentcolor windowtext; padding: 0in; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ APIs&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET &amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Standard: NuGet&amp;lt;/span&amp;gt; package&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET &amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Framework: NuGet&amp;lt;/span&amp;gt; package&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt; or .dll assembly&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt medium medium; border-style: solid solid none none; border-color: windowtext windowtext currentcolor currentcolor; padding: 0in; mso-border-top-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Namespace&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to Objects&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;NETStandard.Library&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Core.dll&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0.1in; line-height: 17pt; mso-add-space: auto;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;LINQ to Objects Interactive Extension (Ix)&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 8pt 0.1in; line-height: 17pt; mso-add-space: auto;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;System.Interactive&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 8pt 0.1in; line-height: 17pt; mso-add-space: auto;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;System.Interactive&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 8pt 0.1in; line-height: 17pt; mso-add-space: auto;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;System.Linq&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Parallel LINQ&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;NETStandard.Library&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Core.dll&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Linq&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to XML&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;NETStandard.Library&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Xml.Linq.dll&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Xml.Linq&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to Entities&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft.EntityFrameworkCore&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft.EntityFrameworkCore&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Microsoft.EntityFrameworkCore&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to NoSQL&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft.Azure.DocumentDB&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;.Core&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft.Azure.DocumentDB&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Microsoft.Azure.Documents.Client&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to SQL&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Not available&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;System.Data.Linq.dll&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Data.Linq&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to DataSets&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Not available&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;System.Data.DataSetExtensions.dll&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;System.Data&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to JSON&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Newtonsoft.Json&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Newtonsoft.Json&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Newtonsoft.Json.Linq&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt 1pt; border-style: none none solid solid; border-color: currentcolor currentcolor windowtext windowtext; padding: 0in; mso-border-left-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;64&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ to Twitter&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;linqtotwitter&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;216&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;linqtotwitter&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor windowtext windowtext currentcolor; padding: 0in; mso-border-right-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;74&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;LinqToTwitter&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;One language for different data domains&lt;/h3&gt;
&lt;p&gt;C# developer can use a single LINQ language syntax to work with different data. At compile time, the LINQ syntax can be compiled to different API calls according to different contexts. At runtime, these specific API calls work with specific data domains. To use LINQ to work with data, there are usually 3 steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Get the data source for LINQ query&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Define the LINQ query&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute the LINQ query&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;LINQ to Objects&lt;/h3&gt;
&lt;p&gt;LINQ to Objects queries .NET objects in memory. The following example queries positive integers from the integer array in memory, and get the integers’ square roots in ascending order:&lt;/p&gt;
&lt;p&gt;internal static void LinqToObjectsWithQueryExpression()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;double&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from int32 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where int32&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby int32
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Sqrt(int32); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (double result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the data source is a sequence of integers in memory. The query is built declaratively in native C# language keywords (where, orderby, select, etc.), which is called query expression:&lt;/p&gt;
&lt;p&gt;· The from clause specifies data source&lt;/p&gt;
&lt;p&gt;· The where clause filters the data source and keeps the integers greater than 0,&lt;/p&gt;
&lt;p&gt;· The orderby clause sort the filtered integers in ascending order&lt;/p&gt;
&lt;p&gt;· The select clause maps the sorted integers to their square roots.&lt;/p&gt;
&lt;p&gt;Building the query does not execute it. Later, when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;p&gt;Besides above query expression syntax. There is another query method call syntax to build LINQ query:&lt;/p&gt;
&lt;p&gt;internal static void LinqToObjectsWithQueryMethods()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt;source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;double&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(int32 =&amp;gt; int32 &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderBy(int32 =&amp;gt; int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Select(int32 =&amp;gt; Math.Sqrt(int32)); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (double result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;These 2 versions of query are identical. The query expression is compiled to query method calls, which is discussed in detail in the Functional Programming and LINQ to Objects chapters.&lt;/p&gt;
&lt;h3&gt;Parallel LINQ&lt;/h3&gt;
&lt;p&gt;The above LINQ to Object query executes sequentially. The filter-sort-map computation are executed for all integers with a single thread, and the query results are produced one by one in a deterministic order. Parallel LINQ (to Objects) is the parallel version of the LINQ to Objects APIs. It also works with objects in memory but can execute the query in parallel with multiple threads, in order to utilize multiple processor cores and improve the LINQ query performance. The following are the parallel version of the above queries:&lt;/p&gt;
&lt;p&gt;internal static void ParallelLinq()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int[] values = { 4, 3, 2, 1, 0, -1 };
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt;source = values.AsParallel(); // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;double&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from int32 in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where int32 &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby int32
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select Math.Sqrt(int32); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// ParallelQuery&amp;lt;double&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(int32 =&amp;gt; int32 &amp;gt; 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(int32 =&amp;gt; int32)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(int32 =&amp;gt; Math.Sqrt(int32));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;query.ForAll(result =&amp;gt; Trace.WriteLine(result)); // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The query creation syntax is exactly the same as sequential LINQ to Objects. The query execution syntax is different. In the previous LINQ to Objects query execution, a foreach loop is used to pull the results one by one sequentially. Here Parallel LINQ provides a special ForAll method to execute the pulling in parallel. Since the results are computed in parallel, the query results can be produced in nondeterministic order.&lt;/p&gt;
&lt;h3&gt;LINQ to XML&lt;/h3&gt;
&lt;p&gt;LINQ to XML queries XML data. The ASP.NET blog RSS feed https://weblogs.asp.net/dixin/rss is XML and can be the source:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;rss version=&quot;2.0&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;title&amp;gt;Dixin&apos;s Blog&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link&amp;gt;https://weblogs.asp.net:443/dixin/&amp;lt;/link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;description&amp;gt;https://weblogs.asp.net:443/dixin/&amp;lt;/description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;title&amp;gt;EntityFramework.Functions: Code First Functions for Entity Framework&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link&amp;gt;https://weblogs.asp.net/dixin/entityframework.functions&amp;lt;/link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;description&amp;gt;&amp;lt;!-- Description. --&amp;gt;&amp;lt;/description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;pubDate&amp;gt;Mon Dec 17, 2015 06:27:56 GMT&amp;lt;/pubDate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;guid isPermaLink=&quot;true&quot;&amp;gt;https://weblogs.asp.net/dixin/entityframework.functions&amp;lt;/guid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;.NET&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;LINQ&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;Entity Framework&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;LINQ to Entities&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;category&amp;gt;Code First&amp;lt;/category&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- More items. --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/channel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/rss&amp;gt;&lt;/p&gt;
&lt;p&gt;The following example queries the items with permalink from the feed and get the items’ titles in ascending order of the items’ publish dates:&lt;/p&gt;
&lt;p&gt;internal static void LinqToXml()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XDocument feed = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;XElement&amp;gt;source = feed.Descendants(&quot;item&quot;); // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from item in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where (bool)item.Element(&quot;guid&quot;).Attribute(&quot;isPermaLink&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby (DateTime)item.Element(&quot;pubDate&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select (string)item.Element(&quot;title&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(item =&amp;gt; (bool)item.Element(&quot;guid&quot;).Attribute(&quot;isPermaLink&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(item =&amp;gt; (DateTime)item.Element(&quot;pubDate&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(item =&amp;gt; (string)item.Element(&quot;title&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In this example, the data source is XML data loaded in memory. It queries all &amp;lt;item&amp;gt; elements in the XML document, filter them and only keep the &amp;lt;item&amp;gt; elements with child&amp;lt; guid&amp;gt; elements, whose isPermaLink attributes have the value true, then sort the &amp;lt;item&amp;gt; element by the time represented by the child&amp;lt; pubDate&amp;gt; elements in descending order; then get &amp;lt;item&amp;gt; elements’ child &amp;lt;title&amp;gt; elements’ values. Again, later when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;h3&gt;LINQ to DataSets&lt;/h3&gt;
&lt;p&gt;.NET Framework provides System.Data.DataSet type to cache tabular data from relational database. When working with relational database, this book uses Microsoft SQL database and Microsoft AdventureWorks sample database. In the following example, data is read from the AdventureWorks database’s Production.Product table, and cached in a DataSet instance. The following example queries the products in the specified subcategory, and get the products’ names, in ascending order of products’ list prices.&lt;/p&gt;
&lt;p&gt;internal static void LinqToDataSets(string connectionString)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DataSet dataSet = new DataSet())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DataAdapter dataAdapter = new SqlDataAdapter(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@&quot;SELECT [Name], [ListPrice], [ProductSubcategoryID] FROM [Production].[Product]&quot;, connectionString))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;dataAdapter.Fill(dataSet);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerableRowCollection&amp;lt;DataRow&amp;gt; source = dataSet.Tables[0].AsEnumerable(); // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;EnumerableRowCollection&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from product in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where product.Field&amp;lt;int&amp;gt;(&quot;ProductSubcategoryID&quot;) == 1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby product.Field&amp;lt;decimal&amp;gt;(&quot;ListPrice&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select product.Field&amp;lt;string&amp;gt;(&quot;Name&quot;); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// EnumerableRowCollection&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(product =&amp;gt; product.Field&amp;lt;int&amp;gt;(&quot;ProductSubcategoryID&quot;) == 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(product =&amp;gt; product.Field&amp;lt;decimal&amp;gt;(&quot;ListPrice&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(product =&amp;gt; product.Field&amp;lt;string&amp;gt;(&quot;Name&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the query is created to filter the products in the DataSet object, and only keeps the products under the specified subcategory, then sort the products by their list price fields, then get the products’ name fields. Later, when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;h3&gt;LINQ to Entities&lt;/h3&gt;
&lt;p&gt;Microsoft Entity Framework Core provides LINQ to Entities to enable LINQ queries directly working with data in database. The AdventureWorks sample database includes the following 3 related tables:&lt;/p&gt;
&lt;p&gt;[](file:///D:/Temp/User/WindowsLiveWriter-1359268108/supfiles8825BF9/image_thumb312.png)&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image004%5B4%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image004%5B4%5D_thumb.gif&quot; alt=&quot;clip_image004[4]&quot; title=&quot;clip_image004[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following example queries Production.Product table for the products under the specified category, and get the products’ names in the order of their list prices:&lt;/p&gt;
&lt;p&gt;internal static void LinqToEntities()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;source = adventureWorks.Products; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from product in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby product.ListPrice
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select product.Name; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(product =&amp;gt; product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(product =&amp;gt; product.ListPrice)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here the data source is the relational data stored in the remote database table, not local .NET objects in memory. The above AdventureWorks type is the LINQ to Entities data context and represents the database, and its Products property represents the table. The query is created to filter the products in the table, and only keeps the products under the specified category, then sort the products by their list prices, and get the products’ names. Later, when pulling the results from the query with a foreach loop, the query is executed to read from the database.&lt;/p&gt;
&lt;h3&gt;LINQ to SQL&lt;/h3&gt;
&lt;p&gt;LINQ to SQL is a lightweight database access technology provided by .NET Framework. As the name suggests, LINQ to SQL only works with Microsoft SQL Server. Its APIs are similar to LINQ to Entities APIs. So, if the above queries are implemented by LINQ to SQL, the code can have the same looking:&lt;/p&gt;
&lt;p&gt;#if NETFX&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToSql()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (AdventureWorks adventureWorks = new AdventureWorks())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt;source = adventureWorks.Products; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from product in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby product.ListPrice
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select product.Name; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(product =&amp;gt; product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(product =&amp;gt; product.ListPrice)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#endif&lt;/p&gt;
&lt;p&gt;Here the AdventureWorks type is a LINQ to SQL data context, which is different from the LINQ to Entities data context. So, the pulling execution on the query triggers LINQ to SQL API calls, which read data from the database.&lt;/p&gt;
&lt;h3&gt;LINQ to NoSQL&lt;/h3&gt;
&lt;p&gt;Microsoft provides LINQ APIs in client library to work with its non-relational database (aka NoSQL database) service, CosmosDB. To setup a data source for LINQ, create a free account, then follow the Microsoft documents to import some JSON documents representing some stores with addresses:&lt;/p&gt;
&lt;p&gt;[&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;id&quot;: &quot;1424&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Name&quot;: &quot;Closeout Boutique&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Address&quot;: {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;AddressType&quot;: &quot;Main Office&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;AddressLine1&quot;: &quot;1050 Oak Street&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;Location&quot;: {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;City&quot;: &quot;Seattle&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;StateProvinceName&quot;: &quot;Washington&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;PostalCode&quot;: &quot;98104&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;CountryRegionName&quot;: &quot;United States&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// More documents.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;]&lt;/p&gt;
&lt;p&gt;Here the source is the database’s Store collection. The following example queries the stores in the specified city, and get their names in the alphabetic order:&lt;/p&gt;
&lt;p&gt;internal static void LinqToNoSql(string key)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DocumentClient client = new DocumentClient(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;new Uri(&quot;https://dixin.documents.azure.com:443/&quot;), key))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IOrderedQueryable&amp;lt;Store&amp;gt;source = client.CreateDocumentQuery&amp;lt;Store&amp;gt;(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;UriFactory.CreateDocumentCollectionUri(&quot;dixin&quot;, &quot;Store&quot;)); // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; query = from store in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where store.Address.Location.City == &quot;Seattle&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby store.Name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select store.Name; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(store =&amp;gt; store.Address.CountryRegionName == &quot;United States&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(store =&amp;gt; store.Address.PostalCode)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(store =&amp;gt; store.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The query is created to filter the products in the collection, and only keeps the stores in the specified city, then sort the stores by their names, then get the stores’ names.&lt;/p&gt;
&lt;h3&gt;LINQ to JSON&lt;/h3&gt;
&lt;p&gt;LINQ to JSON is a third party set of APIs enabling LINQ for JSON data. Tumblr provides APIs returning JSON data, which can be a data source:&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;meta&quot;: {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;status&quot;: 200,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;msg&quot;: &quot;OK&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;response&quot;: {
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;posts&quot;: [
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;type&quot;: &quot;photo&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;blog_name&quot;: &quot;dixinyan&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;id&quot;: 94086491678,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;post_url&quot;: &quot;http://dixinyan.tumblr.com/post/94086491678/microsoft-way-microsoft-campus-microsoft-campus&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;slug&quot;: &quot;microsoft-way-microsoft-campus-microsoft-campus&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;date&quot;: &quot;2014-08-07 19:11:43 GMT&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;timestamp&quot;: 1407438703,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;state&quot;: &quot;published&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;format&quot;: &quot;html&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;reblog_key&quot;: &quot;FZQVzcFD&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;tags&quot;: [ &quot;Microsoft&quot; ],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;short_url&quot;: &quot;https://tmblr.co/Z_W6Et1Nd-UuU&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;summary&quot;: &quot;Microsoft Way, Microsoft Campus Microsoft Campus is the informal name of Microsoft&apos;s corporate headquarters, located at One...&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;recommended_source&quot;: null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;recommended_color&quot;: null,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;note_count&quot;: 4,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;caption&quot;: &quot;&amp;lt;h2&amp;gt;Microsoft Way, Microsoft Campus &amp;lt;/h2&amp;gt;&amp;lt;p&amp;gt;Microsoft Campus is the informal name of Microsoft&amp;amp;rsquo;s corporate headquarters, located at One Microsoft Way in Redmond, Washington. Microsoft initially moved onto the grounds of the campus on February 26, 1986. &amp;lt;a href=\&quot;http://en.wikipedia.org/wiki/Microsoft_Redmond_Campus\&quot; target=\&quot;_blank\&quot;&amp;gt;en.wikipedia.org/wiki/Microsoft_Redmond_Campus&amp;lt;/a&amp;gt;\n\n&amp;lt;a href=\&quot;https://www.flickr.com/dixin\&quot; target=\&quot;_blank\&quot;&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;image_permalink&quot;: &quot;http://dixinyan.tumblr.com/image/94086491678&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;can_like&quot;: true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;can_reblog&quot;: true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;can_send_in_message&quot;: true,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;can_reply&quot;: false,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;display_avatar&quot;: true
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// More post info.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// More posts.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;],
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&quot;total_posts&quot;: 20
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example queries the posts with specified tag, and get their summary in the order of items’ publish dates:&lt;/p&gt;
&lt;p&gt;internal static void LinqToJson(string apiKey)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (WebClient webClient = new WebClient())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string feedUri = $&quot;https://api.tumblr.com/v2/blog/dixinyan.tumblr.com/posts/photo?api_key={apiKey}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;JObject feed = JObject.Parse((webClient.DownloadString(feedUri)));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;JToken&amp;gt;source = feed[&quot;response&quot;][&quot;posts&quot;]; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from post in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where post[&quot;tags&quot;].Any(tag =&amp;gt; &quot;Microsoft&quot;.Equals((string)tag, StringComparison.OrdinalIgnoreCase))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby (DateTime)post[&quot;date&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select (string)post[&quot;summary&quot;]; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IEnumerable&amp;lt;string&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(post =&amp;gt; post[&quot;tags&quot;].Any(tag =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// &quot;Microsoft&quot;.Equals((string)tag, StringComparison.OrdinalIgnoreCase)))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(post =&amp;gt; (DateTime)post[&quot;date&quot;])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(post =&amp;gt; (string)post[&quot;summary&quot;]);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (string result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It queries all posts in the JSON document, filter them and only keep the items with the specified tag, then sort the posts by their publish dates, then get the items’ titles.&lt;/p&gt;
&lt;h3&gt;LINQ to Twitter&lt;/h3&gt;
&lt;p&gt;LINQ to Twitter is another third-party library enabling LINQ queries for Twitter data. To access Twitter as a data source, registering an app with Twitter to get the consumer key, consumer secrete, OAuth token, and OAuth token secrete. The following example queries the tweets with specified search keyword:&lt;/p&gt;
&lt;p&gt;internal static void LinqToTwitter(&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string consumerKey, string consumerSecret, string oAuthToken, string oAuthTokenSecret)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SingleUserAuthorizer credentials = new SingleUserAuthorizer()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CredentialStore = new InMemoryCredentialStore()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConsumerKey = consumerKey,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ConsumerSecret = consumerSecret,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OAuthToken = oAuthToken,
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;OAuthTokenSecret = oAuthTokenSecret
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (TwitterContext twitter = new TwitterContext(credentials))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Search&amp;gt;source = twitter.Search; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;List&amp;lt;Status&amp;gt;&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from search in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where search.Type == SearchType.Search &amp;amp;&amp;amp; search.Query == &quot;LINQ&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby search.SearchMetaData.Count
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select search.Statuses; // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Equivalent to:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// IQueryable&amp;lt;List&amp;lt;Status&amp;gt;&amp;gt; query = source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Where(search =&amp;gt; search.Type == SearchType.Search &amp;amp;&amp;amp; search.Query == &quot;LINQ&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .OrderBy(search =&amp;gt; search.SearchMetaData.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .Select(search =&amp;gt; search.Statuses);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (List&amp;lt;Status&amp;gt; search in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Status status in search)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(status.Text);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Sometimes the query result could be fun. For example, a casino in Las Vegas is named LINQ, and a Japanese idol girls’ music group is also named LinQ (Love in Qshu), etc.&lt;/p&gt;
&lt;h3&gt;Productivity&lt;/h3&gt;
&lt;p&gt;When LINQ was first released with .NET Framework 3.5, MSDN describes it as:&lt;/p&gt;
&lt;p&gt;LINQ is one of Microsoft’s most exciting, powerful new development technologies.&lt;/p&gt;
&lt;p&gt;Traditionally, to work with a specific data domain, a domain specific language and a set of domain specific APIs are used. For example, the following example is equivalent to above LINQ to XML query logic, implemented in traditional programming model, which calls XML APIs to execute query expression in XPath language:&lt;/p&gt;
&lt;p&gt;internal static void Xml()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathDocument feed = new XPathDocument(&quot;https://weblogs.asp.net/dixin/rss&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathNavigator navigator = feed.CreateNavigator();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathExpression selectExpression = navigator.Compile(&quot;//item[guid/@isPermaLink=&apos;true&apos;]/title/text()&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathExpression sortExpression = navigator.Compile(&quot;../../pubDate/text()&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;selectExpression.AddSort(sortExpression, Comparer&amp;lt;DateTime&amp;gt;.Default);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;XPathNodeIterator nodes = navigator.Select(selectExpression);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (object node in nodes)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(node);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For SQL database, the traditional programming model implements the above LINQ to Entities query logic by calling ADO.NET data access APIs to execute query statement in SQL language:&lt;/p&gt;
&lt;p&gt;internal static void Sql(string connectionString)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbConnection connection = new SqlConnection(connectionString))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbCommand command = connection.CreateCommand())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.CommandText =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@&quot;SELECT [Product].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FROM [Production].[Product] AS [Product]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Subcategory]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ON [Subcategory].[ProductSubcategoryID] = [Product].[ProductSubcategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;LEFT OUTER JOIN [Production].[ProductCategory] AS [Category]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ON [Category].[ProductCategoryID] = [Subcategory].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;WHERE [Category].[Name] = @categoryName
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ORDER BY [Product].[ListPrice] DESC&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DbParameter parameter = command.CreateParameter();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.ParameterName = &quot;@categoryName&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;parameter.Value = &quot;Bikes&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;command.Parameters.Add(parameter);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;connection.Open();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;using (DbDataReader reader = command.ExecuteReader())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;while (reader.Read())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;string productName = (string)reader[&quot;Name&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(productName);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Similarly, for Twitter data, there are network APIs to query Twitter’s REST endpoints, etc. LINQ implements a unified and consistent language syntax and programming model for many different data domains. Above examples demonstrated the same C# syntax builds filter-sort-map query flows for .NET objects, XML data, cached tabular data, SQL database, NoSQL database, JSON, Twitter data. This capability makes LINQ a powerful and productive solution for working with data.&lt;/p&gt;
&lt;p&gt;C# is a strongly typed language. In C#, any value has a type, including any value in LINQ query. And any expression is evaluated to a type, including LINQ query expressions. Any method has a type for each parameter and a type for return value, including LINQ query methods. So, LINQ queries are checked by compiler and runtime for type safety, which is great help for productivity, unless dynamic typing is used to bypass the compiler check:&lt;/p&gt;
&lt;p&gt;internal static void Dynamic()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;dynamic&amp;gt; query =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from dynamic value in source
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where value.ByPass.Compiler.Check &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby value.ByPass().Compiler().Check()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select value &amp;amp; new object(); // Define query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (dynamic result in query) // Execute query.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Strong typing also enables IntelliSense for tools, which also improves the productivity:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image006%5B4%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-3-Infrastructure_F6C4/clip_image006%5B4%5D_thumb.gif&quot; alt=&quot;clip_image006[4]&quot; title=&quot;clip_image006[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LINQ also supports deferred execution. Usually, LINQ query is executed only when the results are pulled from the query. This enables creating query with arbitrary complexity. In above examples, during the composition of filter-sort-map, no execution is triggered. Later, when the results are pulled, the entire filter-sort-map query executes is triggered. This is also important for productivity. Take above LINQ to Entities query as example, when the query is executed against the SQL database, the entire filter-sort-map query logic is submitted to database as a single database query.&lt;/p&gt;
&lt;p&gt;LINQ is not only about data query. Many LINQ libraries provide rich APIs to manipulate and change the data, like LINQ to XML, LINQ to SQL, and EF Core, and LINQ to NoSQL, etc. Parallel LINQ is a special set of LINQ APIs, it can significantly improve the query performance for .NET objects, it also provides a simple programming model for general parallel computing.&lt;/p&gt;
&lt;h3&gt;Local query vs. remote query&lt;/h3&gt;
&lt;p&gt;Generally, there are 2 kinds of LINQ technologies:&lt;/p&gt;
&lt;p&gt;· Local query: The data source for local query is .NET objects in local memory of current .NET application or service. Apparently, (sequential) LINQ to Objects queries, and Parallel LINQ (to Objects) queries are local queries. LINQ to XML have XML data loaded to memory as specialized .NET objects representing the XML data structure, then query these objects, so LINQ to XML queries are also local queries too. Similarly, LINQ to DataSets and LINQ to JSON queries are local queries too. As demonstrated above, the local sequential LINQ data source and query is represented by System.Collections.Generics.IEnumerable&amp;lt;T&amp;gt; interface, and the local parallel LINQ data source and query is represented by System.Linq.ParallelQuery&amp;lt;T&amp;gt; type.&lt;/p&gt;
&lt;p&gt;· Remote query: The data source for remote query is not in the local memory. For example, LINQ to Entities queries the data stored in a relational database, apparently the data source is not available as .NET objects in the memory of current .NET application or service. So, LINQ to Entities queries are remote queries. So are LINQ to SQL, LINQ to DocumentDB and LINQ to Twitter. As demonstrated above, the remote LINQ data source and query is represented by System.Linq.IQueryable&amp;lt;T&amp;gt; interface.&lt;/p&gt;
&lt;p&gt;There are so many LINQ technologies, it is infeasible and also unnecessary to have one book for all of them. This book covers C# language&apos;s LINQ features, and the most used LINQ APIs: LINQ to Object (sequential local queries), LINQ to XML (specialized local queries), Parallel LINQ (parallel local queries), as well as EF/Core (remote queries). With the unified and consistent LINQ programming model, mastering these LINQ knowledge enables developers working any other local or remote LINQ technologies, understanding the internal implementation of these LINQ technologies also enables developer to build custom LINQ APIs to for other local or remote data scenarios.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter introduces the brief history and basic concept of .NET, C#, .NET Standard, and demonstrate how to setup tools to start coding on Windows, macOS, and Linux. It also introduces programming paradigms, and explains what is declarative/functional programming by comparing to imperative/object-oriented programming. It also explains what is LINQ, and how LINQ works with many different data domains with a unified programming model. The next chapter discusses more concepts of C# programming and give a overview of C#’s basic syntax used through this book.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (2) Programming Paradigms and Functional Programming</title><link>https://dixin.github.io/posts/introducing-linq-3-what-is-functional-programming/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-3-what-is-functional-programming/</guid><description>Object-oriented programming and functional programming are programming paradigms. A programming paradigm is a fundamental style or approach of programming. Paradigms are not mutually exclusive. It is</description><pubDate>Tue, 28 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;Object-oriented programming and functional programming are programming paradigms. A programming paradigm is a fundamental style or approach of programming. Paradigms are not mutually exclusive. It is common for one programming language to support multiple paradigms, and C# is such a language.&lt;/p&gt;
&lt;h3&gt;Programming paradigms&lt;/h3&gt;
&lt;p&gt;There are many programming paradigms. The following list shows a few common paradigms and their subparadigms:&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Declarative_programming&quot;&gt;Declarative programming:&lt;/a&gt; designs what is the logic of operations, without describing its control flow (SQL, XQuery, etc.)&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://en.wikipedia.org/wiki/Functional_programming&quot;&gt;Functional programming&lt;/a&gt;: uses expressions to describe operations, which are treated as call of functions (Erlang, F#, etc.)&lt;/p&gt;
&lt;p&gt;§ &lt;a href=&quot;https://en.wikipedia.org/wiki/Purely_functional_programming&quot;&gt;Purely functional programming&lt;/a&gt;: does not rely on mutable state (Haskell, Clean, etc.)&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://en.wikipedia.org/wiki/Logic_programming&quot;&gt;Logic programming&lt;/a&gt;: designs the program with facts and rules in logical form (Prolog, Datalog, etc.)&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_programming_language&quot;&gt;Dynamic programming&lt;/a&gt;: executes compile time behaviors at runtime (Python, PHP, etc.)&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Event-driven_programming&quot;&gt;Event-driven programming&lt;/a&gt;: drives the operations with events (JavaScript, TypeScript, etc.)&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Generic_programming&quot;&gt;Generic programming&lt;/a&gt;: supports type parameters for data structures and operations (Swift, VB.NET, etc.)&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Imperative_programming&quot;&gt;Imperative programming:&lt;/a&gt; uses commands/statements to specify how the program operates (Assembly language, Fortran, etc.)&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;Object-oriented programming:&lt;/a&gt; designs the program in objects, containing data in the form of fields, and behaviors in the form of methods&lt;/p&gt;
&lt;p&gt;§ &lt;a href=&quot;https://en.wikipedia.org/wiki/Class-based_programming&quot;&gt;Class-based programming&lt;/a&gt;: defines the data structure and behaviors as classes, and implements inheritance for classes (C++, Java, etc.)&lt;/p&gt;
&lt;p&gt;§ &lt;a href=&quot;https://en.wikipedia.org/wiki/Prototype-based_programming&quot;&gt;Prototype-based programming&lt;/a&gt;: implements classless prototypal inheritance and behavior reuse (Self, Lua, etc.)&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://en.wikipedia.org/wiki/Procedural_programming&quot;&gt;Procedural programming&lt;/a&gt;: designs program in procedures and sub-procedures (C, Pascal, etc.)&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://en.wikipedia.org/wiki/Metaprogramming&quot;&gt;Metaprogramming&lt;/a&gt;: accesses program code as data (Lisp, Ruby, etc.)&lt;/p&gt;
&lt;p&gt;o &lt;a href=&quot;https://en.wikipedia.org/wiki/Reflection_(computer_programming)&quot;&gt;Reflective programming&lt;/a&gt;: accesses the structure and behavior of the program itself at runtime (Delphi, Go, etc.)&lt;/p&gt;
&lt;p&gt;C# is a sophisticated language with a lot of language features. Following the above paradigm descriptions, C# is declarative (C# has attribute, etc.), dynamic (has dynamic type), functional (has first class function), event-driven (has event), generic (supports generics), imperative (has statement, control flow), object-oriented (has first class object), class-based (has class), and can be procedural (with static method). C# also supports metaprogramming (supports code DOM, expression tree, CIL emit, compiler as a service) and is reflective (supports reflection).&lt;/p&gt;
&lt;p&gt;So how functional is C#? C#’s initial release supports important functional features, and since then Microsoft keeps adding many more functional features to C# in each release, from small functional syntactic sugar for convenience to prominent functional features like LINQ:&lt;/p&gt;
&lt;p&gt;· C# 1.0: delegate, higher-order function&lt;/p&gt;
&lt;p&gt;· C# 2.0: generic delegate, anonymous method, closure, covariance and contravariance&lt;/p&gt;
&lt;p&gt;· C# 3.0: extension method, lambda expression, LINQ query expression&lt;/p&gt;
&lt;p&gt;· C# 4.0: covariance and contravariance for generics&lt;/p&gt;
&lt;p&gt;· C# 5.0: asynchronous function&lt;/p&gt;
&lt;p&gt;· C# 6.0: expression-bodied function members&lt;/p&gt;
&lt;p&gt;· C# 7.0-7.3: local function, tuple, pattern matching, more expression-bodied members&lt;/p&gt;
&lt;p&gt;So that C# has been a very functional language. All these language features are discussed in detail in each aspect of functional programming.&lt;/p&gt;
&lt;p&gt;C# supports data mutation and state change by default, so C# is not a purely functional language. However, C# has plenty of features for immutability, laziness, etc., which helps writing elegant purely functional code. And in libraries provided by Microsoft, almost every LINQ API works in a purely functional way. These features are also discussed in detail too.&lt;/p&gt;
&lt;p&gt;The topics of object-oriented programming (encapsulation, inheritance, polymorphism), dynamic programming (the dynamic type), and procedural programming (C-style procedures) are out of the scope of this book. C# event is discussed from a functional programming perspective. C# generics is very important feature for daily usage, and LINQ is entirely built with generics, so generic type, generic method, generic variants are discussed in detail. Metaprogramming with expression tree is also discussed in the LINQ to Entities internals chapter.&lt;/p&gt;
&lt;h3&gt;Imperative programming vs. declarative programming&lt;/h3&gt;
&lt;p&gt;Functional programming is declarative, which means it focus on expressing what to do; Object-oriented programming is imperative, which means it specifies the detailed commands and steps of how to do. To compare these 2 paradigms, a task can be implemented to query the delegate types from the .NET core library:&lt;/p&gt;
&lt;p&gt;· filter all the types to get delegate types&lt;/p&gt;
&lt;p&gt;· group the delegate types by their namespaces&lt;/p&gt;
&lt;p&gt;· sort the groups by each group’s delegate type count in descending order, and if 2 groups have identical delegate type count, then sort them by namespace in ascending order&lt;/p&gt;
&lt;p&gt;The following example implements this query with traditional C# imperative programming:&lt;/p&gt;
&lt;p&gt;internal static void DelegateTypes()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly coreLibrary = typeof(object).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Type&amp;gt; allTypes = coreLibrary.ExportedTypes;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Filter delegate types from all types, and group them by namespace.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; delegateGroups = new Dictionary&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Type type in allTypes)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Delegate type&apos;s base type is System.MulticastDelegate.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (type.BaseType == typeof(MulticastDelegate))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (!delegateGroups.TryGetValue(type.Namespace, out List&amp;lt;Type&amp;gt; delegateGroup))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;delegateGroup = delegateGroups[type.Namespace] = new List&amp;lt;Type&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;delegateGroup.Add(type);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sort delegate type groups by count (descending), and then by namespace (ascending).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;&amp;gt; sortedDelegateGroups =new List&amp;lt;KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; nextGroup in delegateGroups)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;for (int index = 0; index &amp;lt;= sortedDelegateGroups.Count; index++)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (index &amp;lt; sortedDelegateGroups.Count)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; currentGroup = sortedDelegateGroups[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int compare = currentGroup.Value.Count - nextGroup.Value.Count;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (compare == 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;compare = string.CompareOrdinal(nextGroup.Key, currentGroup.Key);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (compare &amp;gt;= 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;continue;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sortedDelegateGroups.Insert(index, nextGroup);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;break;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Output the results.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; delegateGroup in sortedDelegateGroups)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(delegateGroup.Value.Count + &quot; in &quot; + delegateGroup.Key + &quot;:&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Type delegateType in delegateGroup.Value)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(&quot; &quot; + delegateType.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(Environment.NewLine);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 27 in System: Action`1 Action Action`2 Action`3 Action`4 Func`1 Func`2 Func`3 Func`4 Func`5 Action`5 Action`6 Action`7 Action`8 Func`6 Func`7 Func`8 Func`9 Comparison`1 Converter`2 Predicate`1 AssemblyLoadEventHandler AsyncCallback EventHandler EventHandler`1 ResolveEventHandler UnhandledExceptionEventHandler
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 8 in System.Threading: WaitCallback WaitOrTimerCallback IOCompletionCallback TimerCallback ContextCallback ParameterizedThreadStart SendOrPostCallback ThreadStart
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 3 in System.Reflection: MemberFilter ModuleResolveEventHandler TypeFilter
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 3 in System.Runtime.CompilerServices: TryCode CleanupCode CreateValueCallback
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The following example is implemented with LINQ, which is totally declarative:&lt;/p&gt;
&lt;p&gt;internal static void DelegateTypesWithQueryExpression()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly coreLibrary = typeof(object).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Type&amp;gt;&amp;gt; delegateGroups =
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;from type in coreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;where type.BaseType == typeof(MulticastDelegate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;group type by type.Namespace into delegateGroup
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;orderby delegateGroup.Count() descending, delegateGroup.Key
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;select delegateGroup;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;string, Type&amp;gt; delegateGroup in delegateGroups) // Output.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(delegateGroup.Count() + &quot; in &quot; + delegateGroup.Key + &quot;:&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Type delegateType in delegateGroup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(&quot; &quot; + delegateType.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(Environment.NewLine);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;So imperative programming and declarative programming are very different styles and approaches. The imperative example specifies how to accomplish the task step by step:&lt;/p&gt;
&lt;p&gt;· How to filter and group: use a dictionary of key value pairs to store the grouped delegate types, where each key is namespace, and each value is a list of delegate types under that namespace; Scan the types, if a type is a delegate type, then check whether its namespace is in dictionary as a key, if yes, get its type list, if not, add a key value pair to the dictionary, where key is the namespace, and value is an empty list of types; then add the delegate type to the existing or newly added type list.&lt;/p&gt;
&lt;p&gt;· How to sort: copy each group from the dictionary to another sorted list. For each group, scan the groups already in the sorted list to compare delegate type counts, if equal then compare their namespaces; When the right position is found, insert each group to the sorted list.&lt;/p&gt;
&lt;p&gt;The code here is a detailed control flow of statements and commands, including frequent data mutation (variables’ reassignment) and state change (collections’ item change). The business logic is less intuitive in the code.&lt;/p&gt;
&lt;p&gt;The other example simply declares what is the task to accomplish:&lt;/p&gt;
&lt;p&gt;· what is filtering logic: keep delegate types&lt;/p&gt;
&lt;p&gt;· what is grouping logic: group delegate types by namespaces&lt;/p&gt;
&lt;p&gt;· what is sorting logic: sort the groups in descending order of delegate type count, then in ascending order of namespace&lt;/p&gt;
&lt;p&gt;Here an expression of clauses makes the business logic very clear. And there are no details needed, like data mutation or state change involved, at all.&lt;/p&gt;
&lt;p&gt;Imperative/object-oriented programming has a history to think from lower level up. In the early years, computer hardware’s implementation is usually imperative and stateful, so machine code is designed to be imperative and can change hardware state in a control flow. Then, low level programming languages are designed, which usually have strong correspondence to the machine code with a little or no abstractions, so they are also imperative and stateful, like assembly language. Later, higher level programming languages are designed as abstraction of low level languages and usually more portable, but they are still imperative and stateful. For example, C is the abstractions of assembly languages, C++ was initially called C with Classes and designed as extension of C. C# is also rooted in C family of high level languages to make itself immediately familiar to programmers of C, C++, and Java, etc., so C# is imperative and stateful by default as well. Actually, Microsoft used to call it Cool, stood for C-like Object Oriented Language. Many of its elements, like int (System.Int32), long (System.Int64), flow control, etc., are abstracted all the way from hardware.&lt;/p&gt;
&lt;p&gt;In contrast, declarative/functional programming is to think from higher level. It is usually abstractions of the mathematics and logic. The elements in above LINQ query, like where clause, group by clause, order by clause, etc., are such abstractions. It disregards the lower level details of how exactly the declared operations should be executed, like how to change state and how to mutate data, etc. In the next section, more examples demonstrates how this&lt;/p&gt;
&lt;p&gt;Eventually, computer hardware is imperative. So declarative/functional code usually needs to translated to imperative code to execute in hardware. This work is usually done by compilers at compile time, and API calls at runtime, so that at design time, the code is kept declarative and functional. Later, this book discusses how declarative and functional LINQ is internally implemented by C# compiler and query APIs.&lt;/p&gt;
&lt;p&gt;Besides functional programming and LINQ, C# and .NET Standards provide other declarative features and APIs. For example, attribute is widely used to associate declarative information with code elements, including assembly, module, type, type member, function parameter and return value. Regular expression APIs can be viewed as declarative, because it declares what pattern to match, not how to match. There are syntactic sugars like object initializer, collection initializer, etc., which make C# more declarative and less imperative. These are discussed in the C# language basics chapter.&lt;/p&gt;
&lt;h3&gt;Object-oriented programming vs. functional programming&lt;/h3&gt;
&lt;p&gt;In object-oriented programming, object can have behaviours in the form of method, comparing to function in functional programming, they are both modularized reusable code block. They are different in multiple aspects:&lt;/p&gt;
&lt;p&gt;· As fore mentioned, functional programming is more declarative. It encourages expression rather than statement, focuses on what to do, and avoids how to do, especially avoids how to mutate data or change state.&lt;/p&gt;
&lt;p&gt;· Function in functional programming is treated as first class citizen, just like first class object in object-oriented programming. For example, a function can be passed around like a data value, or used as input/output of another function.&lt;/p&gt;
&lt;p&gt;· Functional programming encourages pure function. First, pure function works like mathematics function that simply maps from a set of input to a set of output, and each certain input always leads to a certain output. In another word, a pure function’s output only depends on the input. This is different from object-oriented programming, where method’s execution result can commonly depend on local object’s state or global state. Second, pure function has no side effects, which means no interaction with the outside world of the function. For example, LINQ APIs use deferred execution to implement purity. This is also different from object-oriented programming, where method’s execution can commonly change local object’s state or global state, or produce I/O.&lt;/p&gt;
&lt;p&gt;· Functional programming also emphasizes function composition, rather than object inheritance/composition in object-oriented programming.&lt;/p&gt;
&lt;p&gt;In the previous example, LINQ query expression is actually implemented with the following function calls (In practice, LINQ code can be written with either syntax. They are totally equivalent. The previous query syntax is compiled to the following query, and the compilation is discussed in detail later):&lt;/p&gt;
&lt;p&gt;internal static void DelegateTypesWithQueryMethods()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Assembly coreLibrary = typeof(object).Assembly;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;IGrouping&amp;lt;string, Type&amp;gt;&amp;gt; delegateGroups = coreLibrary.ExportedTypes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.Where(type =&amp;gt; type.BaseType == typeof(MulticastDelegate))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.GroupBy(type =&amp;gt; type.Namespace)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.OrderByDescending(delegateGroup =&amp;gt; delegateGroup.Count())
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.ThenBy(delegateGroup =&amp;gt; delegateGroup.Key);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (IGrouping&amp;lt;string, Type&amp;gt; delegateGroup in delegateGroups) // Output.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(delegateGroup.Count() + &quot; in &quot; + delegateGroup.Key + &quot;:&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;foreach (Type delegateType in delegateGroup)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(&quot; &quot; + delegateType.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Trace.Write(Environment.NewLine);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Where, GroupBy, OrderBy, ThenBy are functions composed together by fluent chaining, each function’s output becomes the next function’s input. They are pure functions, so their output data only depends on the input data. They do not depend on any state, and do not change any state, which is implemented by deferred execution. They also accept an additional input, which is also a function. Each input function is defined on the fly without a function name. This is called anonymous function. Each anonymous function is passed to another function as argument, just like passing a data value. These input functions are also pure. The Where, GroupBy, OrderBy, ThenBy functions are called higher-order function, since they can have another function as input/output. Function composition, fluent chaining, pure function, deferred execution, anonymous function, higher-order function and first class function are discussed in detail later.&lt;/p&gt;
&lt;p&gt;To further demonstrate, a task can be implemented to process document:&lt;/p&gt;
&lt;p&gt;· Download a source file from the specified URI&lt;/p&gt;
&lt;p&gt;· Convert the source file to another format with the specified template file.&lt;/p&gt;
&lt;p&gt;The following example designs the task with object-oriented paradigm:&lt;/p&gt;
&lt;p&gt;internal class Crawler&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly DirectoryInfo downloadDirectory;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Crawler(DirectoryInfo downloadDirectory)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.downloadDirectory = downloadDirectory;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Download the specified URI to the download directory.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FileInfo Download(Uri sourceUri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotImplementedException();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class Template
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly FileInfo templateFile;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal Template(FileInfo templateFilerr
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.templateFile = templateFile;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Convert the specified HTML document with template.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FileInfo Convert(FileInfo sourceFile)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotImplementedException();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal class DocumentBuilder
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Crawler crawler;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;private readonly Template template;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal DocumentBuilder(Crawler crawler, Templatetemplate)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.crawler = crawler;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;this.template = template;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal FileInfo Build(Uri uri)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo htmlDocument = this.crawler.Download(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return this.template.Convert(htmlDocument);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The above Crawler class provides the operation to download the document to a directory. Template class provides the operation to convert a document with template. To focus on the paradigm, the implementations are omitted. To build the document, DocumentBuilder class is defined to compose crawler and template. The following code demonstrates how the task can be done using instances of above classes:&lt;/p&gt;
&lt;p&gt;internal static void BuildDocument(Uri sourceUri, DirectoryInfo downloadDirectory, FileInfo templateFile)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;DocumentBuilder builder = new DocumentBuilder(new Crawler(downloadDirectory), new Template(templateFile));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo resultFile = builder.Build(sourceUri);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In functional paradigm, each operation can be simply modelled as a function, and functions can be composed:&lt;/p&gt;
&lt;p&gt;internal static FileInfo Download(Uri sourceUri, DirectoryInfo downloadDirectory)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotImplementedException();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static FileInfo Convert(FileInfo sourceFile, FileInfo templateFile)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;throw new NotImplementedException();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;internal static Func&amp;lt;Uri, DirectoryInfo, FileInfo, FileInfo&amp;gt; CreateDocumentBuilder(
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Uri, DirectoryInfo, FileInfo&amp;gt; download, Func&amp;lt;FileInfo, FileInfo, FileInfo&amp;gt; convert)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return (sourceUri, downloadDirectory, templateFile) =&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo sourceFile = download(sourceUri, downloadDirectory);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;return convert(sourceFile, templateFile);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is how the task can be done using above functions:&lt;/p&gt;
&lt;p&gt;internal static void BuildDocument(Uri sourceUri, DirectoryInfo downloadDirectory, FileInfo templateFile)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Uri, DirectoryInfo, FileInfo, FileInfo&amp;gt; buildDocument = CreateDocumentBuilder(Download, Convert);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;FileInfo resultFile = buildDocument(sourceUri, downloadDirectory, templateFile);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Here CreateDocumentBuilder function is called with Download and Convert as input, and it outputs another function, which is a composition of Download and Convert. These function are passed just like passing data values. This also demonstrates in C# functions are first class citizens.&lt;/p&gt;
&lt;p&gt;Many C# functional programming features are relatively younger than its imperative/object-oriented features. Some major features, like lambda expression, query expression, are introduced to C# since 3.0. However, functional programming as is actually a very old fashion. Functional programming came from lambda calculus, which was invented in 1930s. The first functional programming language, Lisp, was designed in 1950s. Lisp is the second oldest high-level programming language still widely used today. It is only 1 year younger than Fortran, an imperative programming language still widely used. Another example is LINQ query expression. It is rooted in monad, a concept of category theory. Category theory was started in 1940s, and monad was introduced into category theory in 1950s. Later monad programming appeared in Opal language in 1980s. Since 1990s it has been heavily used in Haskell language. Lambda calculus and category theory are discussed in detail in part 3, since they are the rationale and foundations of functional programming and LINQ.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (1) Cross Platform C# and .NET</title><link>https://dixin.github.io/posts/linq-via-csharp-introduction/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-via-csharp-introduction/</guid><description>C# is a functional and object-oriented programming language built by Microsoft. C# works with a family of programming frameworks crossing many platforms and devices. C# has been used by millions of pe</description><pubDate>Tue, 07 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;C# is a functional and object-oriented programming language built by Microsoft. C# works with a family of programming frameworks crossing many platforms and devices. C# has been used by millions of people to build applications, services, mobile apps, and games, etc.&lt;/p&gt;
&lt;p&gt;This is a latest and cross-platform C# programming book focusing on functional programming and LINQ data access, covering the concepts, practical usage, internal design and underlying theories.&lt;/p&gt;
&lt;p&gt;This chapter introduces the basic concepts for readers who are new to .NET and C# language, and who want to catch up with the latest status. It then demonstrates how to setup coding tools on Windows, macOS and Linux, and finally gives an overview of functional programming and LINQ programming with C#.&lt;/p&gt;
&lt;h2&gt;Introducing cross-platform .NET, C# and LINQ&lt;/h2&gt;
&lt;p&gt;In 2002, C# 1.0 was initially released along with .NET Framework 1.0 on Windows platform. Since then, many functional features including LINQ has been built into C# language and .NET Framework. There are also multiple frameworks joined the .NET family, which enable C# and LINQ to work cross different platforms.&lt;/p&gt;
&lt;h3&gt;.NET Framework, C#, and LINQ&lt;/h3&gt;
&lt;p&gt;Microsoft .NET (pronounced “dot net”) Framework is a free development framework on Windows, widely used to build applications and services with simple programming model and good productivity. .NET Framework is based on Common Intermediate Language (CIL), an object-oriented assembly language. It mainly consists of Framework Class Library (FCL) and Common Language Runtime (CLR):&lt;/p&gt;
&lt;p&gt;· FCL is a set of built-in libraries of rich APIs implemented as classes, interfaces, and structures, etc. It is the fundamental used by .NET applications and services to access system functionality. FCL provides primitive types, exceptions, collections, I/O, threading, reflection, text processing, database access, and LINQ queries, etc.&lt;/p&gt;
&lt;p&gt;· CLR is the runtime environment that works like a virtual machine. All .NET applications and services are executed by CLR. CLR provides features including &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/f144e03t.aspx&quot;&gt;automatic memory management&lt;/a&gt;, thread management, structured exception handling, type safety, security, just-in-time (JIT) compiler, etc.&lt;/p&gt;
&lt;p&gt;C# language (pronounced “c sharp”) is a general purpose high level language designed for .NET Framework. It is type-safe, generic, component-based, object-oriented and functional. It was standardized as ECMA 334 in 2002 and approved as ISO/IEC 23270 in 2003. Microsoft’s C# compiler is an implementation of these standards. It compiles C# code to CIL code, so that the CIL code is JIT-compiled to machine code by CLR, and the machine code is executed by CLR.&lt;/p&gt;
&lt;p&gt;Besides C#, there are multiple high level languages supported by .NET Framework, like VB.NET, F#, etc., all of which are compiled or interpreted to CIL. C# is the most popular .NET language used by millions of people, according to Microsoft. Microsoft provides an ecosystem of tools for .NET software development, the flagship integrated development environment (IDE) is Visual Studio.&lt;/p&gt;
&lt;p&gt;C# is designed to be an object-oriented programming language from the beginning, so that C# works seamlessly with object-oriented CIL of .NET Frameowrk, and many developers could easily get familiar with C#. C# started to have functional features in the initial release. Since then a lot of functional features has been built into the language. Function is first class citizen in C#, just like object. Now with the latest 7.3 release, it is easy and smooth to use C# for elegant and robust functional programming.&lt;/p&gt;
&lt;p&gt;The real-world programs work with data in many different forms, like data objects in local memory, data in XML format, data stored in cloud database, etc. Traditionally, a specific programming model is required to work with each data format. For example, traditionally, querying a sequence of data objects in local memory can be very different from querying data rows from database table. For .NET languages and .NET Framework, Microsoft provides a unified functional programming model to query different data sources, that is LINQ (pronounced “link”), standing for “Language-INtegrated Query”. LINQ consists of language syntax and library APIs:&lt;/p&gt;
&lt;p&gt;· New keywords and new syntax are introduced to the .NET languages. C# has got important functional language features, including extension methods, lambda expression, query expression, etc.&lt;/p&gt;
&lt;p&gt;· New APIs are implemented in .NET FCL, including interfaces and classes to represent the data sources, query methods to implement the query logic, etc.&lt;/p&gt;
&lt;p&gt;Microsoft implements LINQ syntax in .NET languages like C#, VB.NET, F#, as well as LINQ APIs in FCL to work with .NET objects, XML data, and database. At compile time, LINQ data queries written in native language keywords and syntax are compiled to regular calls of LINQ APIs; At runtime, the LINQ API calls are executed by CLR to get the work done with the specified data sources. The model of LINQ is extensible. The language syntax can work both built-in FCL APIs and custom APIs, which enables LINQ working with many data sources.&lt;/p&gt;
&lt;p&gt;LINQ is rooted in Microsoft&apos;s Cω research project and was initially released as a part of .NET Framework 3.5 and C# 3.0. The following table shows the position of LINQ in the historic roadmap of .NET Framework and C# language:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-padding-alt: 0in 0in 0in 0in; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium 1pt; border-style: solid none none solid; border-color: windowtext currentcolor currentcolor windowtext; padding: 0in; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Date&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Visual Studio&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Framework&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Framework features&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt medium medium; border-style: solid none none; border-color: windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-top-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;CLR&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt medium medium; border-style: solid solid none none; border-color: windowtext windowtext currentcolor currentcolor; padding: 0in; mso-border-top-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;C#&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Feb &amp;lt;/span&amp;gt;2002&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET 2002&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;CLR, FCL, ASP.NET, etc&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;1.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Apr &amp;lt;/span&amp;gt;2003&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET 2003&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;IPv6, Oracle database, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in; mso-fareast-language: zh-cn;&quot;&amp;gt;Apr&amp;lt;/span&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt; &amp;lt;/span&amp;gt;2003&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;1.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Nov &amp;lt;/span&amp;gt;2005&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2005&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Generics, full &amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;64-bit&amp;lt;/span&amp;gt; computing, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;2.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Nov &amp;lt;/span&amp;gt;2006&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;3.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;WCF, WPF, WF, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Nov &amp;lt;/span&amp;gt;2007&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2008&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;3.5&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;LINQ, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;3.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Apr &amp;lt;/span&amp;gt;2010&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2010&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;TPL, Parallel LINQ, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4 (&amp;lt;a href=&quot;https://msdn.microsoft.com/en-us/library/8bs2ecf4.aspx&quot; target=&quot;_blank&quot;&amp;gt;not “4.0”&amp;lt;/a&amp;gt;)&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;4.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Aug &amp;lt;/span&amp;gt;2012&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2012&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.5&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Zip, Parallel LINQ improvement, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;5.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Oct &amp;lt;/span&amp;gt;2013&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2013&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.5.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Automatic binding redirection, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;May &amp;lt;/span&amp;gt;2014&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.5.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;New ASP.NET APIs, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Jul &amp;lt;/span&amp;gt;2015&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2015&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.6&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;New 64-bit JIT compiler, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;6.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 12;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Nov &amp;lt;/span&amp;gt;2015&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.6.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET Standard 2.0 support with additional files, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 13;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Aug &amp;lt;/span&amp;gt;2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.6.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;SQL Server client improvement, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 14;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Mar &amp;lt;/span&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;7.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 15;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Apr &amp;lt;/span&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.7&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Azure SQL Database improvement, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 16;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Aug &amp;lt;/span&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;7.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 17;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Oct &amp;lt;/span&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;4.7.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;a href=&quot;https://github.com/dotnet/announcements/issues/32&quot; target=&quot;_blank&quot;&amp;gt;Built-in&amp;lt;/a&amp;gt; .NET Standard 2.0 support, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 18;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Nov &amp;lt;/span&amp;gt;2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;7.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 19;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium medium 1pt; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-left-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Apr 2018&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;4.7.2&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Cryptography improvement, etc.&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;padding: 0in; border: currentcolor; border-image: none;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt medium medium; border-style: none solid none none; border-color: currentcolor windowtext currentcolor currentcolor; padding: 0in; border-image: none; mso-border-right-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 20; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt 1pt; border-style: none none solid solid; border-color: currentcolor currentcolor windowtext windowtext; padding: 0in; mso-border-left-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;60&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;May 2017&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;72&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;240&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium medium 1pt; border-style: none none solid; border-color: currentcolor currentcolor windowtext; padding: 0in; border-image: none; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor windowtext windowtext currentcolor; padding: 0in; mso-border-right-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext .5pt;&quot; valign=&quot;top&quot; width=&quot;32&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;7.3&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;.NET Core, UWP, Mono, Xamarin and Unity&lt;/h3&gt;
&lt;p&gt;After the evolution of 15+ years, .NET Framework has been a rich and mature ecosystem on Windows. Besides .NET Framework, C# also works with multiple other frameworks on many platforms. In 2016, Microsoft released .NET Core, a free, open source and cross-platform version of .NET Framework. .NET Core is essentially a fork a .NET Framework. It is also based on CIL, with class libraries called CoreFX and a runtime called CoreCLR. .NET Core supports the same C# language, as well as fore mentioned F# and VB.NET. As the name suggests, .NET Core implements the core features of .NET Framework. So, it can be viewed as a subset of .NET Framework. It is designed to be a lightweight and high-performance framework to build applications and services on Windows, macOS, and many Linux distributions, including Read Hat, Ubuntu, CentOS, Debian, Fedora, OpenSUSE, Oracle Linux, etc., so that it works on a wide range of devices, clouds, and embedded/IoT scenarios. The following table shows .NET Core is released in much more agile iterations:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Date&amp;lt;/span&amp;gt;&amp;lt;span style=&quot;mso-fareast-font-family: 宋体;&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Core&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Features&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Jun 2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;CoreCLR, CoreFX, WCF, ASP.NET Core, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Sep 2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Oct 2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Nov 2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;More APIs, performance improvements, &amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;bug fixes, including the fix for a bug found by me when writing this book.&amp;lt;/span&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Dec 2016&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.3&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 6;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Mar 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.4/1.1.1&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 7;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;May 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.5/1.1.2&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 8;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Aug 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2.0&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;.NET Standard 2.0, performance improvement, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 9;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Sep 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.6/1.1.3&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 10;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Nov 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.7/1.1.4&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 11;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Nov 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.8/1.1.5/2.0.3&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 12;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Dec 2017&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;2.0.4&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 2.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 13;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Jan 2018&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;1.0.9/1.1.6/2.0.5&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 14;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Mar 2018&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;1.0.10/1.1.7/2.0.6&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 15;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Apr 2018&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;1.0.11/1.1.8/2.0.7&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 16; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;May 2018&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;2.1&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;&amp;lt;span lang=&quot;EN-IN&quot; style=&quot;mso-ansi-language: en-in;&quot;&amp;gt;Performance improvement, API improvement, etc.&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Microsoft also released Universal Windows Platform (UWP), the app model for Windows 10. UWP supports C# (as well as VB.NET, C++, JavaScript) development of Microsoft Store app, that can work cross all Windows 10 device families, including PC, tablet, phone, Xbox, HoloLens, Surface Hub, IoT, etc. UWP takes advantage of .NET Core. In Debug mode, UWP app is compiled to CIL, and runs against CoreCLR. In Release mode, UWP app is compiled to native binaries for better performance, and runs against .NET Native runtime.&lt;/p&gt;
&lt;p&gt;Besides .NET Core and UWP, Mono (Monkey in Spanish) is another open source implementation of .NET Framework based on the ECMA standards for C# and CLR. Mono was initially released in 2004. It works cross many platforms, including Windows, macOS, most Linux distributions, BSD, Solaris, Android, iOS, and game consoles.&lt;/p&gt;
&lt;p&gt;Based on Mono, Xamarin is a framework for building native mobile app on Windows, Android and iOS with C#. Microsoft acquired Xamarin in 2016 and has made it open source, with free edition available.&lt;/p&gt;
&lt;p&gt;C# is also the language of Unity, a cross-platform game engine built by Unity Technologies. Unity also takes advantage of Mono to support C# games development on Windows, macOS, Linux, Android, iOS, and game consoles like Xbox, PlayStation, Wii, etc. Unity used to support UnityScript, a JavaScript-like language, and Boo language. Now UnityScript and Boo are being deprecated regarding the popularity of C#.&lt;/p&gt;
&lt;p&gt;The following table summarizes these frameworks’ languages, base API surface, runtime for managed code, supported application models and platforms:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Framework&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Core&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;UWP&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Xamarin&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Unity&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Languages&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;C#, VB.NET, F#, etc.&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;C#, F#, VB.NET&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;C#, VB.NET, C++, JavaScript&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;C#&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;C#, UnityScript (deprecated), Boo (deprecated)&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Base API surface&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET FCL&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;CoreFX&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Universal device family APIs&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Mono base libraries&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Mono base libraries&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Managed runtime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;CLR&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;CoreCLR&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;.NET Native runtime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Mono runtime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Mono runtime&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Application models&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows desktop applications and services&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Cross-platform services&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft Store apps&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Mobile apps&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Games&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 5; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Platforms&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows, macOS, Linux&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows, Android, iOS&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Windows, macOS, Linux, Android, iOS, game consoles&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;.NET Standard&lt;/h3&gt;
&lt;p&gt;As fore mentioned, C# has been standardized since its beginning. For years, the same C# language works on multiple frameworks, but each framework used to provide its own base API surface. Since 2016, Microsoft released .NET Standard specification to provide a consistent development experience, prevent the API fragmentation of different frameworks or platforms, and enable better code sharing. .NET Standard is a unified list of APIs, which should be implemented as base API surface by any framework in the .NET family. .NET Standard is represented by NuGet package NETStandard.Library, which has a reference assembly netstandard.dll. The latest major release of .NET Standard is 2.0. It has 32k+ APIs. It is supported since:&lt;/p&gt;
&lt;p&gt;· .NET Framework 4.6.1/4.6.2/4.7 (support with additional files), .NET Framework 4.7.1 (built-in support)&lt;/p&gt;
&lt;p&gt;· .NET Core 2.0&lt;/p&gt;
&lt;p&gt;· Mono 5.4&lt;/p&gt;
&lt;p&gt;· UWP 10.0.16299&lt;/p&gt;
&lt;p&gt;· Xamarin.Forms 2.4, Xamarin.Mac 3.8, Xamarin.Android 8.0, Xamarin.iOS 10.14&lt;/p&gt;
&lt;p&gt;· Unity 2018&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image002%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image002%5B9%5D_thumb.gif&quot; alt=&quot;clip_image002[9]&quot; title=&quot;clip_image002[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The standardization of both C# language and library APIs provides great experience and productivity. C# developers now can learn one language and one set of base APIs, then develop many kinds of applications working cross many platforms and devices:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoNormalTable&quot; style=&quot;border: currentcolor; border-image: none; border-collapse: collapse; mso-border-alt: solid black .75pt; mso-yfti-tbllook: 1184;&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 0; mso-yfti-firstrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;padding: 0.75pt; border: 1pt solid black; border-image: none; mso-border-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Framework&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;.NET Core&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;UWP&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Xamarin&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: 1pt 1pt 1pt medium; border-style: solid solid solid none; border-color: black black black currentcolor; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableHead&quot; style=&quot;margin: 3pt 0in; page-break-after: avoid;&quot;&amp;gt;Unity&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 1;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Language&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;5&quot; style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;C#&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 2;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Base API surface&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;5&quot; style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;.NET Standard&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 3;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Application models&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows desktop applications and services&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Cross-platform services&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Microsoft Store apps&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Mobile apps&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Games&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr style=&quot;mso-yfti-irow: 4; mso-yfti-lastrow: yes;&quot;&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt; border-style: none solid solid; border-color: currentcolor black black; padding: 0.75pt; border-image: none; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpFirst&quot; style=&quot;margin: 8pt 0in 0pt; line-height: 17pt;&quot;&amp;gt;Platforms&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows, macOS, Linux&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpMiddle&quot; style=&quot;margin: 0in 0in 0pt; line-height: 17pt;&quot;&amp;gt;Windows, Android, iOS&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td style=&quot;border-width: medium 1pt 1pt medium; border-style: none solid solid none; border-color: currentcolor black black currentcolor; padding: 0.75pt; mso-border-alt: solid black .75pt; mso-border-top-alt: solid black .75pt; mso-border-left-alt: solid black .75pt;&quot;&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;p class=&quot;TableTextCxSpLast&quot; style=&quot;margin: 0in 0in 8pt; line-height: 17pt;&quot;&amp;gt;Windows, macOS, Linux, Android, iOS, game consoles&amp;lt;/p&amp;gt;&amp;lt;font style=&quot;font-size: 12pt;&quot;&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;C#’s LINQ syntax is part of the language standard, and the core LINQ APIs are part of the .NET Standard. Microsoft also implemented other LINQ APIs, like LINQ to Entities with .NET Standard based library. So, LINQ is standardized too, and available on all frameworks in the .NET family. This book covers cross-platform LINQ technologies provided by Microsoft in great detail, including LINQ to Objects, LINQ to XML, Parallel LINQ, and LINQ to Entities.&lt;/p&gt;
&lt;h2&gt;Introducing this book&lt;/h2&gt;
&lt;p&gt;The goal of this book is to deliver latest, cross-platform, complete and in-depth knowledge on C# functional programming&lt;/p&gt;
&lt;p&gt;.NET Standard is an object-oriented collection of reusable types, CIL is a object-oriented assembly language, and C# is also initially an object-oriented programming language, fully supporting encapsulation, inheritance, and polymorphism, so that .NET APIs and C# language work together seamlessly. In the meanwhile, C# also supports functional programming. As a typical example, LINQ is extensively functional. In C#, functions are first class citizens just like objects are. C# has plenty of functional features, like closure, higher-order function, anonymous function, etc. The LINQ features, like query expressions, lambda expression, etc., are also functional features instead of object-oriented features.&lt;/p&gt;
&lt;p&gt;Functional programming is different from object-oriented programming in many aspects. Functional programming is usually more self-contained, more stateless, more immutable, more lazy, more side effects management, etc. The most intuitive difference is, functional programming is more declarative instead of imperative. It focus on describing what to do, instead of specifying the execution details of how to do. As a result, functional programming can be very expressive and productive. When working with data, as a typical example, functional LINQ queries provide the general capabilities of describing what is the query logic for different data source, rather than specifying the execution details of how todata access and query each specific data source, so that LINQ can be one powerful language to work with many data sources. Functional programming can also be more scalable. For example, when working with data using LINQ. As a C# book, it can be very easy to parallelize the workload multiple processor cores.&lt;/p&gt;
&lt;p&gt;In C# development, object-oriented programming and functional programming live in harmony. For example, when a functional LINQ query works with data in local memory, the LINQ query actually works with CLR objects which represent the data. Also, when a LINQ query is executed, LINQ APIs are called, and the LINQ APIs can be internally implemented with imperative object-oriented programming.&lt;/p&gt;
&lt;h2&gt;This tutorial&lt;/h2&gt;
&lt;p&gt;This tutorial discusses cross-platform functional programming and LINQ programming via the latest C# 7.0 language, from real world development to underlying theories. It covers both .NET Framework (for Windows) and .NET Core (for Windows, macOS and Linux). This entire tutorial is based on the latest C# 7.3 language and the latest .NET Standards 2.0 which is supported by all frameworks. in the .NET family crossing many platforms. It covers C#’sis a one-stop book on the subject, covering functional features and of C# language, aspects of functional programming aspects, and the detailed usage and internal mechanisms of mainstream LINQ technologies for different data domains, including LINQ to Objects, Parallel LINQ, LINQ to XML, and LINQ to Entities. It alsoIt is also an in-depth book that discusses internal mechanisms and demystifies the underlying quintessential theories of functional programming and LINQ, including Lambda Calculus and Category Theory.&lt;/p&gt;
&lt;h3&gt;As an in-depth tutorial, some Target readers&lt;/h3&gt;
&lt;p&gt;Some basic understanding of programming and basic concepts of C# language is necessary. to get started with this book. The target audiencesreaders are those who want to learn C# language from a functional perspective or learn functional programming for Windows development and cross-platform developmentwith C# language, and those who want to learnmaster how to use LINQ in C# to work with different data in applications and servicesdomains productively. This tutorialbook is also for advanced audiences who want to learn the quintessence of readers who are already have some experience in functional programming and LINQ, but want to learn the internal mechanisms or learn the mathematical theories to build a deep and generalsolid understanding, on functional programming and those who wantLINQ.&lt;/p&gt;
&lt;p&gt;After reading this book, you should be able to learn internal detailsmaster the concept and aspects, write cross-platform C# code in functional paradigm, use LINQ technologies to work with different data domains. With the knowledge of LINQ in order to internal mechanisms, you should be able use LINQ very effectively, and also be able to create your own LINQ APIs. And those quintessential theories not only build custom LINQ APIs or providersyou a very good understanding on C# functional programming and LINQ, but also greatly helps you understanding any other functional language.&lt;/p&gt;
&lt;h3&gt;Book structure&lt;/h3&gt;
&lt;p&gt;The contents31 chapters are organized as the following chaptersinto 3 distinct parts: code, data, and theories:&lt;/p&gt;
&lt;p&gt;· Part 1 Code - covers functional programming via C#, and fundamentals of LINQ.&lt;/p&gt;
&lt;p&gt;o Chapter 1CODE: Functional programming and LINQ paradigm&lt;/p&gt;
&lt;p&gt;§ What is LINQ, how LINQ uses language to work with many different data domains.&lt;/p&gt;
&lt;p&gt;· Programming paradigm, imperative vs. declarative programming, object-oriented vs. functional programmingand LINQ Paradigm.&lt;/p&gt;
&lt;p&gt;o Chapter 1-2 Getting started: Introduce the basic concepts of .NET, C#, LINQ, gives an overview of functional programming and LINQ programming for different data domains, and warms up the basic syntax of C# language.&lt;/p&gt;
&lt;p&gt;o Chapter 2 C#3-14 functional programming in-depth&lt;/p&gt;
&lt;p&gt;§ C# fundamentals for beginners.&lt;/p&gt;
&lt;p&gt;o C#: Aspects of functional programming via C#, including named function type, named/anonymous/, function polymorphism, local function, closure, function input/output, delegate, function group, lambda expression, higher-order function, currying, partial application, first class function, function. Function composition, LINQ query expression, covariance/contravariance, immutability, tuple, purity, asyncasynchronous function, pattern matching, etc., including how C# is processed at compile time and runtime.&lt;/p&gt;
&lt;p&gt;· Part 2 Data - covers how to use functionalDATA: Using Functional LINQ to workWork with different data domains in the real world, and how LINQ works internally.Data.&lt;/p&gt;
&lt;p&gt;o Chapter 315-18 LINQ to Objects&lt;/p&gt;
&lt;p&gt;§ : How to use functional LINQ queries to work with objects, covering all LINQ and Ix.&lt;/p&gt;
&lt;p&gt;o How built-in standard queries and queries in interactive extension, how the LINQ to Objects query methods are implemented internally, how to implement useful custom LINQ queries.&lt;/p&gt;
&lt;p&gt;o Chapter 419 LINQ to XML&lt;/p&gt;
&lt;p&gt;§ : How to modelingmodel XML data, andhow to use functional LINQ queries to work with XML data.&lt;/p&gt;
&lt;p&gt;o How, how to use the other LINQ to XML APIs to manipulate XML data.&lt;/p&gt;
&lt;p&gt;o Chapter 520-21 Parallel LINQ&lt;/p&gt;
&lt;p&gt;§ : How to use parallelized functional LINQ queries to work with objects.&lt;/p&gt;
&lt;p&gt;o Performance analysis for , internal partitioning, and parallel/sequential LINQ queries query performance.&lt;/p&gt;
&lt;p&gt;o Chapter 622-25 Entity Framework/ Core and LINQ to Entities&lt;/p&gt;
&lt;p&gt;§ : How to model database with object-relational mapping, and use functional LINQ queries to work with relational data in database.&lt;/p&gt;
&lt;p&gt;§ How, how the C# LINQ to Entities queries are implemented to work with database.&lt;/p&gt;
&lt;p&gt;o Howinternally translated and executed, how to change data in database, and handle concurrent conflicts.&lt;/p&gt;
&lt;p&gt;§ Performance tips and asynchrony.&lt;/p&gt;
&lt;p&gt;· Part 3 Theories - demystifies the abstract mathematics theories, which are the rationale and foundationsDemystifying the essentials of LINQFunctional Programming and functional programmingLINQ.&lt;/p&gt;
&lt;p&gt;o Chapter 726-28 Lambda Calculus via C#&lt;/p&gt;
&lt;p&gt;§ : Core concepts of lambda calculus, bound and free variables, reduction (α-conversion, β-reduction, η-conversion), etc.&lt;/p&gt;
&lt;p&gt;§ How to use lambda functions to represent values, data structures and computation, including Church Boolean, Church numbers, Church pair, Church list, and their operations.&lt;/p&gt;
&lt;p&gt;o Combinators and combinatory logic, including SKI combinator calculus, fixed point combinator for function recursion, etc.&lt;/p&gt;
&lt;p&gt;o Chapter 829-31 Category Theory via C#&lt;/p&gt;
&lt;p&gt;§ : Core concepts of category theory, including category, object, morphism, monoid, functor, natural transformation, applicative functor, monad, and their laws.&lt;/p&gt;
&lt;p&gt;§ How these concepts are applied in functional programming and LINQ.&lt;/p&gt;
&lt;p&gt;o How to manage I/O, state, exception handling, shared environment, logging, and continuation, etc., in functional programming.&lt;/p&gt;
&lt;p&gt;This tutorial delivers highly reusable knowledge:&lt;/p&gt;
&lt;p&gt;· It covers C# knowledge in detail, which can be generally used in any programming paradigms other than functional programming.&lt;/p&gt;
&lt;p&gt;· It is a cross platform tutorial, covering both .NET Framework for Windows and .NET Core for Windows, macOS, Linux&lt;/p&gt;
&lt;p&gt;· It delivers LINQ usage and implementation for mainstream data domains, which also enables developer to use the LINQ technologies for other data domains, or build custom LINQ APIs for specific data scenarios.&lt;/p&gt;
&lt;p&gt;· It also demystifies the abstract mathematics knowledge for functional programming, which applies to all functional languages, so it greatly helps understanding any other functional languages too.&lt;/p&gt;
&lt;h3&gt;Code examples&lt;/h3&gt;
&lt;p&gt;The code examples are in the latest C# 7.3 language and based on the latest .NET Standards 2.0. The Parallel LINQ chapters have examples involving .NET Framework just for visualization purpose.&lt;/p&gt;
&lt;p&gt;To make the code examples intuitive, explicit type is always used instead of var; in practice, you can decide which to use accordingly. To save the space and focus on the problems, namespace declaration and using statements are usually omitted in the code examples. For the same purpose, function’s argument null check is omitted by all code examples, in practice you should have null check as needed.&lt;/p&gt;
&lt;p&gt;All code examples are available on GitHub: https://github.com/Dixin/Tutorial. If there is any issue, please feel free to file it hereat: https://github.com/Dixin/Tutorial/issues/new.&lt;/p&gt;
&lt;p&gt;To save the space and paper, all code examples in this tutorial omit argument null check.&lt;/p&gt;
&lt;h2&gt;Starting to code&lt;/h2&gt;
&lt;p&gt;All tools, libraries, services involvedused in this tutorialbook are either free, or withhaving free option available. In theory, any text editor can be used for C# programming, but a powerpowerful tools can greatly improve the productivity. The following are the free tools provided by Microsoft:&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx&quot;&gt;Visual Studio Community Edition&lt;/a&gt;: the free and fully featured Visual Studio for Windows, the powerful and productive is the flagship integrated development environment (IDE) for C#/.NET and other development# with .NET Core, .NET Framework, UWP, Xamarin, etc. Its Community Edition is free for induvial developers or open source projects.&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;:&lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/mac/&quot;&gt;Visual Studio for Mac&lt;/a&gt; Community Edition is the Visual Studio IDE available for macOS with the free Community Edition, supporting C# with .NET Core, Xamarin, etc.&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt; is a free and rich code editor for Windows, macOS and Linux, supporting codingwith full support of C# and other languages with extensionswith .NET Core, as well as limited support of C# with .NET Framework on Windows.&lt;/p&gt;
&lt;p&gt;· &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/mac/&quot;&gt;Visual Studio for Mac&lt;/a&gt;: the free and sophisticated IDE for macOS, supporting development of .NET Core, Xamarin, etc.&lt;/p&gt;
&lt;h3&gt;Start codingCoding with Visual Studio (Windows)&lt;/h3&gt;
&lt;p&gt;The free Community Edition of Visual Studio can be downloaded from the Microsoft official website: https://visualstudio.com. To start C# programming with .NET Core, selectStandard, the “.NET Core cross-platform development” workload; in the installer is recommended, since .NET Core is the most lightweight framework supporting .NET Standard. To start C# programming with .NET Framework on Windows, select the “.NET desktop development” workload:. Other frameworks like UWP, Xamarin, can also be selected if needed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image004%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image004%5B9%5D_thumb.gif&quot; alt=&quot;clip_image004[9]&quot; title=&quot;clip_image004[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image006%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image006%5B9%5D_thumb.gif&quot; alt=&quot;clip_image006[9]&quot; title=&quot;clip_image006[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This installs Visual Studio along with .NET Framework SDK/.NET Core SDK. To install the latest version of .NET Framework SDK/.NET Core SDK, follow the steps from the Microsoft official website: https://dot.net. After all installation&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image007%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image007%5B9%5D_thumb.gif&quot; alt=&quot;clip_image007[9]&quot; title=&quot;clip_image007[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image008%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image008%5B9%5D_thumb.gif&quot; alt=&quot;clip_image008[9]&quot; title=&quot;clip_image008[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Go ahead with the installation. When it is done, launch Visual Studio. For .NET Core, click File =&amp;gt; New =&amp;gt; Project to create a new console applicationapp under Visual C#, .NET Core:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image010%5B16%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image010%5B16%5D_thumb.gif&quot; alt=&quot;clip_image010[16]&quot; title=&quot;clip_image010[16]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image010%5B17%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image010%5B17%5D_thumb.gif&quot; alt=&quot;clip_image010[17]&quot; title=&quot;clip_image010[17]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Visual Studio’s Solution Explorer, under this application, there is a Program.cs file in this project, which has the application’sapp’s entry point Main:..&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace ConsoleApp
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;class Program
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(&quot;Hello World!&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Then right click the project, in the context menu click Properties. In the project property window, go to the Build tab, click the Advanced button, and change the languageLanguage version to latest:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image012%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image012%5B9%5D_thumb.gif&quot; alt=&quot;clip_image012[9]&quot; title=&quot;clip_image012[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image014%5B9%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image014%5B9%5D_thumb.jpg&quot; alt=&quot;clip_image014[9]&quot; title=&quot;clip_image014[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now right click the project again, in the context menu click “Manage NuGet Packages” to install the NuGet packages used in this tutorialbook:&lt;/p&gt;
&lt;p&gt;· FSharp.Core&lt;/p&gt;
&lt;p&gt;· linqtotwitter&lt;/p&gt;
&lt;p&gt;· Microsoft.Azure.DocumentDB.Core&lt;/p&gt;
&lt;p&gt;· Microsoft.EntityFrameworkCore.SqlServer&lt;/p&gt;
&lt;p&gt;· Microsoft.Extensions.Configuration.Json&lt;/p&gt;
&lt;p&gt;· Mono.Cecil&lt;/p&gt;
&lt;p&gt;· System.Interactive&lt;/p&gt;
&lt;p&gt;· System.Memory&lt;/p&gt;
&lt;p&gt;· System.Reflection.Emit.Lightweight&lt;/p&gt;
&lt;p&gt;· System.Threading.Tasks.Extensions&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image016%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image016%5B9%5D_thumb.gif&quot; alt=&quot;clip_image016[9]&quot; title=&quot;clip_image016[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image017%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image017%5B9%5D_thumb.gif&quot; alt=&quot;clip_image017[9]&quot; title=&quot;clip_image017[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For .NET Framework, create a console application ofapp under Visual WindowsC#, Windows classic desktop:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image019%5B16%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image019%5B16%5D_thumb.gif&quot; alt=&quot;clip_image019[16]&quot; title=&quot;clip_image019[16]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image019%5B17%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image019%5B17%5D_thumb.gif&quot; alt=&quot;clip_image019[17]&quot; title=&quot;clip_image019[17]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Change the language version to latest as well, and install the following packages:&lt;/p&gt;
&lt;p&gt;· ConcurrencyVisualizer&lt;/p&gt;
&lt;p&gt;· EntityFramework&lt;/p&gt;
&lt;p&gt;· FSharp.Core&lt;/p&gt;
&lt;p&gt;· linqtotwitter&lt;/p&gt;
&lt;p&gt;· Microsoft.Azure.DocumentDB&lt;/p&gt;
&lt;p&gt;· Microsoft.TeamFoundationServer.ExtendedClient&lt;/p&gt;
&lt;p&gt;· Mono.Cecil&lt;/p&gt;
&lt;p&gt;· System.Collections.Immutable&lt;/p&gt;
&lt;p&gt;· System.Interactive&lt;/p&gt;
&lt;p&gt;· System.Memory&lt;/p&gt;
&lt;p&gt;· System.Threading.Tasks.Extensions&lt;/p&gt;
&lt;p&gt;Then right click the created project’s References child node, in the context menu click Add Reference…, and add the following framework assemblies:&lt;/p&gt;
&lt;p&gt;· System.Configuration&lt;/p&gt;
&lt;p&gt;· System.Transactions&lt;/p&gt;
&lt;p&gt;ThisThe Parallel LINQ chapterchapters also usesuse a free Visual Studio extensionsextension for .NET Framework, Concurrent Visualizer, provided by Microsoft. it can be installed from Tools =&amp;gt; Extensions and Updates….&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image021%5B16%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image021%5B16%5D_thumb.gif&quot; alt=&quot;clip_image021[16]&quot; title=&quot;clip_image021[16]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More code files can be added under the application. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image021%5B17%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image021%5B17%5D_thumb.gif&quot; alt=&quot;clip_image021[17]&quot; title=&quot;clip_image021[17]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now just press F5 to build, run and debug the applicationC# code in Visual Studio.&lt;/p&gt;
&lt;h3&gt;Coding with Visual Studio for Mac (macOS)&lt;/h3&gt;
&lt;p&gt;The free Visual Studio for Mac can be downloaded and installed from Microsoft official website: https://www.visualstudio.com/vs/visual-studio-mac. Then launch Visual Studio for Mac, click New Project button on the welcome page to create a new .NET Core console applicationStart coding under .NET Core, App:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image023%5B16%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image023%5B16%5D_thumb.jpg&quot; alt=&quot;clip_image023[16]&quot; title=&quot;clip_image023[16]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project, in the context menu click Options. In the opened Project Options window, click the General tab under Build, change C# Language Version to latest:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image025%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image025%5B9%5D_thumb.gif&quot; alt=&quot;clip_image025[9]&quot; title=&quot;clip_image025[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project’s Dependencies child node, in the context menu click Add Packages, install the fore mentioned NuGet packages for .NET Core:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image027%5B16%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image027%5B16%5D_thumb.jpg&quot; alt=&quot;clip_image027[16]&quot; title=&quot;clip_image027[16]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, just press F5 to build, run and debug the C# code in Visual Studio for Mac.&lt;/p&gt;
&lt;h3&gt;Coding with Visual Studio Code (Windows, macOS and Linux)&lt;/h3&gt;
&lt;p&gt;The free Visual Studio Code can be downloaded and installed from Microsoft official website: https://code.visualstudio.com. This tutorialbook also uses 2 extensions for Visual Studio Code: C# extension for C# programming, and mssql extension for SQL execution in the LINQ to Entities chapter. These extensions are both provided by Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image029%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image029%5B9%5D_thumb.gif&quot; alt=&quot;clip_image029[9]&quot; title=&quot;clip_image029[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image030%5B9%5D.gif&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image030%5B9%5D_thumb.gif&quot; alt=&quot;clip_image030[9]&quot; title=&quot;clip_image030[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The .NET Core SDK needs toshould be installed separately, by following the steps from Microsoft official website: https://dot.net. TheWhen the installation is done, it can be verified by the dotnet –version command, which outputs the version of .NET Core SDK. To start coding, create a directory for a new console application, then go to this directory, run dotnet new console. 2 files are created, Program.cs and ConsoleApp.csproj. Program.cs is the C# code file, which is the same as above Program.cs created by Visual Studio. ConsoleApp.csproj is the project file containing the metadata and build information for this console application. Open ConsoleApp.csproj, and manually add the &amp;lt;LangVersion&amp;gt;latest&amp;lt;/LangVersion&amp;gt; element to use the latest C# version:&lt;/p&gt;
&lt;p&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;TargetFramework&amp;gt;netcoreapp2.0&amp;lt;/TargetFramework&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;LangVersion&amp;gt;latest&amp;lt;/LangVersion&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/Project&amp;gt;&lt;/p&gt;
&lt;p&gt;The NuGet packages used by this tutorialbook can be added with the dotnet add package {package name} command. For the packages only available as preview, the version has to be specified: dotnet add package {package name} –version {version}.&lt;/p&gt;
&lt;p&gt;From this directory, run code . command to start Visual Studio Code. Visual Studio Code should prompt “Required assets to build and debug are missing from ‘ConsoleApp’. Add them?”. Click Yes, Visual Studio Code should create the debug configuration files ininstall a .vscode subdirectory. Now,few required items. When it is done, just press F5 to build, run and debug the applicationC# code in Visual Studio Code.&lt;/p&gt;
&lt;p&gt;Start coding:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image023%5B17%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image023%5B17%5D_thumb.jpg&quot; alt=&quot;clip_image023[17]&quot; title=&quot;clip_image023[17]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project, click Options. In the opened project options window, click the General tab under Build, change the language version to latest:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image032%5B9%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image032%5B9%5D_thumb.jpg&quot; alt=&quot;clip_image032[9]&quot; title=&quot;clip_image032[9]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project’s Dependencies child node, click Add Packages, install the fore mentioned NuGet packages:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image027%5B17%5D.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/clip_image027%5B17%5D_thumb.jpg&quot; alt=&quot;clip_image027[17]&quot; title=&quot;clip_image027[17]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, just press F5 to build, run and debug the code in Visual Studio for Mac.&lt;/p&gt;
</content:encoded></item><item><title>End-to-End - Setup free SSL certificate to secure Azure Web App with HTTPS</title><link>https://dixin.github.io/posts/end-to-end-setup-free-ssl-certificate-to-secure-azure-web-app-with-https/</link><guid isPermaLink="true">https://dixin.github.io/posts/end-to-end-setup-free-ssl-certificate-to-secure-azure-web-app-with-https/</guid><description>It is 2019 now, and HTTP is considered as “not secure”, and HTTPS is the default. This is a end-to-end tutorial of how to setup SSL certificate to secure Azure Web App with HTTPS. It is based on “[Let</description><pubDate>Tue, 09 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It is 2019 now, and HTTP is considered as “not secure”, and HTTPS is the default. This is a end-to-end tutorial of how to setup SSL certificate to secure Azure Web App with HTTPS. It is based on “&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;” and “&lt;a href=&quot;https://github.com/ohadschn/letsencrypt-webapp-renewer&quot;&gt;letsencrypt-webapp-renewer&lt;/a&gt;”. “Let’s Encrypt” is a free certificate solution, and “letsencrypt-webapp-renewer” is a great automation tool for certificate installation. It is based on another tool “&lt;a href=&quot;https://github.com/sjkp/letsencrypt-siteextension&quot;&gt;letsencrypt-siteextension&lt;/a&gt;”. The differences are,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“letsencrypt-webapp-renewer” does not require an Azure Storage Account, but “letsencrypt-siteextension” does.&lt;/li&gt;
&lt;li&gt;“letsencrypt-webapp-renewer” is a WebJob, and can run on a different Web App from the Web App to install certificate. And it can manage multiple Web Apps’ certificates as well. “letsencrypt-siteextension” is a Website extension, and can only run with the Web App which needs certificate.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So here “letsencrypt-webapp-renewer” is used.&lt;/p&gt;
&lt;h2&gt;What is “Let’s Encrypt”&lt;/h2&gt;
&lt;p&gt;“&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;” is a popular certificate authority, it can issue SSL certificate for free, and currently providing certificates for more than 115 million websites. Since July 2018, the Let’s Encrypt root, ISRG Root X1, is directly trusted by Microsoft products. So currently its root is now trusted by all mainstream root programs, including Microsoft, Google, Apple, Mozilla, Oracle, and Blackberry.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20155224_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20155224_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 155224&quot; title=&quot;Annotation 2019-02-09 155224&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, its free certificate expirees in every 3 months (90 days), not yearly. So a automation process will be setup to renew and install the certificates.&lt;/p&gt;
&lt;h2&gt;Setup Active Directory and App Registration&lt;/h2&gt;
&lt;p&gt;In Azure portal, go to the Active Directory, add a new App Registration:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20073404_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20073404_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 073404_thumb&quot; title=&quot;Annotation 2019-02-09 073404_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Save its application id, later it will be used as “client id”:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to Certificates &amp;amp; secretes, add a client secrete, and save it:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup Resource Group&lt;/h2&gt;
&lt;p&gt;Go to resource group, In Access Control, add the above App Registration as contributor:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_26.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup Azure Web App (aka Azure App Service Website)&lt;/h2&gt;
&lt;p&gt;This article assumes an existing Azure Web App. If you do not have one yet, it is very straightforward to create one from the Azure portal. Then you can deploy your website to that Azure Web App.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20020852_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20020852_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 020852_thumb&quot; title=&quot;Annotation 2019-02-09 020852_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Save the subscription id and resource group name for later usage.&lt;/p&gt;
&lt;p&gt;Only Basic (B1+) and above pricing tiers support SSL. The free tier (F1) and the cheapest Shared tier (D1) does not support SSL, and &lt;a href=&quot;https://feedback.azure.com/forums/169385-web-apps/suggestions/17531527-make-ssl-support-for-d1-shared-app-services&quot;&gt;Microsoft has declined to enable this feature for Shared (D1&lt;/a&gt;). If you have a F1 or D1 web app, go to “Scale up” in the Azure portal, change the pricing tier to B1 and above, which is more than 3 times of the Shared (D1) price.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20072255_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20072255_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 072255_thumb&quot; title=&quot;Annotation 2019-02-09 072255_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Setup custom domain&lt;/h3&gt;
&lt;p&gt;Shared pricing tier and above support custom domain. Follow the guidelines in the portal to setup your domain.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20064042_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20064042_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 064042_thumb&quot; title=&quot;Annotation 2019-02-09 064042_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To verify your domain ownership, Let’s Encrypt requests your-domain.com/.well-known/acme-challenge/{longId}. For example: hanziyuan.net/.well-known/acme-challenge/mftvrU2brecAXB76BsLEqW_SL_srdG3oqTQTzR5KHeA.&lt;/p&gt;
&lt;h3&gt;Enable HTTPS in ASP.NET Core website&lt;/h3&gt;
&lt;p&gt;In your ASP.NET Core website, you may want to enable HSTS, and redirect HTTP request to HTTPS:&lt;/p&gt;
&lt;p&gt;public class Startup
{
public void ConfigureServices(IServiceCollection services) // Container.
{
if (this.environment.IsProduction())
{
&lt;strong&gt;services.AddHttpsRedirection(options =&amp;gt; options.HttpsPort = 443);&lt;/strong&gt;
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    // Other configuration.
}

public void Configure(IApplicationBuilder application, ILoggerFactory loggerFactory, IAntiforgery antiforgery, Settings settings) // HTTP pipeline.
{
    if (this.environment.IsProduction())
    {
        **application.UseHsts();**
        **application.UseHttpsRedirection();** 
    }

    // Other configuration.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;You also want to look up the hyperlinks and resources (images, etc.), and replace their URIs with HTTPS.&lt;/p&gt;
&lt;h2&gt;Automation with letsencrypt-webapp-renewer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ohadschn/letsencrypt-webapp-renewer&quot;&gt;letsencrypt-webapp-renewer&lt;/a&gt; is a console application. It works as a &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/app-service/webjobs-create&quot;&gt;WebJob of Azure Web App&lt;/a&gt;, and automatically install/renew Let’s Encrypt certificate for your Azure Web App.&lt;/p&gt;
&lt;h3&gt;Create a separate Web App for automation&lt;/h3&gt;
&lt;p&gt;You can install SSL on one Azure Web App, and run letsencrypt-webapp-renewer as WebJob of the same Web App, or a different Web App. As the author Ohad Schneider pointed out in the comments, it is highly recommended to have the run letsencrypt-webapp-renewer as WebJob of a separate Web App, because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can use it to manage multiple Web Apps.&lt;/li&gt;
&lt;li&gt;WebJob is just a console application, its files (*.exe, *.dll, etc.) are deployed to your Web App’s App_Data directory (e.g. App_Data/jobs/triggered/letsencrypt/). So a WebJob can be silently deleted when you deploy/publish your website.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this tutorial, I run letsencrypt-webapp-renewer as WebJob of a separate Web App. This automation Web App is created under the same App Service plan. Since Azure charges per App service plan, I do not need to pay additional cost for this automation web App.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Add application settings&lt;/h3&gt;
&lt;p&gt;Download the setup PowerShell script from &lt;a href=&quot;https://github.com/ohadschn/letsencrypt-webapp-renewer/blob/master/OhadSoft.AzureLetsEncrypt.Renewal/Scripts/Set-LetsEncryptConfiguration.ps1&quot;&gt;https://github.com/ohadschn/letsencrypt-webapp-renewer/blob/master/OhadSoft.AzureLetsEncrypt.Renewal/Scripts/Set-LetsEncryptConfiguration.ps1&lt;/a&gt;, and run:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS D:\User\Desktop&amp;gt; &lt;strong&gt;.\Set-LetsEncryptConfiguration.ps1 -LetsEncryptSubscriptionId e09d69aa-afa1-4db3-aea3-ca58cc2d82ee -LetsEncryptResourceGroup etymology -LetsEncryptWebApp etymology-letsencrypt -SubscriptionId e09d69aa-afa1-4db3-aea3-ca58cc2d82ee -ResourceGroup etymology -WebApp etymology -ServicePlanResourceGroup etymology -TenantId dixinyanlive.onmicrosoft.com -ClientId 9ca16da2-9252-4a55-8c99-b41d458d7fc4 –ClientSecret ‘****’ -Hosts hanziyuan.net -Email dixinyan@live.com&lt;/strong&gt; Signing in to Azure Resource Manager account (use the account that contains your Let&apos;s Encrypt renewal web app)...&lt;/p&gt;
&lt;p&gt;Account : dixinyan@live.com SubscriptionName : Visual Studio Enterprise SubscriptionId : e09d69aa-afa1-4db3-aea3-ca58cc2d82ee TenantId : 31a11410-e324-47a1-bbc4-9884031e3b14 Environment : AzureCloud&lt;/p&gt;
&lt;p&gt;Setting context to the Let&apos;s Encrypt subscription ID...&lt;/p&gt;
&lt;p&gt;Name : [dixinyan@live.com, e09d69aa-afa1-4db3-aea3-ca58cc2d82ee] Account : dixinyan@live.com Environment : AzureCloud Subscription : e09d69aa-afa1-4db3-aea3-ca58cc2d82ee Tenant : 31a11410-e324-47a1-bbc4-9884031e3b14 TokenCache : Microsoft.Azure.Commands.Common.Authentication.AuthenticationStoreTokenCache VersionProfile : ExtendedProperties : {}&lt;/p&gt;
&lt;p&gt;Loading existing Let&apos;s Encrypt web app settings... Copying over existing app settings... Adding new settings... Setting &apos;subscriptionId&apos; to &apos;e09d69aa-afa1-4db3-aea3-ca58cc2d82ee&apos;... Setting &apos;resourceGroup&apos; to &apos;etymology&apos;... Setting &apos;servicePlanResourceGroup&apos; to &apos;etymology&apos;... Setting &apos;tenantId&apos; to &apos;dixinyanlive.onmicrosoft.com&apos;... Setting &apos;clientId&apos; to &apos;letsencrypt&apos;... Setting &apos;hosts&apos; to &apos;hanziyuan.net&apos;... Setting &apos;email&apos; to &apos;dixinyan@live.com&apos;... Value not provided for app setting &apos;useIpBasedSsl&apos; - skipping... Value not provided for app setting &apos;rsaKeyLength&apos; - skipping... Value not provided for app setting &apos;acmeBaseUri&apos; - skipping... Setting &apos;renewXNumberOfDaysBeforeExpiration&apos; to &apos;-1&apos;... Copying over existing connection strings... Adding new connection string... Updating settings...&lt;/p&gt;
&lt;p&gt;SiteName : etymology-letsencrypt State : Running HostNames : {etymology-letsencrypt.azurewebsites.net} RepositorySiteName : etymology-letsencrypt UsageState : Normal Enabled : True EnabledHostNames : {etymology-letsencrypt.azurewebsites.net, etymology-letsencrypt.scm.azurewebsites.net} AvailabilityState : Normal HostNameSslStates : {etymology-letsencrypt.azurewebsites.net, etymology-letsencrypt.scm.azurewebsites.net} ServerFarmId : /subscriptions/e09d69aa-afa1-4db3-aea3-ca58cc2d82ee/resourceGroups/etymology/providers/Micr osoft.Web/serverfarms/etymology LastModifiedTimeUtc : 2/10/2019 10:43:42 PM SiteConfig : Microsoft.Azure.Management.WebSites.Models.SiteConfig TrafficManagerHostNames : PremiumAppDeployed : ScmSiteAlsoStopped : False TargetSwapSlot : HostingEnvironmentProfile : MicroService : GatewaySiteName : ClientAffinityEnabled : True ClientCertEnabled : False HostNamesDisabled : False OutboundIpAddresses : 207.46.144.46,207.46.144.85,207.46.144.91,207.46.148.246 ContainerSize : 0 MaxNumberOfWorkers : CloningInfo : ResourceGroup : etymology IsDefaultContainer : DefaultHostName : etymology-letsencrypt.azurewebsites.net Id : /subscriptions/e09d69aa-afa1-4db3-aea3-ca58cc2d82ee/resourceGroups/etymology/providers/Micr osoft.Web/sites/etymology-letsencrypt Name : etymology-letsencrypt Location : East Asia Type : Microsoft.Web/sites Tags :&lt;/p&gt;
&lt;p&gt;Let&apos;s Encrypt settings updated successfully&lt;/p&gt;
&lt;p&gt;PS D:\User\Desktop&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This adds a bunch of settings and a connection string to the automation Web App, which will be read by the WebJob:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Setup and run WebJob&lt;/h3&gt;
&lt;p&gt;Download the latest release of letsencrypt-webapp-renewer, which is a zip file with everything packed. Upload it as a Triggered WebJob of the automation Web App:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As mentioned by the official document, “The &lt;a href=&quot;https://letsencrypt.org/docs/faq/&quot;&gt;recommended Let&apos;s Encrypt renewal period is 60 days&lt;/a&gt;, so you could use a CRON expression that fires once every two months, for example: 0 0 0 1 1,3,5,7,9,11 *.”&lt;/p&gt;
&lt;p&gt;Now manually start the WebJob:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When it’s done, the SSL certificate is installed/renewed for the Azure Web App. And you are good to go with HTTPS: &lt;a href=&quot;https://hanziyuan.net&quot;&gt;https://hanziyuan.net&lt;/a&gt;. You can also click the Logs button to view the details:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20071735_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20071735_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 071735_thumb&quot; title=&quot;Annotation 2019-02-09 071735_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is useful for troubleshooting. For example, if your Web App is Shared (D1) pricing tier, it will fail with detailed info in the logs &lt;a href=&quot;https://etymology.scm.azurewebsites.net/vfs/data/jobs/triggered/letsencrypt/201902081828412089/output_log.txt&quot;&gt;https://etymology.scm.azurewebsites.net/vfs/data/jobs/triggered/letsencrypt/201902081828412089/output_log.txt&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[02/08/2019 18:29:11 &amp;gt; 021587: INFO] AzureLetsEncryptRenewer.exe Error: 0 : Encountered exception: Microsoft.Rest.Azure.CloudException: Cannot enable SNI SSL for a hostname &apos;hanziyuan.net&apos; because current site mode does not allow it. [02/08/2019 18:29:11 &amp;gt; 021587: INFO] at Microsoft.Azure.Management.WebSites.WebAppsOperations.&amp;lt;BeginCreateOrUpdateWithHttpMessagesAsync&amp;gt;d__208.MoveNext() [02/08/2019 18:29:11 &amp;gt; 021587: INFO] --- End of stack trace from previous location where exception was thrown ---&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once the WebJob finishes running, your Web App is secured with SSL, and HTTP requests are redirected to HTTPS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And this is your certificate issued by Let’s Encrypt:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup notification with SendGrid&lt;/h2&gt;
&lt;p&gt;These steps are optional and just for WebJob notification. In Azure portal, create a free SendGrid account:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20074622_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20074622_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 074622_thumb&quot; title=&quot;Annotation 2019-02-09 074622_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to its settings, copy the user name.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20074843_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20074843_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 074843_thumb&quot; title=&quot;Annotation 2019-02-09 074843_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Use the user name and password to log on SendGrid – &lt;a href=&quot;https://sendgrid.com&quot;&gt;https://sendgrid.com&lt;/a&gt;, then go to Settings, create an API key:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20075120_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20075120_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 075120_thumb&quot; title=&quot;Annotation 2019-02-09 075120_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then in Azure portal, add a connection string “letsencrypt:SendGridApiKey” to Web App, then you are good to go:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20075707_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20075707_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 075707_thumb&quot; title=&quot;Annotation 2019-02-09 075707_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup notification with Zapier&lt;/h2&gt;
&lt;p&gt;These steps are optional and just for WebJob notification. In Azure portal, go to the Web App’s Properties, copy its deployment trigger URL. Then go to Zapier &lt;a href=&quot;https://zapier.com&quot;&gt;https://zapier.com&lt;/a&gt;, use that URL to create a Azure Web Apps Trigger with new Triggered WebJob run:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20080358_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20080358_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 080358_thumb&quot; title=&quot;Annotation 2019-02-09 080358_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then setup email action:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20081318_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/962e9ee15b1a_8139/Annotation%202019-02-09%20081318_thumb_thumb.jpg&quot; alt=&quot;Annotation 2019-02-09 081318_thumb&quot; title=&quot;Annotation 2019-02-09 081318_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (9) Performance</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-9-performance-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-9-performance-7/</guid><description>The previous parts has discussed some aspects that can impact the performance of EF/Core and LINQ to Entities, and here is a summary:</description><pubDate>Sun, 31 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-9-performance&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-9-performance&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;EF version of this article: &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-10-performance&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-10-performance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous parts has discussed some aspects that can impact the performance of EF/Core and LINQ to Entities, and here is a summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remote LINQ to Entities query can have better performance than local or hybrid query. An intuitive example is Last query for a table data source, which could query the entire table, load data to local, and query the last result locally. It is better to just have a remote query and only load the specific result.&lt;/li&gt;
&lt;li&gt;Using Select to only query the data can have better performance than querying full entity.&lt;/li&gt;
&lt;li&gt;Disabling entity tracking can improve the performance.&lt;/li&gt;
&lt;li&gt;Disabling automatic change detection can improve the performance.&lt;/li&gt;
&lt;li&gt;When adding a sequence of entities to repository, DbSet&amp;lt;T&amp;gt;.AddRange/DbSet&amp;lt;T&amp;gt;.RemoveRange call can have better performance than many DbSet&amp;lt;T&amp;gt;.Add/DbSet&amp;lt;T&amp;gt;.Remove calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;And, in EF, with lazy loading, accessing an entity’s navigation property can cause additional database query round trips (the N + 1 queries problem). Eager loading can improve the performance by read all needed data with 1 single database query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This part continues the discussion of performance.&lt;/p&gt;
&lt;h2&gt;Initialization&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;EF dies a lot of initialization work before the first database query is executed.&lt;/p&gt;
&lt;p&gt;The following example simply pulls categories from the repository, with one LINQ to Entities query:’&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Performance
{
    internal static void Initialize()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories;
            categories.WriteLines(category =&amp;gt; category.Name);
            // select cast(serverproperty(&apos;EngineEdition&apos;) as int)

            // SELECT Count(*)
            // FROM INFORMATION_SCHEMA.TABLES AS t
            // WHERE t.TABLE_SCHEMA + &apos;.&apos; + t.TABLE_NAME IN (&apos;HumanResources.Employee&apos;,&apos;Person.Person&apos;,&apos;Production.ProductCategory&apos;,&apos;Production.ProductSubcategory&apos;,&apos;Production.Product&apos;,&apos;Production.ProductProductPhoto&apos;,&apos;Production.ProductPhoto&apos;,&apos;Production.TransactionHistory&apos;,&apos;HumanResources.vEmployee&apos;) 
            //    OR t.TABLE_NAME = &apos;EdmMetadata&apos;
            // exec sp_executesql N&apos;SELECT 
            //    [GroupBy1].[A1] AS [C1]
            //    FROM ( SELECT 
            //        COUNT(1) AS [A1]
            //        FROM [dbo].[__MigrationHistory] AS [Extent1]
            //        WHERE [Extent1].[ContextKey] = @p__linq__0
            //    )  AS [GroupBy1]&apos;,N&apos;@p__linq__0 nvarchar(4000)&apos;,@p__linq__0=N&apos;AdventureWorks&apos;
            // SELECT 
            //    [GroupBy1].[A1] AS [C1]
            //    FROM ( SELECT 
            //        COUNT(1) AS [A1]
            //        FROM [dbo].[__MigrationHistory] AS [Extent1]
            //    )  AS [GroupBy1]
            // SELECT TOP (1) 
            //    [Extent1].[Id] AS [Id], 
            //    [Extent1].[ModelHash] AS [ModelHash]
            //    FROM [dbo].[EdmMetadata] AS [Extent1]
            //    ORDER BY [Extent1].[Id] DESC
            // SELECT 
            //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
            //    [Extent1].[Name] AS [Name]
            //    FROM [Production].[ProductCategory] AS [Extent1]
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing above code, a bunch of SQL queries can be traced. And only the last SELECT query is the expected LINQ to Entities query translation. Actually, before a database’s first operation at runtime (e.g., querying Production.ProductCategory table here), EF does a lot of work to initialize its object-relational mapping:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize provider manifest&lt;/li&gt;
&lt;li&gt;Initialize the entity data model. EF automatically builds the object models (CLR models, not above entities), conceptual models, storage models, object-conceptual model mappings, conceptual-storage model mappings, etc..&lt;/li&gt;
&lt;li&gt;Initialize the database, if needed.&lt;/li&gt;
&lt;li&gt;Initialize mapping views, which are the mapping information for entity sets.&lt;/li&gt;
&lt;li&gt;Initialize a dynamic assembly &quot;EntityFrameworkDynamicProxies-{OriginalAssemblyName}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot;, and define proxy types in it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above initialization steps executes only once at runtime, and their performance can be improved from the default behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Provider initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;As fore mentioned, EF implements the provider model to work with different kinds of data stores, and it need to get the basic information of current data store. For SQL database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The SQL database server’s version is detected by calling DbConnection.ServerVersion&lt;/li&gt;
&lt;li&gt;The engine edition is queried by above &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms174396.aspx&quot;&gt;SERVERPROPERTY&lt;/a&gt; metadata function, to determine whether it is a on premise database (SQL Server) or cloud database (SQL Azure, aka Azure SQL Database).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For SQL database, the supported provider manifest tokens are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer
{
    internal class SqlProviderManifest : DbXmlEnabledProviderManifest
    {
        internal const string TokenSql8 = &quot;2000&quot;;

        internal const string TokenSql9 = &quot;2005&quot;;

        internal const string TokenSql10 = &quot;2008&quot;;

        internal const string TokenSql11 = &quot;2012&quot;;

        internal const string TokenAzure11 = &quot;2012.Azure&quot;;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For any on premise SQL database later than 11.0, just use “2012”. For cloud SQL database, use “2012.Azure”. In this tutorial, the server version and engine edition is known. So these information can be provided to EF via System.Data.Entity.Infrastructure.IManifestTokenResolver:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SqlConfiguration : DbConfiguration
{
    public SqlConfiguration() =&amp;gt;
            this.SetManifestTokenResolver(new SqlManifestTokenResolver());
}

public class SqlManifestTokenResolver : IManifestTokenResolver
{
    public string ResolveManifestToken(DbConnection connection) =&amp;gt; &quot;2012.Azure&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then engine edition query is not executed during initialization. Notice EF only support defining a single type derived from DbConfiguration. In the object-relational mapping part, there us already a RetryConfiguration type defined to specify the retry strategy. The logic in both types must be merged intto one type, otherwise EF throws exception during initialization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Database initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The database initialization work is represented by System.Data.Entity.IDatabaseInitializer&amp;lt;TContext&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public interface IDatabaseInitializer&amp;lt;in TContext&amp;gt; where TContext : DbContext
    {
        void InitializeDatabase(TContext context);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF provides several built-in initializers under System.Data.Entity namespace:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NullDatabaseInitializer&amp;lt;TContext&amp;gt;: Do nothing for initialization&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseAlways&amp;lt;TContext&amp;gt;: Always drop the database and create again&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseIfModelChanges&amp;lt;TContext&amp;gt;: Drop and create database when the code mapping mismatches database schema.&lt;/li&gt;
&lt;li&gt;MigrateDatabaseToLatestVersion&amp;lt;TContext, TMigrationsConfiguration&amp;gt;: Use the specified code to update the database to the latest version.&lt;/li&gt;
&lt;li&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: Create database if not exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: is the default initializer, so it is executed here too. As a result, EF attempts to &lt;a href=&quot;https://romiller.com/2014/06/10/reducing-code-first-database-chatter/&quot;&gt;query the existence of the mapped tables and views, database migration history, and entity data model info, etc&lt;/a&gt;. Apparently, here AdventureWorks database does not have the migration and entity data model info; recreating database is not needed as well. So the database initialization can be turned off, by setting the initializer to NullDatabaseInitializer&amp;lt;TContext&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    static AdventureWorks()
    {
        Database.SetInitializer(new NullDatabaseInitializer&amp;lt;AdventureWorks&amp;gt;()); // Call once.
        // Equivalent to: Database.SetInitializer&amp;lt;AdventureWorks&amp;gt;(null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where NullDatabaseInitializer&amp;lt;TContext&amp;gt; provide empty operation that does nothing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class NullDatabaseInitializer&amp;lt;TContext&amp;gt; : IDatabaseInitializer&amp;lt;TContext&amp;gt; where TContext : DbContext
    {
        public virtual void InitializeDatabase(TContext context)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all the additional database queries for initialization are turned off.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Mapping views initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, mapping views are not the views inside the database. They are System.Data.Entity.Infrastructure.MappingViews.DbMappingView instances, representing the mapping information for entity sets. Instead of generate these instances at runtime, pre-generate them at design time can improve the performance. Microsoft provides a Visual Studio extension, EF Power Tools, to generate these code. It needs to be &lt;a href=&quot;http://thedatafarm.com/data-access/installing-ef-power-tools-into-vs2015/&quot;&gt;modified&lt;/a&gt; to installed with the latest Visual Studio. After the installation, just right click the code file containing the database mapping (the class derived from DbContext), and in the menu click EF =&amp;gt; Generate Views, it generates a file, containing the code to create the DbMappingView instances.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Cache&lt;/h2&gt;
&lt;p&gt;After the object-relational mapping metadata is initialized, they are cached, so that the initialization only happens once for the AppDomain. EF/Core also implement cache for entities and query translation.&lt;/p&gt;
&lt;h3&gt;Entity cache&lt;/h3&gt;
&lt;p&gt;As fore mentioned, by default, the entities queried from repository are cached and tracked. This behavior can be demonstrated by the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CachedEntity(AdventureWorks adventureWorks)
{
    ProductCategory categoryCopy1 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
    categoryCopy1.Name = &quot;Cache&quot;;

    ProductCategory categoryCopy2 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
    categoryCopy2.Name.WriteLine(); // Cache
    object.ReferenceEquals(categoryCopy1, categoryCopy2).WriteLine(); // True

    ProductCategory categoryCopy3 = adventureWorks.ProductCategories
#if EF
        .SqlQuery(
#else
        .FromSql(
#endif
            @&quot;SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy3).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the first query reads data from the repository and materialize the data to a category entity, and update its Name. Then the repository is queried again by Name. After reading the data, EF/Core find the primary key is the same as the cached entity, so EF/Core do not materialize the data just read, it reuses the previous category entity. Performance can be improved by skipping the materialization, but tricky result can happen. The second query reads entity with Name “Bikes”, but the query result entity has Name “Cache”. This is not only LINQ to Entities queries’ behavior, When DbSet&amp;lt;T&amp;gt; directly executes SQL query in the repository, EF/Core still uses cached entities.&lt;/p&gt;
&lt;p&gt;Entity is not cached when tracking is turned off, or entity is not queried from the repository. Each of the following queries materializes a new entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UncachedEntity(AdventureWorks adventureWorks)
{
    ProductCategory categoryCopy1 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
    categoryCopy1.Name = &quot;Cache&quot;;

    ProductCategory categoryCopy2 = adventureWorks.ProductCategories
        .AsNoTracking().Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
    categoryCopy2.Name.WriteLine(); // Bikes
    object.ReferenceEquals(categoryCopy1, categoryCopy2).WriteLine(); // False

    ProductCategory categoryCopy3 = adventureWorks.ProductCategories
#if EF
        .SqlQuery(
#else
        .FromSql(
#endif
            @&quot;SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .AsNoTracking()
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy3).WriteLine(); // False

#if EF
    ProductCategory categoryCopy4 = adventureWorks.Database
        .SqlQuery&amp;lt;ProductCategory&amp;gt;(@&quot;
            SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy4).WriteLine(); // False
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbSet.Find accept the primary keys and returns an entity. Calling Find can improve the performance, because it looks up cache before querying the repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Find(AdventureWorks adventureWorks)
{
    Product[] products = adventureWorks.Products
        .Where(entity =&amp;gt; entity.Name.StartsWith(&quot;Road&quot;)).ToArray(); // Execute query.
    Product product = adventureWorks.Products.Find(999); // No database query.
    object.ReferenceEquals(products.Last(), product).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here when Find is called, entity with the specified primary key is already queries, cached and tracked, so Find directly returns the cached entity, without repository query or data materialization.&lt;/p&gt;
&lt;h3&gt;LINQ query translation cache&lt;/h3&gt;
&lt;p&gt;As discussed in the query translation part, EF/Core translate a LINQ to Entities query in 2 steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compile LINQ expression tree to database expression tree&lt;/li&gt;
&lt;li&gt;Generate SQL from database expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To improve the performance, EF Core caches the query translations in a Microsoft.Extensions.Caching.Memory.MemoryCache. Before processing a LINQ query, EF Core computes the cache key, and looks up the cache. If the translation is found, then it reuses the translation; if not, it translates the query, and add the translation to cache.. For SQL database queries, the cache key’s hash code is computed with the the hash code of the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The LINQ query expression tree. The LINQ query expression tree is scanned recursively, the hash code of the nodes and APIs represented by the expression tree nodes are used to compute the hash code of the entire expression tree.&lt;/li&gt;
&lt;li&gt;DbContext.Model&lt;/li&gt;
&lt;li&gt;DbContext.ChangeTracker.QueryTrackingBehavior, which is an enumeration of TrackAll or NoTracking&lt;/li&gt;
&lt;li&gt;A Boolean value that indicates whether the query is executed asynchronously&lt;/li&gt;
&lt;li&gt;SqlServerOptionsExtension.UseRelationalNulls, which can be specified with SqlServerDbContextOptionsBuilder.UseRelationalNulls&lt;/li&gt;
&lt;li&gt;SqlServerOptionsExtension.RowNumberPaging, which can be specified with SqlServerDbContextOptionsBuilder.UseRowNumberForPaging&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EF always compiles the LINQ expression tree to database expression tree, then cache the SQL generation in a dictionary. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; query = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength)
        .Include(product =&amp;gt; product.ProductSubcategory);
    query.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF generates the cache key with the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The database expression tree’s string representation. Here it is: [Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.Products:Transient.collection[Product(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),@p__linq__0:Edm.Int32(Nullable=False,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;The parameters’ string representation: @@1p__linq__0:System.Int32&lt;/li&gt;
&lt;li&gt;The path of the Include query. Here it is ProductSubcategory&lt;/li&gt;
&lt;li&gt;The query’s MergeOption, which is AppendOnly by default.&lt;/li&gt;
&lt;li&gt;System.Data.Entity.Core.Objects.ObjectContextOptions.UseCSharpNullComparisonBehavior&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The following example executes 2 LINQ to Entities queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UnreusedTranslationCache(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; queryWithConstant1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= 1);
    queryWithConstant1.Load();

    IQueryable&amp;lt;Product&amp;gt; queryWithConstant2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= 10);
    queryWithConstant2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These first LINQ query builds expression trees with a ConstantExpression node representing int value 1. The second query builds similar expression tree but with a different ConstantExpression node representing int value 10. So these LINQ expression trees are different. In EF Core, the first expression tree’s translation cannot be reused for the second query.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, their compiled database expression trees are different too, with 2 different DbConstantExpression nodes. The 2 database expression trees’ string representations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),1:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),10:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the first query’s SQL generation cannot be used for the second query either.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To reuse the translation cache, these queries can be parameterized by simply replace the constants with variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReusedTranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure1.Load();

    minLength = 10;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the C# features chapter, the predicate lambda expressions capture variable minLength with the closure syntactic sugar. The above code is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReusedTranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure1.Load();

    minLength = 10;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the predicates, the outer variable access is compiled to field access. So in the LINQ queries’ expression trees, there are no longer ConstantExpression nodes representing different int values, but MemberExpression nodes representing the same field. As a result, the 2 query’s LINQ expression trees are identical, and the translation is reused.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, if a query method accepts values instead of lambda expression, this parameterization approach does not work. For example, Skip and Take accept int values as parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UnresuedSkipTakeTranslationCache(AdventureWorks adventureWorks)
{
    int skip = 1;
    int take = 1;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithVariable1 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(skip).Take(take);
    skipTakeWithVariable1.Load();

    skip = 10;
    take = 10;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithVariable2 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(skip).Take(take);
    skipTakeWithVariable2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above LINQ queries access to variable skip and take, but these variable access are also represented by ConstantExpression nodes. So their expression trees are different, and converted database command trees are different, and their translations cannot be reused for each other. To resolve this problem, EF provides a lambda expression version for these methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public static class QueryableExtensions
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);

        public static IQueryable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Skip and Take can access variables via closure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ResuedSkipTakeTranslationCache(AdventureWorks adventureWorks)
{
    int skip = 1;
    int take = 1;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithClosure1 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
    skipTakeWithClosure1.Load();

    skip = 10;
    take = 10;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithClosure2 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
    skipTakeWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These LINQ queries have MemberExpression nodes again. EF can convert them to identical parameterized database expression trees. Now their translations can be reused for each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;SQL query plan cache&lt;/h3&gt;
&lt;p&gt;LINQ queries with different constants are translated to different SQL queries. Above queryWithConstant1 and queryWithConstant2 are translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= 1

SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently they have different query plans in SQL database, which cannot be reused for each other:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_428A/image_thumb3_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_428A/image_thumb3_thumb.png&quot; alt=&quot;image_thumb3&quot; title=&quot;image_thumb3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With parameterization, queryWithClosure1 and queryWithClosure2 are translated to identical SQL queries, with different parameter values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= @__minLength_0&apos;,N&apos;@__minLength_0 int&apos;,@__minLength_0=1

exec sp_executesql N&apos;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= @__minLength_0&apos;,N&apos;@__minLength_0 int&apos;,@__minLength_0=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in SQL database, queryWithClosure1’s query plan is cached and reused for queryWithClosure2:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_428A/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_428A/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Asynchrony&lt;/h2&gt;
&lt;p&gt;Generally, for long running I/O bound operation, asynchrony can improve the application responsiveness and service scalability. EF/Core support asynchrony for database CRUD operations, and these async APIs are very easy to use with C# async/await keywords. Please notice this does not mean all the synchronous API calls must be replaced by asynchronous API calls, the application must be tested to identify which API has better performance.&lt;/p&gt;
&lt;h3&gt;Asynchronous data queries and data changes&lt;/h3&gt;
&lt;p&gt;For LINQ to Entities queries, EF/Core start to read the data when values are pulled from IQueryable&amp;lt;T&amp;gt; data source, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull the values from the query represented by IQueryable&amp;lt;T&amp;gt;.&lt;/li&gt;
&lt;li&gt;Call a query method to return a single value from the IQueryable&amp;lt;T&amp;gt;, like First, etc..&lt;/li&gt;
&lt;li&gt;Call a LINQ to Objects query method to return a new collection, like ToArray, etc..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For these operations and APIs, async parities are provided as IQueryable&amp;lt;T&amp;gt; extension methods. In EF Core, these async query APIs are also provided as extension methods in Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;async iteration method: ForEachAsync asynchronously pulls each value from IQueryable&amp;lt;T&amp;gt; data source and call the specified function.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;async methods to return a single value:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Element: FirstAsync, FirstOrDefaultAsync, LastAsync, LastOrDefaultAsync, SingleAsync, SingleOrDefaultAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: CountAsync, LongCountAsync, MinAsync, MaxAsync, SumAsync, AverageAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quantifier: AllAsync, AnyAsync, ContainsAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;async methods to return a new collection: ToArrayAsync, ToDictionaryAsync, ToListAsync&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, these methods are provided in System.Data.Entity.QueryableExtensions, and LastAsync, LastOrDefaultAsync are not provided, since EF does not support Last, LastOrDefault.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For data changes, DbContext.SaveChangesAsync is provided as a parity of DbContext.SaveChanges. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task Async(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories;
    await categories.ForEachAsync( // Async version of foreach/ForEach.
        category =&amp;gt; category.Name.WriteLine());

    ProductSubcategory subcategory = await adventureWorks.ProductSubcategories
        .FirstAsync(entity =&amp;gt; entity.Name.Contains(&quot;Bike&quot;)); // Async version of First.
    subcategory.Name.WriteLine();

    Product[] products = await adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt;= 10)
        .ToArrayAsync(); // Async version of ToArray.

    adventureWorks.Products.RemoveRange(products);
    (await adventureWorks.SaveChangesAsync()).WriteLine(); // Async version of SaveChanges.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Transactions and connection resiliency with asynchronous operations&lt;/h3&gt;
&lt;p&gt;These async APIs work in EF/Core transaction. In this tutorial, connection resiliency is enabled because cloud SQL database is used, so call the retry strategy’s ExecuteAsync method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task DbContextTransactionAsync(AdventureWorks adventureWorks)
{
    await adventureWorks.Database.CreateExecutionStrategy().ExecuteAsync(async () =&amp;gt;
    {
#if EF
        using (IDbContextTransaction transaction = adventureWorks.Database.BeginTransaction(
#else
        using (IDbContextTransaction transaction = await adventureWorks.Database.BeginTransactionAsync(
#endif
            IsolationLevel.ReadUncommitted))
        {
            try
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // ReadUncommitted

                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
#if EF
                adventureWorks.ProductCategories.Add(category);
#else
                await adventureWorks.ProductCategories.AddAsync(category);
#endif
                (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1

                await adventureWorks.Database.ExecuteSqlCommandAsync(
                    sql: &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {0}&quot;,
                    parameters: nameof(ProductCategory)).WriteLine(); // 1
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These async APIs also work in ADO.NET transaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task DbTransactionAsync()
{
    using (SqlConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
    {
        await connection.OpenAsync();
        using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
        {
            try
            {
                using (AdventureWorks adventureWorks = new AdventureWorks(connection))
                {
                    await adventureWorks.Database.CreateExecutionStrategy().ExecuteAsync(async () =&amp;gt;
                    {
                        adventureWorks.Database.UseTransaction(transaction);
                        adventureWorks.CurrentIsolationLevel().WriteLine(); // Serializable

                        ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
#if EF
                        adventureWorks.ProductCategories.Add(category);
#else
                        await adventureWorks.ProductCategories.AddAsync(category);
#endif
                        (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1.
                    });
                }

                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                    DbParameter parameter = command.CreateParameter();
                    parameter.ParameterName = &quot;@p0&quot;;
                    parameter.Value = nameof(ProductCategory);
                    command.Parameters.Add(parameter);
                    command.Transaction = transaction;
                    (await command.ExecuteNonQueryAsync()).WriteLine(); // 1
                }
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TransactionScope by default does not support across thread transaction flow. Using the the async/await syntactic sugar for TransactionScope causes InvalidOperationException: A TransactionScope must be disposed on the same thread that it was created.. To resolved this, Since .NET 4.5.1, a new constructor for TransactionScope is provided to explicitly enable transaction flow across thread continuations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task TransactionScopeAsync()
{
    await new ExecutionStrategy().ExecuteAsync(async () =&amp;gt;
    {
        using (TransactionScope scope = new TransactionScope(
            scopeOption: TransactionScopeOption.Required,
            transactionOptions: new TransactionOptions()
            {
                IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead
            },
            asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
        {
            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = DbContextExtensions.CurrentIsolationLevelSql;
                await connection.OpenAsync();
                using (DbDataReader reader = await command.ExecuteReaderAsync())
                {
                    await reader.ReadAsync();
                    reader[0].WriteLine(); // RepeatableRead
                }
            }

            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                adventureWorks.ProductCategories.Add(category);
                (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1
            }

            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // RepeatableRead
            }

            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                DbParameter parameter = command.CreateParameter();
                parameter.ParameterName = &quot;@p0&quot;;
                parameter.Value = nameof(ProductCategory);
                command.Parameters.Add(parameter);

                await connection.OpenAsync();
                (await command.ExecuteNonQueryAsync()).WriteLine(); // 1
            }

            scope.Complete();
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Asynchronous concurrent conflicts&lt;/h3&gt;
&lt;p&gt;EF/Core also provide async APIs for other database operations. In the previous concurrency part, a DbContext.SaveChanges overload is implemented to handle concurrency conflict, refresh entity, and retry saving changes. Here a async version can be implemented easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return await context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                await resolveConflictsAsync(exception.Entries);
            }
        }
        return await context.SaveChangesAsync();
    }

    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, RetryStrategy retryStrategy)
    {
        RetryPolicy retryPolicy = new RetryPolicy(
            new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(), retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt;
            resolveConflictsAsync(((DbUpdateConcurrencyException)e.LastException).Entries).Wait();
        return await retryPolicy.ExecuteAsync(async () =&amp;gt; await context.SaveChangesAsync());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the async/await syntactic sugar, the implementation looks very similar to the synchronous version. The following are the SaveChangesAsync overloads to accept RefreshConflict enumeration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
    this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
{
    if (retryCount &amp;lt;= 0)
    {
        throw new ArgumentOutOfRangeException(nameof(retryCount));
    }

    return await context.SaveChangesAsync(
        async conflicts =&amp;gt; await Task.WhenAll(conflicts.Select(async tracking =&amp;gt;
            await tracking.RefreshAsync(refreshMode))),
        retryCount);
}

public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
    this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =&amp;gt;
        await context.SaveChangesAsync(
            async conflicts =&amp;gt; await Task.WhenAll(conflicts.Select(async tracking =&amp;gt;
                await tracking.RefreshAsync(refreshMode))),
            retryStrategy);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of calling the previously defined Refresh extension method to refresh the DbEntityEntry instance, here a async method RefreshAsync is called to refresh asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;EntityEntry&amp;gt; RefreshAsync(this EntityEntry tracking, RefreshConflict refreshMode)
{
    switch (refreshMode)
    {
        case RefreshConflict.StoreWins:
        {
            await tracking.ReloadAsync();
            break;
        }
        case RefreshConflict.ClientWins:
        {
            PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
            if (databaseValues == null)
            {
                tracking.State = EntityState.Detached;
            }
            else
            {
                tracking.OriginalValues.SetValues(databaseValues);
            }
            break;
        }
        case RefreshConflict.MergeClientAndStore:
        {
            PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
            if (databaseValues == null)
            {
                tracking.State = EntityState.Detached;
            }
            else
            {
                PropertyValues originalValues = tracking.OriginalValues.Clone();
                tracking.OriginalValues.SetValues(databaseValues);
#if EF
                databaseValues.PropertyNames
                    .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
                databaseValues.Properties
                    .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
                    .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
            }
            break;
        }
    }
    return tracking;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now concurrency conflict can be resolved automatically and asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task SaveChangesAsync()
{
    using (AdventureWorks adventureWorks1 = new AdventureWorks())
    using (AdventureWorks adventureWorks2 = new AdventureWorks())
    {
        int id = 950;
        Product productCopy1 = await adventureWorks1.Products.FindAsync(id);
        Product productCopy2 = await adventureWorks2.Products.FindAsync(id);

        productCopy1.Name = nameof(productCopy1);
        productCopy1.ListPrice = 100;
        (await adventureWorks1.SaveChangesAsync()).WriteLine(); // 1

        productCopy2.Name = nameof(productCopy2);
        productCopy2.ProductSubcategoryID = 1;
        (await adventureWorks2.SaveChangesAsync(RefreshConflict.MergeClientAndStore)).WriteLine(); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (8) Optimistic Concurrency</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency-7/</guid><description>Conflicts can occur if the same data is read and changed concurrently. Generally, there are 2  approaches:</description><pubDate>Sat, 30 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-9-optimistic-concurrency&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-9-optimistic-concurrency&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Conflicts can occur if the same data is read and changed concurrently. Generally, there are 2 &lt;a href=&quot;https://en.wikipedia.org/wiki/Concurrency_control&quot;&gt;concurrency control&lt;/a&gt; approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pessimistic concurrency: one database client can lock the data being accessed, in order to prevent other database clients to change that same data concurrently.&lt;/li&gt;
&lt;li&gt;Optimistic concurrency: Data is not locked in the database for client to CRUD. Any database client is allowed to read and change any data concurrently. As a result, concurrency conflicts can happen. This is how EF/Core work with database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate the behavior of EF/Core for concurrency, the following DbReaderWriter type is defined as database CRUD client:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter : IDisposable
{
    private readonly DbContext context;

    internal DbReaderWriter(DbContext context) =&amp;gt; this.context = context;

    internal TEntity Read&amp;lt;TEntity&amp;gt;(params object[] keys) where TEntity : class =&amp;gt; 
        this.context.Set&amp;lt;TEntity&amp;gt;().Find(keys);

    internal int Write(Action change)
    {
        change();
        return this.context.SaveChanges();
    }

    internal DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class =&amp;gt; this.context.Set&amp;lt;TEntity&amp;gt;();

    public void Dispose() =&amp;gt; this.context.Dispose();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple DbReaderWriter instances can be be used to read and write data concurrently. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Concurrency
{
    internal static void NoCheck(
        DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
    {
        int id = 1;
        ProductCategory categoryCopy1 = readerWriter1.Read&amp;lt;ProductCategory&amp;gt;(id);
        ProductCategory categoryCopy2 = readerWriter2.Read&amp;lt;ProductCategory&amp;gt;(id);

        readerWriter1.Write(() =&amp;gt; categoryCopy1.Name = nameof(readerWriter1));
        // exec sp_executesql N&apos;SET NOCOUNT ON;
        // UPDATE [Production].[ProductCategory] SET [Name] = @p0
        // WHERE [ProductCategoryID] = @p1;
        // SELECT @@ROWCOUNT;
        // &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter1&apos;
        readerWriter2.Write(() =&amp;gt; categoryCopy2.Name = nameof(readerWriter2)); // Last client wins.
        // exec sp_executesql N&apos;SET NOCOUNT ON;
        // UPDATE [Production].[ProductCategory] SET [Name] = @p0
        // WHERE [ProductCategoryID] = @p1;
        // SELECT @@ROWCOUNT;
        // &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=1,@p0=N&apos;readerWriter2&apos;

        ProductCategory category3 = readerWriter3.Read&amp;lt;ProductCategory&amp;gt;(id);
        category3.Name.WriteLine(); // readerWriter2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, multiple DbReaderWriter instances read and write data concurrently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads category “Bikes”&lt;/li&gt;
&lt;li&gt;readerWriter2 reads category “Bikes”. These 2 entities are independent because they are are from different DbContext instances.&lt;/li&gt;
&lt;li&gt;readerWriter1 updates category’s name from “Bikes” to “readerWriter1”. As previously discussed, by default EF/Core locate the category with its primary key.&lt;/li&gt;
&lt;li&gt;In database, this category’s name is no longer “Bikes”&lt;/li&gt;
&lt;li&gt;readerWriter2 updates category’s name from “Bikes” to “readerWriter2”. It locates the category with its primary key as well. The primary key is unchanged, so the same category can be located and the name can be changed.&lt;/li&gt;
&lt;li&gt;So later when readerWriter3 reads the entity with the same primary key, the category entity’s Name is “readerWriter2”.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Detect Concurrency conflicts&lt;/h2&gt;
&lt;p&gt;Concurrency conflicts can be detected by checking entities’ property values besides primary keys. To required EF/Core to check a certain property, just add a System.ComponentModel.DataAnnotations.ConcurrencyCheckAttribute to it. Remember when defining ProductPhoto entity, its ModifiedDate has a [ConcurrencyCheck] attribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductPhoto
{
    [ConcurrencyCheck]
    public DateTime ModifiedDate { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This property is also called the concurrency token. When EF/Core translate changes of a photo, ModifiedDate property is checked along with the primary key to locate the photo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcurrencyCheck(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)
{
    int id = 1;
    ProductPhoto photoCopy1 = readerWriter1.Read&amp;lt;ProductPhoto&amp;gt;(id);
    ProductPhoto photoCopy2 = readerWriter2.Read&amp;lt;ProductPhoto&amp;gt;(id);

    readerWriter1.Write(() =&amp;gt;
    {
        photoCopy1.LargePhotoFileName = nameof(readerWriter1);
        photoCopy1.ModifiedDate = DateTime.Now;
    });
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
    // WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter1&apos;,@p1=&apos;2017-01-25 22:04:25.9292433&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
    readerWriter2.Write(() =&amp;gt;
    {
        photoCopy2.LargePhotoFileName = nameof(readerWriter2);
        photoCopy2.ModifiedDate = DateTime.Now;
    });
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[ProductPhoto] SET [LargePhotoFileName] = @p0, [ModifiedDate] = @p1
    // WHERE [ProductPhotoID] = @p2 AND [ModifiedDate] = @p3;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 datetime2(7),@p3 datetime2(7)&apos;,@p2=1,@p0=N&apos;readerWriter2&apos;,@p1=&apos;2017-01-25 22:04:59.1792263&apos;,@p3=&apos;2008-04-30 00:00:00&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the translated SQL statement, the WHERE clause contains primary key and the original concurrency token. The following is how EF/Core check the concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter2 reads the same photo with primary key 1, and modified date “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter1 locates the photo with primary key and original modified date, and update its large photo file name and modified date.&lt;/li&gt;
&lt;li&gt;In database the photo’s modified date is no longer the original value “2008-04-30 00:00:00”&lt;/li&gt;
&lt;li&gt;readerWriter2 tries to locate the photo with primary key and original modified date. However the provided modified date is outdated. EF/Core detect that 0 row is updated by the translated SQL, and throws DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See &lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkId=527962&quot;&gt;http://go.microsoft.com/fwlink/?LinkId=527962&lt;/a&gt; for information on understanding and handling optimistic concurrency exceptions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another option for concurrency check is System.ComponentModel.DataAnnotations.TimestampAttribute. It can only be used for a byte[] property, which is mapped from a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms182776.aspx&quot;&gt;rowversion&lt;/a&gt; (timestamp) column. For SQL database, these 2 terms, rowversion and timestamp, are the same thing. timestamp is just a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms177566.aspx&quot;&gt;synonym&lt;/a&gt; of rowversion data type. A row’s non-nullable rowversion column is a 8 bytes (binary(8)) counter maintained by database, its value increases for each change of the row.&lt;/p&gt;
&lt;p&gt;Microsoft’s AdventureWorks sample database does not have such a rowversion column, so create one for the Production.Product table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER TABLE [Production].[Product] ADD [RowVersion] rowversion NOT NULL
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then define the mapping property for Product entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Timestamp]
    public byte[] RowVersion { get; set; }

    [NotMapped]
    public string RowVersionString =&amp;gt;
        $&quot;0x{BitConverter.ToUInt64(this.RowVersion.Reverse().ToArray(), 0).ToString(&quot;X16&quot;)}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now RowVersion property is the concurrency token. Regarding database automatically increases the RowVersion value, Rowversion also has the [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute. The other RowVersionString property returns a readable representation of the byte array returned by RowVersion. It is not a part of the object-relational mapping, so it has a [NotMapped] attribute. The following example updates and and deletes the same product concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RowVersion(DbReaderWriter readerWriter1, DbReaderWriter readerWriter2)
{
    int id = 995;
    Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
    productCopy1.RowVersionString.WriteLine(); // 0x0000000000000803

    Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
    productCopy2.RowVersionString.WriteLine(); // 0x0000000000000803

    readerWriter1.Write(() =&amp;gt; productCopy1.Name = nameof(readerWriter1));
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // UPDATE [Production].[Product] SET [Name] = @p0
    // WHERE [ProductID] = @p1 AND [RowVersion] = @p2;
    // SELECT [RowVersion]
    // FROM [Production].[Product]
    // WHERE @@ROWCOUNT = 1 AND [ProductID] = @p1;
    // &apos;,N&apos;@p1 int,@p0 nvarchar(50),@p2 varbinary(8)&apos;,@p1=995,@p0=N&apos;readerWriter1&apos;,@p2=0x0000000000000803
    productCopy1.RowVersionString.WriteLine(); // 0x00000000000324B1
    readerWriter2.Write(() =&amp;gt; readerWriter2.Set&amp;lt;Product&amp;gt;().Remove(productCopy2));
    // exec sp_executesql N&apos;SET NOCOUNT ON;
    // DELETE FROM [Production].[Product]
    // WHERE [ProductID] = @p0 AND [RowVersion] = @p1;
    // SELECT @@ROWCOUNT;
    // &apos;,N&apos;@p0 int,@p1 varbinary(8)&apos;,@p0=995,@p1=0x0000000000000803
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When updating and deleting photo entities, its auto generated RowVersion property value is checked too. So this is how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads product with primary key 995 and row version 0x0000000000000803&lt;/li&gt;
&lt;li&gt;readerWriter2 reads product with the same primary key 995 and row version 0x0000000000000803&lt;/li&gt;
&lt;li&gt;readerWriter1 locates the photo with primary key and original row version, and update its name. Database automatically increases the photo’s row version. Since the row version is specified as [DatabaseGenerated(DatabaseGeneratedOption.Computed)], EF/Core also locate the photo with the primary key to query the increased row version, and update the entity at client side.&lt;/li&gt;
&lt;li&gt;In database the product’s row version is no longer 0x0000000000000803.&lt;/li&gt;
&lt;li&gt;Then readerWriter2 tries to locate the product with primary key and original row version, and delete it. No product can be found with outdated row version, EF/Core detect that 0 row is deleted, and throws DbUpdateConcurrencyException.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Resolve concurrency conflicts&lt;/h2&gt;
&lt;p&gt;DbUpdateConcurrencyException is thrown when SaveChanges detects concurrency conflict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore
{
    public class DbUpdateException : Exception
    {
        public virtual IReadOnlyList&amp;lt;EntityEntry&amp;gt; Entries { get; }

        // Other members.
    }

    public class DbUpdateConcurrencyException : DbUpdateException
    {
        // Members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inherited from DbUpdateException, DbUpdateConcurrencyException has an Entries property. Entries returns a sequence of EntityEntry instances, representing the conflicting entities’ tracking information. The basic idea of resolving concurrency conflicts, is to handle DbUpdateConcurrencyException and retry SaveChanges:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int Write(Action change, Action&amp;lt;DbUpdateConcurrencyException&amp;gt; handleException, int retryCount = 3)
    {
        change();
        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return this.context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception)
            {
                handleException(exception);
            }
        }
        return this.context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above Write overload, if SaveChanges throws DbUpdateConcurrencyException, the handleException function is called. This function is expected to handle the exception and resolve the conflicts properly. Then SaveChanges is called again. If the last retry of SaveChanges still throws DbUpdateConcurrencyException, the exception is thrown to the caller.&lt;/p&gt;
&lt;h3&gt;Retain database values (database wins)&lt;/h3&gt;
&lt;p&gt;Similar to previous examples, the following example has multiple DbReaderWriter instances to update a product concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UpdateProduct(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3,
    Action&amp;lt;EntityEntry&amp;gt; resolveConflicts)
{
    int id = 950;
    Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
    Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);

    readerWriter1.Write(() =&amp;gt;
    {
        productCopy1.Name = nameof(readerWriter1);
        productCopy1.ListPrice = 100.0000M;
    });
    readerWriter2.Write(
        change: () =&amp;gt;
        {
            productCopy2.Name = nameof(readerWriter2);
            productCopy2.ProductSubcategoryID = 1;
        },
        handleException: exception =&amp;gt;
        {
            EntityEntry tracking = exception.Entries.Single();
            Product original = (Product)tracking.OriginalValues.ToObject();
            Product current = (Product)tracking.CurrentValues.ToObject();
            Product database = productCopy1; // Values saved in database.
            $&quot;Original:  ({original.Name},   {original.ListPrice}, {original.ProductSubcategoryID}, {original.RowVersionString})&quot;
                        .WriteLine();
            $&quot;Database:  ({database.Name}, {database.ListPrice}, {database.ProductSubcategoryID}, {database.RowVersionString})&quot;
                .WriteLine();
            $&quot;Update to: ({current.Name}, {current.ListPrice}, {current.ProductSubcategoryID})&quot;
                .WriteLine();

            resolveConflicts(tracking);
        });

    Product resolved = readerWriter3.Read&amp;lt;Product&amp;gt;(id);
    $&quot;Resolved:  ({resolved.Name}, {resolved.ListPrice}, {resolved.ProductSubcategoryID}, {resolved.RowVersionString})&quot;
        .WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how it works with concurrency conflicts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;readerWriter1 reads product with primary key 950, and RowVersion 0x00000000000007D1&lt;/li&gt;
&lt;li&gt;readerWriter2 reads product with the same primary key 950, and RowVersion 0x00000000000007D1&lt;/li&gt;
&lt;li&gt;readerWriter1 locates product with primary key and original RowVersion 0x00000000000007D1, and updates product’s name and list price. Database automatically increases the product’s row version&lt;/li&gt;
&lt;li&gt;In database the product’s row version is no longer 0x00000000000007D1.&lt;/li&gt;
&lt;li&gt;readerWriter2 tries to locate product with primary key and original RowVersion, and update product’s name and subcategory.&lt;/li&gt;
&lt;li&gt;readerWriter2 fails to update product, because it cannot locate the product with original RowVersion 0x00000000000007D1. Again, no product can be found with outdated row version, DbUpdateConcurrencyException is thrown.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a result, the handleException function specified for readWriter2 is called, it retrieves the conflicting product’s tracking information from DbUpdateConcurrencyException.Entries, and logs these information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;product’s original property values read by readerWriter2 before the changes&lt;/li&gt;
&lt;li&gt;product’s property values in database at this moment, which are already updated readerWriter1&lt;/li&gt;
&lt;li&gt;product’s current property values after changes, which readerWriter2 fails to save to database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then handleException calls resolveConflicts function to actually resolve the conflict. Then readerWriter2 retries to save the product changes again. This time, SaveChanges should succeed, because there is no conflicts anymore (In this example, there are only 2 database clients reading/writing data concurrently. In reality, the concurrency can be higher, an appropriate retry count or retry strategy should be specified.). Eventually, readerWriter3 reads the product from database, verify its property values.&lt;/p&gt;
&lt;p&gt;There are several options to implement the resolveConflicts function to resolves the conflicts. One simple option, called “database wins”, is to simply give up the client update, and let database retain whatever values it has for that entity. This seems to be easy to just catch DbUpdateConcurrencyException and do nothing, then database naturally wins, and retains its values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int WriteDatabaseWins(Action change)
    {
        change();
        try
        {
            return this.context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            return 0; // this.context is in a corrupted state.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this way leaves the DbContext, the conflicting entity, and the entity’s tracking information in a corrupted state. For the caller, since the change saving is done, the entity’s property values should be in sync with database values, but the values are actually out of sync and still conflicting. Also, the entity has a tracking state Modified after change saving is done. So the safe approach is to reload and refresh the entity’s values and tracking information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DatabaseWins(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True

        tracking.Reload(); // Execute query.

        tracking.State.WriteLine(); // Unchanged
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // False
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UpdateProduct is called with a resolveConflicts function, which resolves the conflict by calling Reload method on the EntityEntry instance representing the conflicting product’s tracking information:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EntityEntry.Reload executes a SELECT statement to read the product’s property values from database, then refresh the product entity and all tracking information. The product’s property values, the tracked original property values before changes, the tracked current property values after changes, are all refreshed to the queried database values. The entity tracking state is also refreshed to Unchanged.&lt;/li&gt;
&lt;li&gt;At this moment, product has the same tracked original values and current values, as if it is just initially read from database, without changes.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, no changed entity is detected. SaveChanges succeeds without executing any SQL, and returns 0. As expected, readerWriter2 does not update any value to database, and all values in database are retained.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrtier1.&lt;/p&gt;
&lt;h3&gt;Overwrite database values (client wins)&lt;/h3&gt;
&lt;p&gt;Another simple option, called “client wins”, is to disregard values in database, and overwrite them with whatever data submitted from client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ClientWins(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        PropertyValues databaseValues = tracking.GetDatabaseValues();
        // Refresh original values, which go to WHERE clause of UPDATE statement.
        tracking.OriginalValues.SetValues(databaseValues);

        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // True
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036336)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter2, 256.4900, 1, 0x0000000000036337)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same conflict is resolved differently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version. This call does not impact the product values or tracking information.&lt;/li&gt;
&lt;li&gt;Manually set the tracked original property values to the queried database values. The entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product properties are tracked as modified.&lt;/li&gt;
&lt;li&gt;At this moment, the product has tracked original values updated, and keeps all tracked current values, as if it is read from database after readerWriter1 updates the name and list price, and then have all properties values changed.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. So EF/Core translate the product change to a UPDATE statement. In the SET clause, since there are 3 properties tracked as modified, 3 columns are set. In the WHERE clause, to locate the product, the tracked original row version has been set to the updated value from database. This time product can be located, and all 3 properties are updated. SaveChanges succeeds and returns 1. As expected, readerWriter2 updates all value to database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has all values updated by readerWrter2.&lt;/p&gt;
&lt;h3&gt;Merge with database values&lt;/h3&gt;
&lt;p&gt;A more complex but useful option, is to merge the client values and database values. For each property:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If original value is different from database value, which means database value is already updated by other concurrent client, then give up updating this property, and retain the database value&lt;/li&gt;
&lt;li&gt;If original value is the same as database value, which means no concurrency conflict for this property, then process normally to submit the change&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeClientAndDatabase(
    DbReaderWriter readerWriter1, DbReaderWriter readerWriter2, DbReaderWriter readerWriter3)
{
    UpdateProduct(readerWriter1, readerWriter2, readerWriter3, resolveConflicts: tracking =&amp;gt;
    {
        PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute query.
        PropertyValues originalValues = tracking.OriginalValues.Clone();
        // Refresh original values, which go to WHERE clause.
        tracking.OriginalValues.SetValues(databaseValues);
        // If database has an different value for a property, then retain the database value.
#if EF
        databaseValues.PropertyNames // Navigation properties are not included.
            .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
            .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
        databaseValues.Properties // Navigation properties are not included.
            .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
            .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
        tracking.State.WriteLine(); // Modified
        tracking.Property(nameof(Product.Name)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ListPrice)).IsModified.WriteLine(); // False
        tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified.WriteLine(); // True
    });
    // Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
    // Database:  (readerWriter1, 100.0000, 8, 0x0000000000036338)
    // Update to: (readerWriter2, 256.4900, 1)
    // Resolved:  (readerWriter1, 100.0000, 1, 0x0000000000036339)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Again, EntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, including the updated row version.&lt;/li&gt;
&lt;li&gt;Backup tracked original values, then refresh conflict.OriginalValues to the database values, so that these values can go to the translated WHERE clause. Again, the entity tracking state is still Changed. The original property values become all different from tracked current property values. So all product values are tracked as modified and should go to SET clause.&lt;/li&gt;
&lt;li&gt;For each property, if the backed original value is different from the database value, it means this property is changed by other client and there is concurrency conflict. In this case, revert this property’s tracking status to unmodified. The name and list price are reverted.&lt;/li&gt;
&lt;li&gt;At this moment, the product has tracked original values updated, and only keeps tracked current value of subcategory, as if it is read from database after readerWriter1 updates the name and list price, and then only have subcategory changed, which has no conflict.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product changes are detected to submit. Here only subcategory is updated to database. SaveChanges succeeds and returns 1. As expected, readerWriter2 only updates value without conflict, the other conflicted values are retained.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product, product has name and list price values updated by readerWrtier1, and has subcategory updated by readerWriter2.&lt;/p&gt;
&lt;h2&gt;Save changes with concurrency conflict handling&lt;/h2&gt;
&lt;p&gt;Similar to above DbReaderWriter.Write method, a general SaveChanges extension method for DbContext can be defined to handle concurrency conflicts and apply simple retry logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                resolveConflicts(exception.Entries);
            }
        }
        return context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To apply custom retry logic, Microsoft provides EnterpriseLibrary.TransientFaultHandling NuGet package (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn440728.aspx&quot;&gt;Exception Handling Application Block&lt;/a&gt;) for .NET Framework. It has been ported to .NET Core for this tutorial, as EnterpriseLibrary.TransientFaultHandling.Core NuGet package. can be used. With this library, a SaveChanges overload with customizable retry logic can be easily defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TransientDetection&amp;lt;TException&amp;gt; : ITransientErrorDetectionStrategy
    where TException : Exception
{
    public bool IsTransient(Exception ex) =&amp;gt; ex is TException;
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;&amp;gt; resolveConflicts, RetryStrategy retryStrategy)
    {
        RetryPolicy retryPolicy = new RetryPolicy(
            errorDetectionStrategy: new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(),
            retryStrategy: retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt;
            resolveConflicts(((DbUpdateConcurrencyException)e.LastException).Entries);
        return retryPolicy.ExecuteAction(context.SaveChanges);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ITransientErrorDetectionStrategy is the contract to detect each exception, and determine whether the exception is transient and the operation should be retried. Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryStrategy is the contract of retry logic. Then Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy executes the operation with the specified exception detection, exception handling, and retry logic.&lt;/p&gt;
&lt;p&gt;As discussed above, to resolve a concurrency conflict, the entity and its tracking information need to be refreshed. So the more specific SaveChanges overloads can be implemented by applying refresh for each conflict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum RefreshConflict
{
    StoreWins,

    ClientWins,

    MergeClientAndStore
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        return context.SaveChanges(
            conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryCount);
    }

    public static int SaveChanges(
        this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =&amp;gt;
            context.SaveChanges(
                conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryStrategy);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A RefreshConflict enumeration has to be defined with 3 members to represent the 3 options discussed above: database wins, client wind, merge client and database.. And here the Refresh method is an extension method for EntityEntry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static EntityEntry Refresh(this EntityEntry tracking, RefreshConflict refreshMode)
{
    switch (refreshMode)
    {
        case RefreshConflict.StoreWins:
        {
            // When entity is already deleted in database, Reload sets tracking state to Detached.
            // When entity is already updated in database, Reload sets tracking state to Unchanged.
            tracking.Reload(); // Execute SELECT.
            // Hereafter, SaveChanges ignores this entity.
            break;
        }
        case RefreshConflict.ClientWins:
        {
            PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
            if (databaseValues == null)
            {
                // When entity is already deleted in database, there is nothing for client to win against.
                // Manually set tracking state to Detached.
                tracking.State = EntityState.Detached;
                // Hereafter, SaveChanges ignores this entity.
            }
            else
            {
                // When entity is already updated in database, refresh original values, which go to in WHERE clause.
                tracking.OriginalValues.SetValues(databaseValues);
                // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
            }
            break;
        }
        case RefreshConflict.MergeClientAndStore:
        {
            PropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
            if (databaseValues == null)
            {
                // When entity is already deleted in database, there is nothing for client to merge with.
                // Manually set tracking state to Detached.
                tracking.State = EntityState.Detached;
                // Hereafter, SaveChanges ignores this entity.
            }
            else
            {
                // When entity is already updated, refresh original values, which go to WHERE clause.
                PropertyValues originalValues = tracking.OriginalValues.Clone();
                tracking.OriginalValues.SetValues(databaseValues);
                // If database has an different value for a property, then retain the database value.
#if EF
                databaseValues.PropertyNames // Navigation properties are not included.
                    .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
                databaseValues.Properties // Navigation properties are not included.
                    .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
                    .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
                // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
            }
            break;
        }
    }
    return tracking;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF already provides a System.Data.Entity.Core.Objects.RefreshMode enumeration, but it only has 2 members: StoreWins and ClientWins.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This Refresh extension method covers the update conflicts discussed above, as well as deletion conflicts. Now the these SaveChanges extension methods can be used to manage concurrency conflicts easily. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveChanges(AdventureWorks adventureWorks1, AdventureWorks adventureWorks2)
{
    int id = 950;
    Product productCopy1 = adventureWorks1.Products.Find(id);
    Product productCopy2 = adventureWorks2.Products.Find(id);

    productCopy1.Name = nameof(adventureWorks1);
    productCopy1.ListPrice = 100;
    adventureWorks1.SaveChanges();

    productCopy2.Name = nameof(adventureWorks2);
    productCopy2.ProductSubcategoryID = 1;
    adventureWorks2.SaveChanges(RefreshConflict.MergeClientAndStore);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (6) Query Data Loading</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading-7/</guid><description>After translated to SQL, in LINQ to Entities, sequence queries returning IQueryable&lt;T&gt; implements deferred execution too.</description><pubDate>Wed, 27 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-6-query-data-loading&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;EF Version of this article: &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-6-deferred-execution-laziness-loading-and-eager-loading&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-6-deferred-execution-laziness-loading-and-eager-loading&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After translated to SQL, in LINQ to Entities, sequence queries returning IQueryable&amp;lt;T&amp;gt; implements deferred execution too.&lt;/p&gt;
&lt;h2&gt;Deferred execution&lt;/h2&gt;
&lt;p&gt;As previous part discussed, when defining a LINQ to Entities query represented by IQueryable&amp;lt;T&amp;gt;, an expression tree is built, there is no query execution. The execution is deferred until trying to pull the results from the query.&lt;/p&gt;
&lt;h3&gt;Iterator pattern&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; is derived from IEnumerable&amp;lt;T&amp;gt;, so values can be pulled from IQueryable&amp;lt;T&amp;gt; with the standard iterator pattern. When trying to pull the first value, EF Core translates LINQ to Entities query to SQL, and execute SQL in the database. The implementation can be demonstrated with the Iterator&amp;lt;T&amp;gt; type from the LINQ to Objects chapter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class QueryableExtensions
{
    public static IEnumerator&amp;lt;TEntity&amp;gt; GetEntityIterator&amp;lt;TEntity&amp;gt;(
        this IQueryable&amp;lt;TEntity&amp;gt; query, DbContext dbContext) where TEntity : class
    {
        &quot;| |_Compile LINQ expression tree to database expression tree.&quot;.WriteLine();
        (SelectExpression DatabaseExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt; Parameters) compilation =
            dbContext.Compile(query.Expression);

        IEnumerator&amp;lt;TEntity&amp;gt; entityIterator = null;
        return new Iterator&amp;lt;TEntity&amp;gt;(
            start: () =&amp;gt;
            {
                &quot;| |_Generate SQL from database expression tree.&quot;.WriteLine();
                IRelationalCommand sql = dbContext.Generate(
                    compilation.DatabaseExpression, compilation.Parameters);
                IEnumerable&amp;lt;TEntity&amp;gt; sqlQuery = dbContext.Set&amp;lt;TEntity&amp;gt;().FromSql(
                    sql: sql.CommandText,
                    parameters: compilation.Parameters
                        .Select(parameter =&amp;gt; new SqlParameter(parameter.Key, parameter.Value)).ToArray());
                entityIterator = sqlQuery.GetEnumerator();
                &quot;| |_Execute generated SQL.&quot;.WriteLine();
            },
            moveNext: () =&amp;gt; entityIterator.MoveNext(),
            getCurrent: () =&amp;gt;
            {
                $&quot;| |_Materialize data row to {typeof(TEntity).Name} entity.&quot;.WriteLine();
                return entityIterator.Current;
            },
            dispose: () =&amp;gt; entityIterator.Dispose(),
            end: () =&amp;gt; &quot;  |_End.&quot;.WriteLine()).Start();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example executes Where and Take query to load 3 products with more than 10 characters in name. It demonstrates how to pull the results from IQueryable&amp;lt;T&amp;gt; with the iterator pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Loading
{
    internal static void DeferredExecution(AdventureWorks adventureWorks)
    {
        IQueryable&amp;lt;Product&amp;gt; categories = adventureWorks.Products
            .Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
            .Take(3);
        &quot;Iterator - Create from LINQ to Entities query.&quot;.WriteLine();
        using (IEnumerator&amp;lt;Product&amp;gt; iterator = categories.GetEntityIterator(adventureWorks)) // Compile query.
        {
            int index = 0;
            while (new Func&amp;lt;bool&amp;gt;(() =&amp;gt;
                {
                    bool moveNext = iterator.MoveNext();
                    $&quot;|_Iterator - [{index++}] {nameof(IEnumerator&amp;lt;Product&amp;gt;.MoveNext)}: {moveNext}.&quot;.WriteLine();
                    return moveNext; // Generate SQL when first time called.
                })())
            {
                Product product = iterator.Current;
                $&quot;| |_Iterator - [{index}] {nameof(IEnumerator&amp;lt;Product&amp;gt;.Current)}: {product.Name}.&quot;.WriteLine();
            }
        }
        // Iterator - Create from LINQ to Entities query.
        // | |_Compile LINQ expression tree to database expression tree.
        // |_Iterator - [0] MoveNext: True.
        // | |_Generate SQL from database expression tree.
        // | |_Execute generated SQL.
        // | |_Materialize data row to Product entity.
        // | |_Iterator - [0] Current: ML Crankset.
        // |_Iterator - [1] MoveNext: True.
        // | |_Materialize data row to Product entity.
        // | |_Iterator - [1] Current: HL Crankset.
        // |_Iterator - [2] MoveNext: True.
        // | |_Materialize data row to Product entity.
        // | |_Iterator - [2] Current: Touring-2000 Blue, 60.
        // |_Iterator - [3] MoveNext: False.
        //   |_End.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here for demonstration purpose, the GetEntityIterator extension method of IQueryable&amp;lt;T&amp;gt; is called instead of GetEnumerator. In EF Core, when the iterator is created from IQueryable&amp;lt;T&amp;gt;, the LINQ query expression tree is compiled to database query expression tree. Later, when the iterator’s MoveNext method is called for the first time, the SQL query is generated and executed. In each iteration, an entity is materialized from the SQL execution result.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF is slightly more deferred then EF Core. The query compilation, SQL generation, and SQL execution all start when the iterator’s MoveNext method is called for the first time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lazy evaluation vs. eager evaluation&lt;/h3&gt;
&lt;p&gt;Deferred execution can be either lazy evaluation or eager evaluation. Internally, EF/Core call ADP.NET APIs to execute query, including DbDataReader, etc. DbDataReader is abstract class. EF/Core SQL database provider actually uses SqlDataReader in ADO.NET, which is derived from DbDataReader, to load the database query results. By default, when SqlDataReader starts to read data, it &lt;a href=&quot;http://blogs.msdn.com/b/adonet/archive/2012/04/20/using-sqldatareader-s-new-async-methods-in-net-4-5-beta.aspx&quot;&gt;streams&lt;/a&gt; a number of rows to local buffer through &lt;a href=&quot;https://en.wikipedia.org/wiki/Tabular_Data_Stream&quot;&gt;TDS (tabular data stream) protocol&lt;/a&gt;. So by default, LINQ to Entities’ deferred execution is neither eager (load all rows when pulling the first result), nor totally lazy (load 1 result when pulling each result).&lt;/p&gt;
&lt;p&gt;When retry logic is specified for connection resiliency, EF/Core become eager evaluation. When trying to pull the first query result, EF/Core call DbDataReader to load all results from database.&lt;/p&gt;
&lt;h2&gt;Explicit loading&lt;/h2&gt;
&lt;p&gt;After an entity is queried, its related entities can be loaded through the navigation property. DbContext.Entry method accepts an entity of type TEntity, and returns Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry&amp;lt;TEntity&amp;gt;, which represents that entity’s tracking and loading information. EntityEntry&amp;lt;TEntity&amp;gt; provides a Reference method to return Microsoft.EntityFrameworkCore.ChangeTracking.ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt; instance, which represents the tracking and loading information of a single related entity from reference navigation property. EntityEntry&amp;lt;TEntity&amp;gt; also provides a Collection method to return Microsoft.EntityFrameworkCore.ChangeTracking.ReferenceEntry.CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;, which represents the tracking and loading information of multiple related entities from collection navigation property. These related entities in the navigation properties can be manually loaded by calling ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Load and CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;.Load:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExplicitLoading(AdventureWorks adventureWorks)
{
    ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
    // SELECT TOP(1) [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [p]
    subcategory.Name.WriteLine();

    adventureWorks
        .Entry(subcategory) // Return EntityEntry&amp;lt;ProductSubcategory&amp;gt;.
        .Reference(entity =&amp;gt; entity.ProductCategory) // Return ReferenceEntry&amp;lt;ProductSubcategory, ProductCategory&amp;gt;.
        .Load(); // Execute query.
    // exec sp_executesql N&apos;SELECT [e].[ProductCategoryID], [e].[Name]
    // FROM [Production].[ProductCategory] AS [e]
    // WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
    subcategory.ProductCategory.Name.WriteLine();

    adventureWorks
        .Entry(subcategory) // Return EntityEntry&amp;lt;ProductSubcategory&amp;gt;.
        .Collection(entity =&amp;gt; entity.Products) // Return CollectionEntry&amp;lt;ProductSubcategory, Product&amp;gt;.
        .Load(); // Execute query.
    // exec sp_executesql N&apos;SELECT [e].[ProductID], [e].[ListPrice], [e].[Name], [e].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [e]
    // WHERE [e].[ProductSubcategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
    subcategory.Products.WriteLines(product =&amp;gt; product.Name);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the Load method is called, the related entities are queried, and become available through the navigation properties. Besides loading the full entities, explicit lazy loading also support custom query. The following example uses the reference navigation property and collection navigation property as LINQ to Entities data sources, by calling ReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Query and CollectionEntry&amp;lt;TEntity, TProperty&amp;gt;.Query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExplicitLoadingWithQuery(AdventureWorks adventureWorks)
{
    ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
    // SELECT TOP(1) [p].[ProductSubcategoryID], [p].[Name], [p].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [p]
    subcategory.Name.WriteLine();
    string categoryName = adventureWorks
        .Entry(subcategory).Reference(entity =&amp;gt; entity.ProductCategory)
        .Query() // Return IQueryable&amp;lt;ProductCategory&amp;gt;.
        .Select(category =&amp;gt; category.Name).Single(); // Execute query.
    // exec sp_executesql N&apos;SELECT TOP(2) [e].[Name]
    // FROM [Production].[ProductCategory] AS [e]
    // WHERE [e].[ProductCategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
    categoryName.WriteLine();

    IQueryable&amp;lt;string&amp;gt; products = adventureWorks
        .Entry(subcategory).Collection(entity =&amp;gt; entity.Products)
        .Query() // Return IQueryable&amp;lt;Product&amp;gt;.
        .Select(product =&amp;gt; product.Name); // Execute query.
    // exec sp_executesql N&apos;SELECT [e].[Name]
    // FROM [Production].[Product] AS [e]
    // WHERE [e].[ProductSubcategoryID] = @__get_Item_0&apos;,N&apos;@__get_Item_0 int&apos;,@__get_Item_0=1
    products.WriteLines();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the above entry types are named with the Db prefix: DbEntityEntry&amp;lt;TEntity&amp;gt;, DbReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;, DbCollectionEntry&amp;lt;TEntity, TElement&amp;gt;. And they are under System.Data.Entity.Infrastructure namespace.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Eager loading&lt;/h2&gt;
&lt;p&gt;In explicit loading, after an entity is queried, its related entities are loaded separately. In eager loading, when an entity is queried, its related entities are loaded during the same query. To enable eager loading, call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions’ Include method, which is an extension method for IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingWithInclude(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategoriesWithCategory = adventureWorks.ProductSubcategories
        .Include(subcategory =&amp;gt; subcategory.ProductCategory);
    subcategoriesWithCategory.WriteLines(subcategory =&amp;gt;
        $&quot;{subcategory.ProductCategory.Name}: {subcategory.Name}&quot;);
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID], [p].[ProductCategoryID], [p].[Name]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // INNER JOIN [Production].[ProductCategory] AS [p] ON [subcategory].[ProductCategoryID] = [p].[ProductCategoryID]

    IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategoriesWithProducts = adventureWorks.ProductSubcategories
        .Include(subcategory =&amp;gt; subcategory.Products);
    subcategoriesWithProducts.WriteLines(subcategory =&amp;gt; $@&quot;{subcategory.Name}: {string.Join(
        &quot;, &quot;, subcategory.Products.Select(product =&amp;gt; product.Name))}&quot;);
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // ORDER BY [subcategory].[ProductSubcategoryID]

    // SELECT [p].[ProductID], [p].[ListPrice], [p].[Name], [p].[ProductSubcategoryID], [p].[RowVersion]
    // FROM [Production].[Product] AS [p]
    // WHERE EXISTS (
    //    SELECT 1
    //    FROM [Production].[ProductSubcategory] AS [subcategory]
    //    WHERE [p].[ProductSubcategoryID] = [subcategory].[ProductSubcategoryID])
    // ORDER BY [p].[ProductSubcategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eager loading related entity through reference navigation property is translated to INNER JOIN. Eager loading through collection navigation property is translated to 2 SQL queries for 2 types of entities. More query methods can be chained after calling Include.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As fore mentioned, EF always translates LINQ to Entities queries to remote query. In EF, eager loading is translated to a single LEFT OUTER JOIN query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In EF Core, ThenInclude can be called for eager loading of multiple levels of related entities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingMultipleLevels(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; products = adventureWorks.Products
        .Include(product =&amp;gt; product.ProductProductPhotos)
        .ThenInclude(productProductPhoto =&amp;gt; productProductPhoto.ProductPhoto);
    products.WriteLines(product =&amp;gt; $@&quot;{product.Name}: {string.Join(
        &quot;, &quot;, 
        product.ProductProductPhotos.Select(productProductPhoto =&amp;gt; 
            productProductPhoto.ProductPhoto.LargePhotoFileName))}&quot;);
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ProductID]

    // SELECT [p].[ProductID], [p].[ProductPhotoID], [p0].[ProductPhotoID], [p0].[LargePhotoFileName], [p0].[ModifiedDate]
    // FROM [Production].[ProductProductPhoto] AS [p]
    // INNER JOIN [Production].[ProductPhoto] AS [p0] ON [p].[ProductPhotoID] = [p0].[ProductPhotoID]
    // WHERE EXISTS (
    //    SELECT 1
    //    FROM [Production].[Product] AS [product]
    //    WHERE [p].[ProductID] = [product].[ProductID])
    // ORDER BY [p].[ProductID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, Include with Select subquery can load multiple levels of related entities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingMultipleLevels(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; products = adventureWorks.Products
        .Include(product =&amp;gt; product.ProductProductPhotos
            .Select(productProductPhoto =&amp;gt; productProductPhoto.ProductPhoto));
    products.WriteLines(product =&amp;gt; $@&quot;{product.Name}: {string.Join(
        &quot;, &quot;, 
        product.ProductProductPhotos.Select(productProductPhoto =&amp;gt; 
            productProductPhoto.ProductPhoto.LargePhotoFileName))}&quot;);
    // SELECT 
    //    [Project1].[ProductID] AS [ProductID], 
    //    [Project1].[Name] AS [Name], 
    //    [Project1].[ListPrice] AS [ListPrice], 
    //    [Project1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    //    [Project1].[RowVersion] AS [RowVersion], 
    //    [Project1].[C1] AS [C1], 
    //    [Project1].[ProductID1] AS [ProductID1], 
    //    [Project1].[ProductPhotoID] AS [ProductPhotoID], 
    //    [Project1].[ProductPhotoID1] AS [ProductPhotoID1], 
    //    [Project1].[LargePhotoFileName] AS [LargePhotoFileName], 
    //    [Project1].[ModifiedDate] AS [ModifiedDate]
    //    FROM ( SELECT 
    //        [Extent1].[ProductID] AS [ProductID], 
    //        [Extent1].[Name] AS [Name], 
    //        [Extent1].[ListPrice] AS [ListPrice], 
    //        [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    //        [Extent1].[RowVersion] AS [RowVersion], 
    //        [Join1].[ProductID] AS [ProductID1], 
    //        [Join1].[ProductPhotoID1] AS [ProductPhotoID], 
    //        [Join1].[ProductPhotoID2] AS [ProductPhotoID1], 
    //        [Join1].[LargePhotoFileName] AS [LargePhotoFileName], 
    //        [Join1].[ModifiedDate] AS [ModifiedDate], 
    //        CASE WHEN ([Join1].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    //        FROM  [Production].[Product] AS [Extent1]
    //        LEFT OUTER JOIN  (SELECT [Extent2].[ProductID] AS [ProductID], [Extent2].[ProductPhotoID] AS [ProductPhotoID1], [Extent3].[ProductPhotoID] AS [ProductPhotoID2], [Extent3].[LargePhotoFileName] AS [LargePhotoFileName], [Extent3].[ModifiedDate] AS [ModifiedDate]
    //            FROM  [Production].[ProductProductPhoto] AS [Extent2]
    //            INNER JOIN [Production].[ProductPhoto] AS [Extent3] ON [Extent2].[ProductPhotoID] = [Extent3].[ProductPhotoID] ) AS [Join1] ON [Extent1].[ProductID] = [Join1].[ProductID]
    //    )  AS [Project1]
    //    ORDER BY [Project1].[ProductID] ASC, [Project1].[C1] ASC
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Lazy loading&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;EF also supports lazy loading. When an entity’s navigation property is accessed, the related entities are queried and loaded automatically:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LazyLoading(AdventureWorks adventureWorks)
{
    ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
    // SELECT TOP (1) 
    //    [c].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    //    [c].[Name] AS [Name], 
    //    [c].[ProductCategoryID] AS [ProductCategoryID]
    //    FROM [Production].[ProductSubcategory] AS [c]
    subcategory.Name.WriteLine();

    ProductCategory category = subcategory.ProductCategory; // Execute query.
    // exec sp_executesql N&apos;SELECT 
    //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[ProductCategory] AS [Extent1]
    //    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
    category.Name.WriteLine();

    ICollection&amp;lt;Product&amp;gt; products = subcategory.Products; // Execute query.
    // exec sp_executesql N&apos;SELECT 
    //    [Extent1].[ProductID] AS [ProductID], 
    //    [Extent1].[Name] AS [Name], 
    //    [Extent1].[ListPrice] AS [ListPrice], 
    //    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE [Extent1].[ProductSubcategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
    products.WriteLines(product =&amp;gt; product.Name);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The N + 1 problem&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes lazy loading can cause the “N + 1 queries” problem. The following example queries the subcategories, and pulls each subcategory’s information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MultipleLazyLoading(AdventureWorks adventureWorks)
{
    ProductSubcategory[] subcategories = adventureWorks.ProductSubcategories.ToArray(); // Execute query.
    // SELECT 
    //    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    //    [Extent1].[Name] AS [Name], 
    //    [Extent1].[ProductCategoryID] AS [ProductCategoryID]
    //    FROM [Production].[ProductSubcategory] AS [Extent1]

    subcategories.WriteLines(subcategory =&amp;gt; 
        $&quot;{subcategory.Name} ({subcategory.ProductCategory.Name})&quot;); // Execute query.
    // exec sp_executesql N&apos;SELECT 
    //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[ProductCategory] AS [Extent1]
    //    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1

    // exec sp_executesql N&apos;SELECT 
    //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[ProductCategory] AS [Extent1]
    //    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=2

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When loading the subcategories, 1 database query is executed. When each subcategory’s related category is pulled through the navigation property, it is loaded instantly, if not loaded yet. So in total there are N queries for related categories + 1 query for subcategories executed. For better performance in this kind of scenario, eager loading or inner join should be used to load all entities and related entities with 1 single query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Disable lazy loading&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;There are some scenarios where lazy loading needs to be disabled, like entity serialization. There are several ways to disable lazy loading for different scopes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To globally disable lazy loading for specific navigation properties, just do not mark it as virtual, so that the derived proxy entity cannot override it with the lazy load implementation.&lt;/li&gt;
&lt;li&gt;To disable lazy loading for specific DbContext or specific query, call DbContext.Configuration to get a DbConfiguration instance, and set its LazyLoadingEnabled property to false.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void DisableLazyLoading(AdventureWorks adventureWorks)
{
    adventureWorks.Configuration.LazyLoadingEnabled = false;
    ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Execute query.
  
    ProductCategory category = subcategory.ProductCategory; // No query.
    (category == null).WriteLine(); // True

    ICollection&amp;lt;Product&amp;gt; products = subcategory.Products; // No query.
    (products == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (7) Data Changes and Transactions</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions-7/</guid><description>Besides LINQ to Entities queries, EF/Core also provides rich APIs for data changes, with imperative paradigm.</description><pubDate>Wed, 27 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;EF version of this article: &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-7-data-changes&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-7-data-changes&lt;/a&gt; and &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-8-transactions&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-8-transactions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Besides LINQ to Entities queries, EF/Core also provides rich APIs for data changes, with imperative paradigm.&lt;/p&gt;
&lt;h2&gt;Repository pattern and unit of work pattern&lt;/h2&gt;
&lt;p&gt;In EF/Core, DbSet&amp;lt;T&amp;gt; implements &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff649690.aspx&quot;&gt;repository pattern&lt;/a&gt;. Repositories can centralize data access for applications, and connect between the data source and the business logic. A DbSet&amp;lt;T&amp;gt; instance can be mapped to a database table, which is a repository for data &lt;a href=&quot;https://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD (create, read, update and delete)&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore
{
    public abstract class DbSet&amp;lt;TEntity&amp;gt; : IQueryable&amp;lt;TEntity&amp;gt; // Other interfaces.
        where TEntity : class
    {
        public virtual TEntity Find(params object[] keyValues);

        public virtual EntityEntry&amp;lt;TEntity&amp;gt; Add(TEntity entity);

        public virtual void AddRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        public virtual EntityEntry&amp;lt;TEntity&amp;gt; Remove(TEntity entity);

        public virtual void RemoveRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt;, so that DbSet&amp;lt;T&amp;gt; can represent the data source to read from. DbSet&amp;lt;T&amp;gt;.Find is also provided to read entity by the primary keys. After reading, the retrieved data can be changed. Add and AddRange methods track the specified entities as to be created in the repository. Remove and RemoveRange methods track the specified entities as to be deleted in the repository.&lt;/p&gt;
&lt;p&gt;As fore mentioned, a &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt; is a collection of data operations that should together or fail together as a unit. DbContext implements unit of work pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore
{
    public class DbContext : IDisposable, IInfrastructure&amp;lt;IServiceProvider&amp;gt;
    {
        public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;

        public virtual ChangeTracker ChangeTracker { get; }

        public virtual int SaveChanges();

        public virtual void Dispose();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the mapping of database, DbContext’s Set method returns the specified entity’s repositories. For example, calling AdventureWorks.Products is equivalent to calling AdventureWorks.Set&amp;lt;Product&amp;gt;. The entities tracking is done at the DbContext level, by its ChangeTracker. When DbContext.Submit is called, the tracked changes are submitted to database. When a unit of work is done, DbContext should be disposed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the members of DbSet&amp;lt;TEntity&amp;gt; and DbContext have slightly different signatures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class DbSet&amp;lt;TEntity&amp;gt; : DbQuery&amp;lt;TEntity&amp;gt;, IQueryable&amp;lt;TEntity&amp;gt; // Other interfaces.
        where TEntity : class
    {
        public virtual TEntity Find(params object[] keyValues);

        public virtual TEntity Add(TEntity entity);

        public virtual IEnumerable&amp;lt;TEntity&amp;gt; AddRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        public virtual TEntity Remove(TEntity entity);

        public virtual IEnumerable&amp;lt;TEntity&amp;gt; RemoveRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        // Other members.
    }

    public class DbContext : IDisposable // Other interfaces.
    {
        public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;

        public DbChangeTracker ChangeTracker { get; }

        public virtual int SaveChanges();

        public void Dispose();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Track entities and changes&lt;/h2&gt;
&lt;p&gt;DbContext.ChangeTracker property returns Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker, which can track entities for the source DbContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
    public class ChangeTracker : IInfrastructure&amp;lt;IStateManager&amp;gt;
    {
        public virtual IEnumerable&amp;lt;EntityEntry&amp;gt; Entries();

        public virtual IEnumerable&amp;lt;EntityEntry&amp;lt;TEntity&amp;gt;&amp;gt; Entries&amp;lt;TEntity&amp;gt;() where TEntity : class;

        public virtual void DetectChanges();

        public virtual bool HasChanges();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each entity’s loading and tracking information is represented by Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry or Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry&amp;lt;TEntity&amp;gt;. The following is the non generic EntityEntry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
    public class EntityEntry : IInfrastructure&amp;lt;InternalEntityEntry&amp;gt;
    {
        public virtual EntityState State { get; set; }

        public virtual object Entity { get; }

        public virtual PropertyEntry Property(string propertyName);

        public virtual PropertyValues CurrentValues { get; }

        public virtual PropertyValues OriginalValues { get; }

        public virtual PropertyValues GetDatabaseValues();

        public virtual void Reload();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides the loading information APIs discussed in previous part, EntityEntry also provides rich APIs for entity’s tracking information and state management:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;State returns the entity’s tracking state: Detached, Unchanged, Added, Deleted, or Modified.&lt;/li&gt;
&lt;li&gt;Entity property returns the tracked entity&lt;/li&gt;
&lt;li&gt;Property returns the specified property’s tracking information.&lt;/li&gt;
&lt;li&gt;CurrentValues returns the tracked entity’s current property values.&lt;/li&gt;
&lt;li&gt;OriginalValues returns the tracked entity’s original property values&lt;/li&gt;
&lt;li&gt;GetDatabaseValues instantly execute a SQL query to read entity’s property values from database, without updating current entity’s property values and tracking information.&lt;/li&gt;
&lt;li&gt;Reload also executes a SQL query to read the database values, and also update current entity’s property values, and all tracking information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The generic EntityEntry&amp;lt;TEntity&amp;gt; is just stronger typing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
    public class EntityEntry&amp;lt;TEntity&amp;gt; : EntityEntry where TEntity : class
    {
        public virtual TEntity Entity { get; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned in data loading part, DbContext.Entry also accepts an entity and return its EntityEntry&amp;lt;TEntity&amp;gt;/EntityEntry.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the types involved above are named with Db prefix: DbChangeTracker, DbEntityEntry, DbEntityEntry&amp;lt;TEntity&amp;gt;, DbPropertyEntry, DbPropertyValues, with similar members.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Track entities&lt;/h3&gt;
&lt;p&gt;By default, all entities read from repositories are tracked by the source DbContext. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Tracking
{
    internal static void EntitiesFromSameDbContext(AdventureWorks adventureWorks)
    {
        Product productById = adventureWorks.Products
            .Single(product =&amp;gt; product.ProductID == 999);
        adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1

        Product productByName = adventureWorks.Products
            .Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
        adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
        object.ReferenceEquals(productById, productByName).WriteLine(); // True
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The single result from the first LINQ to Entities query is tracked by DbContext. Later, the second query has a single result too. EF/Core identifies both results map to the same data row of the same table, so they are reference to the same entity instance.&lt;/p&gt;
&lt;p&gt;If data from repositories are not entities mapping to table rows, they cannot be tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ObjectsFromSameDbContext(AdventureWorks adventureWorks)
{
    var productById = adventureWorks.Products
        .Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
        .Single(product =&amp;gt; product.ProductID == 999);
    var productByName = adventureWorks.Products
        .Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
        .Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
    adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0
    object.ReferenceEquals(productById, productByName).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here data is queries from repositories, and anonymous type instances are constructed on the fly. EF/Core cannot decide if 2 arbitrary instances semantically represent the same piece of data in remote database. This time 2 query results are independent from each other.&lt;/p&gt;
&lt;p&gt;Since the tracking is at DbContext scope. Entities of different DbContext instances belong to different units of work, and do not interfere each other:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EntitiesFromMultipleDbContexts()
{
    Product productById;
    Product productByName;
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        productById = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999);
    }
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        productByName = adventureWorks.Products.Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
    }
    object.ReferenceEquals(productById, productByName).WriteLine(); // False.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Track entity changes and property changes&lt;/h3&gt;
&lt;p&gt;The following example demonstrate CRUD operations in the product repository, then examine all the tracking information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EntityChanges(AdventureWorks adventureWorks)
{
    Product create = new Product() { Name = nameof(create), ListPrice = 1 };
    adventureWorks.Products.Add(create); // Create locally.
    Product read = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999); // Read from remote to local.
    IQueryable&amp;lt;Product&amp;gt; update = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Contains(&quot;HL&quot;));
    update.ForEach(product =&amp;gt; product.ListPrice += 100); // Update locally.
    IQueryable&amp;lt;Product&amp;gt; delete = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Contains(&quot;ML&quot;));
    adventureWorks.Products.RemoveRange(delete); // Delete locally.

    adventureWorks.ChangeTracker.HasChanges().WriteLine(); // True
    adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
    {
        Product changed = tracking.Entity;
        switch (tracking.State)
        {
            case EntityState.Added:
            case EntityState.Deleted:
            case EntityState.Unchanged:
                $&quot;{tracking.State}: {(changed.ProductID, changed.Name, changed.ListPrice)}&quot;.WriteLine();
                break;
            case EntityState.Modified:
                Product original = (Product)tracking.OriginalValues.ToObject();
                $&quot;{tracking.State}: {(original.ProductID, original.Name, original.ListPrice)} =&amp;gt; {(changed.ProductID, changed.Name, changed.ListPrice)}&quot;
                    .WriteLine();
                break;
        }
    });
    // Added: (-2147482647, toCreate, 1)
    // Unchanged: (999, Road-750 Black, 52, 539.9900)
    // Modified: (951, HL Crankset, 404.9900) =&amp;gt; (951, HL Crankset, 504.9900)
    // Modified: (996, HL Bottom Bracket, 121.4900) =&amp;gt; (996, HL Bottom Bracket, 221.4900)
    // Deleted: (950, ML Crankset, 256.4900)
    // Deleted: (995, ML Bottom Bracket, 101.2400)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an entity is not read from a DbContext instance’s repositories, then it has nothing to do with that unit of work, and apparently is not tracked by that DbContext instance. DbSet&amp;lt;T&amp;gt; provides an Attach method to place an entity to the repository, and the DbContext tracks the entity as the Unchanged state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Attach(AdventureWorks adventureWorks)
{
    Product product = new Product() { ProductID = 950, Name = &quot;ML Crankset&quot;, ListPrice = 539.99M };
    adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0

    adventureWorks.Products.Attach(product);
    adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
    adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State.WriteLine(); // Unchanged
    product.Name = &quot;After attaching&quot;;
    adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State.WriteLine(); // Modified
    adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().WriteLines(tracking =&amp;gt;
        $&quot;{tracking.State}: {tracking.OriginalValues[nameof(Product.Name)]} =&amp;gt; {tracking.CurrentValues[nameof(Product.Name)]}&quot;);
    // Modified: ML Crankset =&amp;gt; After attaching
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Track relationship changes&lt;/h3&gt;
&lt;p&gt;The relationship of entities is also tracked. Remember Product’s foreign key ProductSubcategoryID is nullable. The following example reads a subcategory and its products, then delete the relationship. As a result, each navigation property is cleared to empty collection or null. And each related subcategory’s foreign key property value is synced to null, which is tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RelationshipChanges(AdventureWorks adventureWorks)
{
    ProductSubcategory subcategory = adventureWorks.ProductSubcategories
        .Include(entity =&amp;gt; entity.Products).Single(entity =&amp;gt; entity.ProductSubcategoryID == 8);
    subcategory.Products.Count.WriteLine(); // 2
    subcategory.Products
        .All(product =&amp;gt; product.ProductSubcategory == subcategory).WriteLine(); // True

    subcategory.Products.Clear();
    // Equivalent to: subcategory.Products.ForEach(product =&amp;gt; product.ProductSubcategory = null);
    subcategory.Products.Count.WriteLine(); // 0
    subcategory.Products
        .All(product =&amp;gt; product.ProductSubcategory == null).WriteLine(); // True
    adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
    {
        Product original = (Product)tracking.OriginalValues.ToObject();
        Product changed = tracking.Entity;
        $&quot;{tracking.State}: {(original.ProductID, original.Name, original.ProductSubcategoryID)} =&amp;gt; {(changed.ProductID, changed.Name, changed.ProductSubcategoryID)}&quot;.WriteLine();
    });
    // Modified: (950, ML Crankset, 8) =&amp;gt; (950, ML Crankset, )
    // Modified: (951, HL Crankset, 8) =&amp;gt; (951, HL Crankset, )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Enable and disable tracking&lt;/h3&gt;
&lt;p&gt;DbContext’s default behavior is to track all changes automatically. This can be turned off if not needed. To disable tracking for specific entities queried from repository, call the EntityFrameworkQueryableExtensions.AsNoTracking extension method for IQueryable&amp;lt;T&amp;gt; query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsNoTracking(AdventureWorks adventureWorks)
{
    Product untracked = adventureWorks.Products.AsNoTracking().First();
    adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tracking can also be enabled or disabled at the DbContext scope, by setting the ChangeTracker.AutoDetectChangesEnabled property to true or false. The default value of ChangeTracker.AutoDetectChangesEnabled is true, so usually it is not needed to manually detect changes by calling ChangeTracker.DetectChanges method. The changes are automatically detected when DbContext.SubmitChanges is called. The changes are also automatically detected when tracking information is calculated, for example, when calling ChangeTracker.Entries, DbContext.Entry, etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the switch is DbContext.Configuration.AutoDetectChangesEnabled. And when AutoDetectChangesEnabled is true (by default), DetectChanges is called much more frequently than in EF Core.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If needed, changes and be manually tracked by calling ChangeTracker.DetectChanges method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DetectChanges(AdventureWorks adventureWorks)
{
    adventureWorks.ChangeTracker.AutoDetectChangesEnabled = false;
    Product product = adventureWorks.Products.First();
    product.ListPrice += 100;
    adventureWorks.ChangeTracker.HasChanges().WriteLine(); // False
    adventureWorks.ChangeTracker.DetectChanges();
    adventureWorks.ChangeTracker.HasChanges().WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Change data&lt;/h2&gt;
&lt;p&gt;To change the data in the database, just create a DbContext instance, change the data in its repositories, and call DbContext.SaveChanges method to submit the tracked changes to the remote database as a unit of work.&lt;/p&gt;
&lt;h3&gt;Create&lt;/h3&gt;
&lt;p&gt;To create new entities into the repository, call DbSet&amp;lt;T&amp;gt;.Add or DbSet&amp;lt;T&amp;gt;.AddRange. The following example creates a new category, and a new related subcategory, and add to repositories:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Changes
{
    internal static ProductCategory Create()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            ProductCategory category = new ProductCategory() { Name = &quot;Create&quot; };
            ProductSubcategory subcategory = new ProductSubcategory() { Name = &quot;Create&quot; };
            category.ProductSubcategories = new HashSet&amp;lt;ProductSubcategory&amp;gt;() { subcategory };
            // Equivalent to: subcategory.ProductCategory = category;
            category.ProductCategoryID.WriteLine(); // 0
            subcategory.ProductCategoryID.WriteLine(); // 0
            subcategory.ProductSubcategoryID.WriteLine(); // 0

            adventureWorks.ProductCategories.Add(category); // Track creation.
            // Equivalent to: adventureWorks.ProductSubcategories.Add(subcategory);
            adventureWorks.ChangeTracker.Entries()
                .Count(tracking =&amp;gt; tracking.State == EntityState.Added).WriteLine(); // 2
            object.ReferenceEquals(category.ProductSubcategories.Single(), subcategory).WriteLine(); // True

            adventureWorks.SaveChanges().WriteLine(); // 2
            // BEGIN TRANSACTION
            //    exec sp_executesql N&apos;SET NOCOUNT ON;
            //    INSERT INTO [Production].[ProductCategory] ([Name])
            //    VALUES (@p0);
            //    SELECT [ProductCategoryID]
            //    FROM [Production].[ProductCategory]
            //    WHERE @@ROWCOUNT = 1 AND [ProductCategoryID] = scope_identity();
            //    &apos;,N&apos;@p0 nvarchar(50)&apos;,@p0=N&apos;Create&apos;
            //
            //    exec sp_executesql N&apos;SET NOCOUNT ON;
            //    INSERT INTO [Production].[ProductCategory] ([Name])
            //    VALUES (@p0);
            //    SELECT [ProductCategoryID]
            //    FROM [Production].[ProductCategory]
            //    WHERE @@ROWCOUNT = 1 AND [ProductCategoryID] = scope_identity();
            //    &apos;,N&apos;@p0 nvarchar(50)&apos;,@p0=N&apos;Create&apos;
            // COMMIT TRANSACTION

            adventureWorks.ChangeTracker.Entries()
                .Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged).WriteLine(); // 0
            category.ProductCategoryID.WriteLine(); // 5
            subcategory.ProductCategoryID.WriteLine(); // 5
            subcategory.ProductSubcategoryID.WriteLine(); // 38
            return category;
        } // Unit of work.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here DbSet&amp;lt;T&amp;gt;.Add is called only once with 1 subcategory entity. Internally, Add triggers change detection, and tracks this subcategory as Added state. Since this subcategory is related with another category entity with navigation property, the related category is also tracked, as the Added state too. So in total there are 2 entity changes tracked. When DbContext.SaveChanges is called, EF/Core translates these 2 changes to 2 SQL INSERT statements:&lt;/p&gt;
&lt;p&gt;The category’s key is identity key, with value generated by database, so is subcategory. So in the translated INSERT statements, the new category’s ProductCategoryID and the new subcategory’s ProductSubcategory are ignored. After the each new row is created, a SELECT statement calls SCOPE_IDENTITY metadata function to read the last generated identity value, which is the primary key of the inserted row. As a result, since there are 2 row changes in total, SaveChanges returns 2, And the 2 changes are submitted in a transaction, so that all changes can succeed or fail as a unit.&lt;/p&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt;.AddRange can be called with multiple entities. AddRange only triggers change detection once for all the entities, so it can have better performance than multiple Add calls,&lt;/p&gt;
&lt;h3&gt;Update&lt;/h3&gt;
&lt;p&gt;To update entities in the repositories, just change their properties, including navigation properties. The following example updates a subcategory entity’s name, and related category entity, which is translated to UPDATE statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Update(int categoryId, int subcategoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories.Find(categoryId);
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.Find(subcategoryId);
        $&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;
            .WriteLine(); // (48, Create, 25)
        subcategory.Name = &quot;Update&quot;; // Entity property update.
        subcategory.ProductCategory = category; // Relashionship (foreign key) update.
        adventureWorks.ChangeTracker.Entries().Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged)
            .WriteLine(); // 1
        $&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;
            .WriteLine(); // (48, Update, 1)
        adventureWorks.SaveChanges().WriteLine(); // 1
        // BEGIN TRANSACTION
        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    UPDATE [Production].[ProductSubcategory] SET [Name] = @p0, [ProductCategoryID] = @p1
        //    WHERE [ProductSubcategoryID] = @p2;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p2 int,@p0 nvarchar(50),@p1 int&apos;,@p2=25,@p0=N&apos;Update&apos;,@p1=25
        // COMMIT TRANSACTION
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example first call Find to read the entities with a SELECT query, then execute the UPDATE statement. Here the row to update is located by primary key, so, if the primary key is known, then it can be used directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UpdateWithoutRead(int categoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = new ProductCategory()
        {
            ProductCategoryID = categoryId,
            Name = Guid.NewGuid().ToString() // To be updated.
        };
        adventureWorks.ProductCategories.Attach(category); // Track entity.
        EntityEntry tracking = adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single();
        tracking.State.WriteLine(); // Unchanged
        tracking.State = EntityState.Modified;
        adventureWorks.SaveChanges().WriteLine(); // 1
        // BEGIN TRANSACTION
        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    UPDATE [Production].[ProductCategory] SET [Name] = @p0
        //    WHERE [ProductCategoryID] = @p1;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p1 int,@p0 nvarchar(50)&apos;,@p1=25,@p0=N&apos;513ce396-4a5e-4a86-9d82-46f284aa4f94&apos;
        // COMMIT TRANSACTION
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a category entity is constructed on the fly, with specified primary key and updated Name. To track and save the changes, ii is attached to the repository. As fore mentioned, the attached entity is tracked as Unchanged state, so just manually set its state to Modified. This time, only one UPDATE statement is translated and executed, without SELECT.&lt;/p&gt;
&lt;p&gt;When there is no change to save, SaveChanges does not translate or execute any SQL and returns 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveNoChanges(int categoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories.Find(categoryId);
        string originalName = category.Name;
        category.Name = Guid.NewGuid().ToString(); // Entity property update.
        category.Name = originalName; // Entity property update.
        EntityEntry tracking = adventureWorks.ChangeTracker.Entries().Single();
        tracking.State.WriteLine(); // Unchanged
        adventureWorks.ChangeTracker.HasChanges().WriteLine(); // False
        adventureWorks.SaveChanges().WriteLine(); // 0
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Delete&lt;/h3&gt;
&lt;p&gt;To delete entities from the repositories, call DbSet&amp;lt;T&amp;gt;.Remove or DbSet&amp;lt;T&amp;gt;.RemoveRange. The following example read an entity then delete it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Delete(int subcategoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.Find(subcategoryId);
        adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
        adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State.WriteLine(); // Unchanged
        adventureWorks.ProductSubcategories.Remove(subcategory); // Track deletion.
        adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State.WriteLine(); // Deleted
        adventureWorks.SaveChanges().WriteLine(); // 1
        // BEGIN TRANSACTION
        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    DELETE FROM [Production].[ProductSubcategory]
        //    WHERE [ProductSubcategoryID] = @p0;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p0 int&apos;,@p0=48
        // COMMIT TRANSACTION
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the row to delete is also located with primary key. So again, when primary key is known, reading entity can be skipped:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeleteWithoutRead(int categoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = new ProductCategory() { ProductCategoryID = categoryId };
        adventureWorks.ProductCategories.Attach(category);
        adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 1
        adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State.WriteLine(); // Unchanged
        adventureWorks.ProductCategories.Remove(category); // Track deletion.
        adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State.WriteLine(); // Deleted
        adventureWorks.SaveChanges().WriteLine(); // 1
        //    BEGIN TRANSACTION
        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    DELETE FROM [Production].[ProductCategory]
        //    WHERE [ProductCategoryID] = @p0;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p0 int&apos;,@p0=25
        // COMMIT TRANSACTION
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a principal entity is loaded with its dependent entities, deleting the principal entity becomes cascade deletion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeleteCascade(int categoryId)
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories
            .Include(entity =&amp;gt; entity.ProductSubcategories)
            .Single(entity =&amp;gt; entity.ProductCategoryID == categoryId);
        ProductSubcategory subcategory = category.ProductSubcategories.Single();
        adventureWorks.ChangeTracker.Entries().Count().WriteLine(); // 2
        adventureWorks.ProductCategories.Remove(category); // Track deletion.
        // Optional: adventureWorks.ProductSubcategories.Remove(subcategory);
        adventureWorks.ChangeTracker.Entries().Count(tracking =&amp;gt; tracking.State == EntityState.Deleted)
            .WriteLine(); // 2
        adventureWorks.SaveChanges().WriteLine(); // 2
        // BEGIN TRANSACTION
        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    DELETE FROM [Production].[ProductSubcategory]
        //    WHERE [ProductSubcategoryID] = @p0;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p0 int&apos;,@p0=49

        //    exec sp_executesql N&apos;SET NOCOUNT ON;
        //    DELETE FROM [Production].[ProductCategory]
        //    WHERE [ProductCategoryID] = @p1;
        //    SELECT @@ROWCOUNT;
        //    &apos;,N&apos;@p1 int&apos;,@p1=26
        // COMMIT TRANSACTION
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the cascade deletion are translated and executed in the right order. The subcategory is deleted first, then category is deleted.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, untracked entities’ changes cannot to be translated or executed. The following example tries to delete a untracked entity from the repository, it throws InvalidOperationException:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UntrackedChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory untracked = adventureWorks.ProductCategories
            .AsNoTracking()
            .Single(category =&amp;gt; category.Name == &quot;Bikes&quot;);
        adventureWorks.ProductCategories.Remove(untracked); // Track no deletion.
        adventureWorks.SaveChanges().WriteLine();
        // InvalidOperationException: The object cannot be deleted because it was not found in the ObjectStateManager.
    } // Unit of work.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Transaction&lt;/h2&gt;
&lt;p&gt;As discussed above, by default DbContext.SaveChanges execute all data creation, update and deletion in a transaction, so that all the work can succeed or fail as a unit. If the unit of work succeeds, the transaction is committed, if any operation fails, the transaction is rolled back. EF/Core also supports custom transactions.&lt;/p&gt;
&lt;h3&gt;Transaction with connection resiliency and execution strategy&lt;/h3&gt;
&lt;p&gt;If the retry strategy is enabled for connection resiliency for DbContext by default, then this default retry strategy does not work custom transaction. Custom transaction works within a single retry operation, but not cross multiple retries. In EF Core, database façade’s CreateExecutionStrategy method can be called to explicitly specify a single retry operation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Transactions
{
    internal static void ExecutionStrategy(AdventureWorks adventureWorks)
    {
        adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
        {
            // Single retry operation, which can have custom transactions.
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the default retry strategy must be manually disabled, so that an individual retry logic must be manually created to start a single retry operation. In the object-relational mapping part, an ExecutionStrategy type is defined to turn on/off the default retry strategy. It can be reused to implement this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ExecutionStrategy : IDbExecutionStrategy
{
    private readonly IDbExecutionStrategy strategy = Create();

    public bool RetriesOnFailure =&amp;gt; this.strategy.RetriesOnFailure;

    public void Execute(Action operation) =&amp;gt;
        ExecuteOperation(() =&amp;gt; { this.strategy.Execute(operation); return (object)null; });

    public TResult Execute&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; operation) =&amp;gt;
        ExecuteOperation(() =&amp;gt; this.strategy.Execute(operation));

    public Task ExecuteAsync(
        Func&amp;lt;Task&amp;gt; operation, CancellationToken cancellationToken = default) =&amp;gt;
            ExecuteOperation(() =&amp;gt; this.strategy.ExecuteAsync(operation, cancellationToken));

    public Task&amp;lt;TResult&amp;gt; ExecuteAsync&amp;lt;TResult&amp;gt;(
        Func&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; operation, CancellationToken cancellationToken = default) =&amp;gt;
            ExecuteOperation(() =&amp;gt; this.strategy.ExecuteAsync(operation, cancellationToken));

    private static T ExecuteOperation&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; resultFactory)
    {
        DisableExecutionStrategy = true;
        try
        {
            return resultFactory();
        }
        finally
        {
            DisableExecutionStrategy = false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF, the database façade does not have CreateExecutionStrategy method, so a extension method can be defined for DbContext.Database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class DatabaseExtensions
{
    public static ExecutionStrategy CreateExecutionStrategy(this DatabaseFacade database) =&amp;gt; 
        new ExecutionStrategy();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now EF can use the same pattern as EF Core to work with custom transactions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;EF/Core transaction&lt;/h3&gt;
&lt;p&gt;EF Core provides Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction to represent a transaction. It can be created by DbContext.Database.BeginTransaction, where the transaction’s &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms189122.aspx&quot;&gt;isolation level&lt;/a&gt; can be optionally specified. The following example executes a entity change and custom SQL with one EF/Core transaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DbContextTransaction(AdventureWorks adventureWorks)
{
    adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
    {
        using (IDbContextTransaction transaction = adventureWorks.Database.BeginTransaction(
            IsolationLevel.ReadUncommitted))
        {
            try
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // ReadUncommitted

                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                adventureWorks.ProductCategories.Add(category);
                adventureWorks.SaveChanges().WriteLine(); // 1

                adventureWorks.Database.ExecuteSqlCommand(
                    sql: &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {0}&quot;,
                    parameters: nameof(ProductCategory)).WriteLine(); // 1
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF/Core transaction wraps ADO.NET transaction. When the EF/Core transaction begins, The specified isolation level is written to a packet (represented by System.Data.SqlClient.SNIPacket type), and sent to SQL database via TDS protocol. There is no SQL statement like &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms173763.aspx&quot;&gt;SET TRANSACTION ISOLATION LEVEL&lt;/a&gt; executed, so the actual isolation level cannot be logged by EF/Core, or traced by SQL Profiler. In above example, CurrentIsolationLevel is called to verify the current transaction’s isolation level. It is an extension method of DbContext. It queries the dynamic management view &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms176013.aspx&quot;&gt;sys.dm_exec_sessions&lt;/a&gt; with current session id, which can be retrieved with &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms189535.aspx&quot;&gt;@@SPID&lt;/a&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static readonly string CurrentIsolationLevelSql = $@&quot;
        SELECT
            CASE transaction_isolation_level
                WHEN 0 THEN N&apos;{IsolationLevel.Unspecified}&apos;
                WHEN 1 THEN N&apos;{IsolationLevel.ReadUncommitted}&apos;&apos;
                WHEN 2 THEN N&apos;{IsolationLevel.ReadCommitted}&apos;&apos;
                WHEN 3 THEN N&apos;{IsolationLevel.RepeatableRead}&apos;&apos;
                WHEN 4 THEN N&apos;{IsolationLevel.Serializable}&apos;&apos;
                WHEN 5 THEN N&apos;{IsolationLevel.Snapshot}&apos;&apos;
            END
        FROM sys.dm_exec_sessions
        WHERE session_id = @@SPID&quot;;

    public static string CurrentIsolationLevel(this DbContext context)
    {
        using (DbCommand command = context.Database.GetDbConnection().CreateCommand())
        {
            command.CommandText = CurrentIsolationLevelSql;
            command.Transaction = context.Database.CurrentTransaction.GetDbTransaction();
            return (string)command.ExecuteScalar();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When DbContext.SaveChanges is called to create entity. it detects a transaction is explicitly created with the current DbContext, so it uses that transaction and does not automatically begins a new transaction like all the previous examples. Then DbContext.Database.ExecuteSqlCommnd is called to delete entity. It also detects and uses transaction of the current DbContext. Eventually, to commit the transaction, call IDbContextTransaction.Commit, to rollback the transaction, call IDbContextTransaction.Rollback&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF has built-in support to execute custom SQL with result of primitive type, so CurrentIsolationLevel can be implemented as:/p&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string CurrentIsolationLevel(this DbContext context) =&amp;gt;
    context.Database.SqlQuery&amp;lt;string&amp;gt;(CurrentIsolationLevelSql).Single();
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;ADO.NET transaction&lt;/h3&gt;
&lt;p&gt;EF/Core can also use the ADO.NET transaction, represented by System.Data.Common.DbTransaction. The following example execute the same entity change and custom SQL command with one ADO.NET transaction. To use an existing ADO.NET transaction, call DbContext.Database.UseTransaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DbTransaction()
{
    using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
    {
        connection.Open();
        using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.RepeatableRead))
        {
            try
            {
                using (AdventureWorks adventureWorks = new AdventureWorks(connection))
                {
                    adventureWorks.Database.CreateExecutionStrategy().Execute(() =&amp;gt;
                    {
                        adventureWorks.Database.UseTransaction(transaction);
                        adventureWorks.CurrentIsolationLevel().WriteLine(); // RepeatableRead

                        ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                        adventureWorks.ProductCategories.Add(category);
                        adventureWorks.SaveChanges().WriteLine(); // 1.
                    });
                }
                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                    DbParameter parameter = command.CreateParameter();
                    parameter.ParameterName = &quot;@p0&quot;;
                    parameter.Value = nameof(ProductCategory);
                    command.Parameters.Add(parameter);
                    command.Transaction = transaction;
                    command.ExecuteNonQuery().WriteLine(); // 1
                }
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Transaction scope&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The EF transaction only work with its source DbContext, and the ADO.NET transaction only work with its source DbConnection. Since EF work with .NET Framework, where System.Transactions.TransactionScope is provided, TransactionScope can be used with EF to have a transaction that work across the lifecycle of multiple DbContext or DbConnection instances:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TransactionScope()
{
    new ExecutionStrategy().Execute(() =&amp;gt;
    {
        using (TransactionScope scope = new TransactionScope(
            scopeOption: TransactionScopeOption.Required,
            transactionOptions: new TransactionOptions()
            {
                IsolationLevel = System.Transactions.IsolationLevel.Serializable
            }))
        {
            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = DbContextExtensions.CurrentIsolationLevelSql;
                connection.Open();
                using (DbDataReader reader = command.ExecuteReader())
                {
                    reader.Read();
                    reader[0].WriteLine(); // RepeatableRead
                }
            }
            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                adventureWorks.ProductCategories.Add(category);
                adventureWorks.SaveChanges().WriteLine(); // 1
            }
            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // Serializable
            }
            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                DbParameter parameter = command.CreateParameter();
                parameter.ParameterName = &quot;@p0&quot;;
                parameter.Value = nameof(ProductCategory);
                command.Parameters.Add(parameter);

                connection.Open();
                command.ExecuteNonQuery().WriteLine(); // 1
            }
            scope.Complete();
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (5) Query Translation Implementation</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation-7/</guid><description>The previous part demonstrated what are the SQL translations of the LINQ to Entities queries. This part discusses how the translation is implemented. Regarding different database systems can have diff</description><pubDate>Mon, 25 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-5-query-translation&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-5-query-translation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous part demonstrated what are the SQL translations of the LINQ to Entities queries. This part discusses how the translation is implemented. Regarding different database systems can have different query languages or different query APIs, EF/Core implement a provider model to work with different kinds of databases. In EF Core, the base libraries are the Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Relational NuGet packages. Microsoft.EntityFrameworkCore provides the database provider contracts as Microsoft.EntityFrameworkCore.Storage.IDatabaseProviderServices interface. And the SQL database support is implemented by the Microsoft.EntityFrameworkCore,SqlServer NuGet package, which provides Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerDatabaseProviderServices type to implement IDatabaseProviderServices. There are other libraries for different databases, like Microsoft.EntityFrameworkCore.SQLite NuGet package for SQLite, etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the EntityFramework NuGet package contains 2 assemblies, EntityFramework.dll and EntityFramework.SqlServer.dll. The base library EntityFramework.dll provides database provider contracts as System.Data.Entity.Core.Common.DbProviderServices abstract class, and the SQL database provider library EntityFramework.SqlServer.dll provides System.Data.Entity.SqlServer.SqlProviderServices to implement DbProviderServices&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With this provider model, EF/Core breaks the translation into 2 parts. First, IQueryable&amp;lt;T&amp;gt; query methods work with expression trees, and EF/Core base libraries translate these .NET expression tree to generic, intermediate database expression tree; Then the specific EF/Core database provider is responsible to generate query language for the specific database.&lt;/p&gt;
&lt;h2&gt;Code to LINQ expression tree&lt;/h2&gt;
&lt;p&gt;Before translation, .NET expression tree must be built to represent the query logic. As fore mentioned, expression tree enables function as data. In C#, an expression tree shares the same syntax as functions, but is compiled to abstract syntactic tree representing function’s source code. In LINQ, IQueryable&amp;lt;T&amp;gt; utilizes expression tree to represent the abstract syntactic structure of a remote query.&lt;/p&gt;
&lt;h3&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; has been demonstrated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable
    {
        // IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); from IEnumerable&amp;lt;T&amp;gt;.

        // Type ElementType { get; } from IQueryable.

        // Expression Expression { get; } from IQueryable.

        // IQueryProvider Provider { get; } from IQueryable.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a wrapper of iterator factory, an element type, an expression tree representing the current query’s logic, and a query provider of IQueryProvider type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryProvider
    {
        IQueryable CreateQuery(Expression expression);

        IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression);

        object Execute(Expression expression);

        TResult Execute&amp;lt;TResult&amp;gt;(Expression expression);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IQueryProvider has CreateQuery and Execute methods, all accepting a expression tree parameter. CreateQuery methods return an IQueryable&amp;lt;T&amp;gt; query, and Execute methods return a query result. These methods are called inside the Queryable methods.&lt;/p&gt;
&lt;h3&gt;Queryable methods&lt;/h3&gt;
&lt;p&gt;As fore mentioned, Queryable also provides 2 kinds of query methods, sequence queries returning IQueryable&amp;lt;T&amp;gt; query, and value queries returning a query result. Take Where, Select, and First as examples, the following are their implementations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;TSource&amp;gt;&amp;gt; currentMethod = 
                Where;
            MethodCallExpression whereCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(predicate));
            return source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(whereCallExpression);
        }

        public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;, IQueryable&amp;lt;TResult&amp;gt;&amp;gt; currentMethod = 
                Select;
            MethodCallExpression selectCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(selector));
            return source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(selectCallExpression);
        }

        public static TSource First&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, TSource&amp;gt; currentMethod = First;
            MethodCallExpression firstCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(predicate));
            return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
        }

        public static TSource First&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, TSource&amp;gt; currentMethod = First;
            MethodCallExpression firstCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression);
            return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They just build a MethodCallExpression expression, representing the current query method is called. Then they obtain query provider from source’s Provider property. The sequence query methods call query provider’s CreateQuery method to return IQueryable&amp;lt;T&amp;gt; query, and the value query methods call query provider’s Execute method to return a query result. All Queryable methods are implemented in this pattern, except AsQueryable, which is discussed in the previous part.&lt;/p&gt;
&lt;h3&gt;Build LINQ to Entities abstract syntax tree&lt;/h3&gt;
&lt;p&gt;With above Where and Select query methods, a simple LINQ to Entities query can be implemented to return an IQueryable&amp;lt;T&amp;gt; of values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Translation
{
    internal static void WhereAndSelect(AdventureWorks adventureWorks)
    {
        // IQueryable&amp;lt;string&amp;gt; products = adventureWorks.Products
        //    .Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
        //    .Select(product =&amp;gt; product.Name);
        IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products;
        IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(product =&amp;gt; product.Name.Length &amp;gt; 10);
        IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(product =&amp;gt; product.Name); // Define query.
        foreach (string result in selectQueryable) // Execute query.
        {
            result.WriteLine();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example filters the products with Name longer than 10 characters, and queries the products’ Names. By desugaring the lambda expressions, and unwrapping the query methods, the above LINQ to Entities query is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectLinqExpressions(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products; // DbSet&amp;lt;Product&amp;gt;.
    ConstantExpression sourceConstantExpression = (ConstantExpression)sourceQueryable.Expression;
    IQueryProvider sourceQueryProvider = sourceQueryable.Provider; // EntityQueryProvider.

    // Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = product =&amp;gt; product.Name.Length &amp;gt; 10;
    ParameterExpression productParameterExpression = Expression.Parameter(typeof(Product), &quot;product&quot;);
    Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
        body: Expression.GreaterThan(
            left: Expression.Property(
                expression: Expression.Property(
                    expression: productParameterExpression, propertyName: nameof(Product.Name)), 
                propertyName: nameof(string.Length)),
            right: Expression.Constant(10)),
        parameters: productParameterExpression);

    // IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(predicateExpression);
    Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;Product&amp;gt;&amp;gt; whereMethod =
        Queryable.Where;
    MethodCallExpression whereCallExpression = Expression.Call(
        method: whereMethod.Method,
        arg0: sourceConstantExpression,
        arg1: Expression.Quote(predicateExpression));
    IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryProvider
        .CreateQuery&amp;lt;Product&amp;gt;(whereCallExpression); // EntityQueryable&amp;lt;Product&amp;gt;.
    IQueryProvider whereQueryProvider = whereQueryable.Provider; // EntityQueryProvider.

    // Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression = product =&amp;gt; product.Name;
    Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;(
        body: Expression.Property(productParameterExpression, nameof(Product.Name)),
        parameters: productParameterExpression);

    // IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(selectorExpression);
    Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;, IQueryable&amp;lt;string&amp;gt;&amp;gt; selectMethod =
        Queryable.Select;
    MethodCallExpression selectCallExpression = Expression.Call(
        method: selectMethod.Method,
        arg0: whereCallExpression,
        arg1: Expression.Quote(selectorExpression));
    IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryProvider
        .CreateQuery&amp;lt;string&amp;gt;(selectCallExpression); // EntityQueryable&amp;lt;Product&amp;gt;/DbQuery&amp;lt;Product&amp;gt;.

    using (IEnumerator&amp;lt;string&amp;gt; iterator = selectQueryable.GetEnumerator()) // Execute query.
    {
        while (iterator.MoveNext())
        {
            iterator.Current.WriteLine();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the steps how the fluent query builds its query expression tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Build data source:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The initial source IQueryable&amp;lt;T&amp;gt; is a DbSet&amp;lt;T&amp;gt; instance automatically created by EF/Core. It wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A ConstantExpression expression representing the data source.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider that implements IQueryProvider. In EF Core it is an automatically created EntityQueryProvider instance, and in EF it is DbQueryProvider.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build Where query:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A predicate expression is built for Where,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Where accepts the IQueryable&amp;lt;T&amp;gt; source. But actually Where only needs the source’s expression and query provider. A MethodCallExpression expression is built to represent a call of Where itself with 2 arguments, the source and the predicate expression. Then source query provider’s CreateQuery method is called with the MethodCallExpression expression just built, and return an IQueryable&amp;lt;T&amp;gt; query, which wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The MethodCallExpression expression representing current Where call&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider, which is the same one from the source.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build Select query:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A selector expression is built for Select&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select accepts the IQueryable&amp;lt;T&amp;gt; returned by Where as source. Again, Select only needs the expression and query provider from source. A MethodCallExpression expression is built to represent a call to Select itself with 2 arguments, the source and the selector expression. Then source query provider’s CreateQuery method is called with the MethodCallExpression expression just built, and return an IQueryable&amp;lt;T&amp;gt; query, which wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The MethodCallExpression expression representing current Select call&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider, which is the same one from the source.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, the final IQueryable&amp;lt;T&amp;gt; query’s Expression property is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)
|_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
|_Object = null
|_Arguments
  |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;Product&amp;gt;)
  | |_Method = Queryable.Where&amp;lt;Product&amp;gt;
  | |_Object = null
  | |_Arguments
  |   |_ConstantExpression (NodeType = Constant, Type = IQueryable&amp;lt;Product&amp;gt;)
  |   | |_Value = new EntityQueryable&amp;lt;Product&amp;gt;(adventureWorks.GetService&amp;lt;IAsyncQueryProvider&amp;gt;())
  |   |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;)
  |     |_Operand
  |       |_Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, bool&amp;gt;)
  |         |_Parameters
  |         | |_ParameterExpression (NodeType = Parameter, Type = Product)
  |         |   |_Name = &quot;product&quot;
  |         |_Body
  |           |_BinaryExpression (NodeType = GreaterThan, Type = bool)
  |             |_Left
  |             | |_MemberExpression (NodeType = MemberAccess, Type = int)
  |             |   |_Member = &quot;Length&quot;
  |             |   |_Expression
  |             |     |_MemberExpression (NodeType = MemberAccess, Type = string)
  |             |       |_Member = &quot;Name&quot;
  |             |       |_Expression
  |             |         |_ParameterExpression (NodeType = Parameter, Type = Product)
  |             |           |_Name = &quot;product&quot;
  |             |_Right
  |               |_ConstantExpression (NodeType = Constant, Type = int)
  |                 |_Value = 10
  |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
    |_Operand
      |_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
        |_Parameters
        | |_ParameterExpression (NodeType = Parameter, Type = Product)
        |   |_Name = &quot;product&quot;
        |_Body
          |_MemberExpression (NodeType = MemberAccess, Type = string)
            |_Member = &quot;Name&quot;
            |_Expression
              |_ParameterExpression (NodeType = Parameter, Type = Product)
                |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In FE, the difference is, the original IQueryable&amp;lt;T&amp;gt; data source wraps a MethodCallExpression expression, which represents an ObjectQuery&amp;lt;T&amp;gt; instance’s MergeAs instance method call with 1 argument, the MergeOption.AppendOnly enumeration. It means append new entities to the entity cache if any entity is constructed by the query. Entity cache will be discussed in a later part.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This also demonstrates that lambda expression, extension methods, and LINQ query expression are powerful language features of C#. Such a rich abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectQuery(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;string&amp;gt; products = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
        .Select(product =&amp;gt; product.Name);
    // Equivalent to:
    // IQueryable&amp;lt;string&amp;gt; products =
    //    from product in adventureWorks.Products
    //    where product.Name.Length &amp;gt; 10
    //    select product.Name;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other kind of query returning a single value works in the similar way. Take above First as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirst(AdventureWorks adventureWorks)
{
    // string first = adventureWorks.Products.Select(product =&amp;gt; product.Name).First();
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
    string first = selectQueryable.First().WriteLine(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the initial source and and Select query are the same as the previous example. So this time, just unwrap the First method. The above First query is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstLinqExpressions(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = adventureWorks.Products;

    IQueryable&amp;lt;string&amp;gt; selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
    MethodCallExpression selectCallExpression = (MethodCallExpression)selectQueryable.Expression;
    IQueryProvider selectQueryProvider = selectQueryable.Provider; // DbQueryProvider.

    // string first = selectQueryable.First();
    Func&amp;lt;IQueryable&amp;lt;string&amp;gt;, string&amp;gt; firstMethod = Queryable.First;
    MethodCallExpression firstCallExpression = Expression.Call(
        method: firstMethod.Method, arg0: selectCallExpression);

    string first = selectQueryProvider.Execute&amp;lt;string&amp;gt;(firstCallExpression).WriteLine(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In First query, the MethodCallExpression expression is built in the same way to represent current First call. The difference is, query provider’s Execute method is called instead of CreateQuery, so that a query result is returned instead of a query.&lt;/p&gt;
&lt;p&gt;Similarly, the last expression tree built inside First, is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression (NodeType = Call, Type = string)
|_Method = Queryable.First&amp;lt;string&amp;gt;
|_Object = null
|_Arguments
  |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)
    |_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
    |_Object = null
    |_Arguments
      |_ConstantExpression (NodeType = Constant, Type = IQueryable&amp;lt;Product&amp;gt;)
      | |_Value = new EntityQueryable&amp;lt;Product&amp;gt;(adventureWorks.GetService&amp;lt;IAsyncQueryProvider&amp;gt;())
      |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
       |_Operand
          |_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
            |_Parameters
            | |_ParameterExpression (NodeType = Parameter, Type = Product)
            |   |_Name = &quot;product&quot;
            |_Body
              |_MemberExpression (NodeType = MemberAccess, Type = string)
                |_Member = &quot;Name&quot;
                |_Expression
                  |_ParameterExpression (NodeType = Parameter, Type = Product)
                    |_Name = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Again, in FE, the original IQueryable&amp;lt;Product&amp;gt; data source wraps a MethodCallExpression expression, instead of ConstantExpression.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And again, the entire abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstQuery(AdventureWorks adventureWorks)
{
    string first = adventureWorks.Products.Select(product =&amp;gt; product.Name).First();
    // Equivalent to:
    // string first = (from product in adventureWorks.Products select product.Name).First();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;.NET expression tree to database expression tree&lt;/h2&gt;
&lt;p&gt;When LINQ to Entities queries are executed by either pulling values from IQueryable&amp;lt;T&amp;gt;, or calling IQueryProvider.Execute, EF/Core compiles .NET expression tree to database expression tree.&lt;/p&gt;
&lt;h3&gt;Database query abstract syntax tree&lt;/h3&gt;
&lt;p&gt;The logic of LINQ to Entities can be represented by .NET expression tree, and EF/Core also use expression tree to represent the database query logic. For example, EF Core base libraries provides the Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpression represents a database SELECT query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.Query.Expressions
{
    public class SelectExpression : TableExpressionBase
    {
        public virtual IReadOnlyList&amp;lt;Expression&amp;gt; Projection { get; } // SELECT.

        public virtual bool IsDistinct { get; set; } // DISTINCT.

        public virtual Expression Limit { get; set; } // TOP.

        public virtual IReadOnlyList&amp;lt;TableExpressionBase&amp;gt; Tables { get; } // FROM.

        public virtual Expression Predicate { get; set; } // WHERE.

        public virtual IReadOnlyList&amp;lt;Ordering&amp;gt; OrderBy { get; } // ORDER BY.

        public virtual Expression Offset { get; set; } // OFFSET.

        public override Type Type { get; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are all the database expressions provided by EF Core, and the Remotion.Linq library used by EF Core:&lt;/p&gt;
&lt;p&gt;Expression&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;AggregateExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MaxExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SumExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AliasExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ColumnExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CountExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DatePartExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DiscriminatorPredicateExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ExistsExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ExplicitCastExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;InExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IsNullExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LikeExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NotNullableExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NullConditionalExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PartialEvaluationExceptionExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PropertyParameterExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;QuerySourceReferenceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RowNumberExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SqlFunctionExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;StringCompareExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SubQueryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TableExpressionBase&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CrossJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FromSqlExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;JoinExpressionBase&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;InnerJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LeftOuterJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LateralJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SelectExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TableExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;VBStringComparisonExpression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EF provides database command tree, where each node derives from System.Data.Entity.Core.Common.CommandTrees.DbExpression:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DbExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbApplyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbArithmeticExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbBinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbAndExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbComparisonExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbExceptExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIntersectExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbOrExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbUnionAllExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCaseExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbConstantExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCrossJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbFilterExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbFunctionExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbGroupByExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbInExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLambdaExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLikeExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLimitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNewInstanceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNullExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbParameterReferenceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbProjectExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbPropertyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbQuantifierExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRelationshipNavigationExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbScanExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbSkipExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbSortExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbUnaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCastExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbDerefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbDistinctExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbElementExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbEntityRefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsEmptyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsNullExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsOfExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNotExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbOfTypeExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbTreatExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRefKeyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbVariableReferenceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When representing a complete database query, command tree’s top node is a DbQueryCommandTree instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common.CommandTrees
{
    public abstract class DbCommandTree
    {
        public IEnumerable&amp;lt;KeyValuePair&amp;lt;string, TypeUsage&amp;gt;&amp;gt; Parameters { get; }

        // Other members.
    }
    
    public sealed class DbQueryCommandTree : DbCommandTree
    {
        public DbExpression Query { get; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbQueryCommandTree’s Parameters property contains the parameters for the database query, and Query property is the top node of the DbExpression tree. They are similar to LambdaExpression’s Parameters and Body properties.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Compile LINQ expressions to database expressions&lt;/h3&gt;
&lt;p&gt;EF Core calls the third party library Remotion.Linq to compile LINQ expression tree to a query model, then EF Core compiles the query model to database expression tree, which is a SelectExpression instance. The following Compile method demonstrates how the compilation can be done. It accepts a LINQ expression tree, and returns a tuple of SelectExpression and its parameters, if any:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static (SelectExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt;) Compile(
        this DbContext dbContext, Expression linqExpression)
    {
        QueryContext queryContext = dbContext.GetService&amp;lt;IQueryContextFactory&amp;gt;().Create();
        IEvaluatableExpressionFilter evaluatableExpressionFilter = dbContext.GetService&amp;lt;IEvaluatableExpressionFilter&amp;gt;();
        linqExpression = new ParameterExtractingExpressionVisitor(
            evaluatableExpressionFilter: evaluatableExpressionFilter,
            parameterValues: queryContext,
            logger: dbContext.GetService&amp;lt;IDiagnosticsLogger&amp;lt;DbLoggerCategory.Query&amp;gt;&amp;gt;(),
            parameterize: true).ExtractParameters(linqExpression);
        QueryParser queryParser = new QueryParser(new ExpressionTreeParser(
            nodeTypeProvider: dbContext.GetService&amp;lt;INodeTypeProviderFactory&amp;gt;().Create(),
            processor: new CompoundExpressionTreeProcessor(new IExpressionTreeProcessor[]
            {
                new PartialEvaluatingExpressionTreeProcessor(evaluatableExpressionFilter),
                new TransformingExpressionTreeProcessor(ExpressionTransformerRegistry.CreateDefault())
            })));
        QueryModel queryModel = queryParser.GetParsedQuery(linqExpression);

        Type resultType = queryModel.GetResultType();
        if (resultType.IsConstructedGenericType &amp;amp;&amp;amp; resultType.GetGenericTypeDefinition() == typeof(IQueryable&amp;lt;&amp;gt;))
        {
            resultType = resultType.GenericTypeArguments.Single();
        }

        QueryCompilationContext compilationContext = dbContext.GetService&amp;lt;IQueryCompilationContextFactory&amp;gt;()
            .Create(async: false);
        RelationalQueryModelVisitor queryModelVisitor = (RelationalQueryModelVisitor)compilationContext
            .CreateQueryModelVisitor();
        queryModelVisitor.GetType()
            .GetMethod(nameof(RelationalQueryModelVisitor.CreateQueryExecutor))
            .MakeGenericMethod(resultType)
            .Invoke(queryModelVisitor, new object[] { queryModel });
        SelectExpression databaseExpression = queryModelVisitor.TryGetQuery(queryModel.MainFromClause);
        databaseExpression.QuerySource = queryModel.MainFromClause;
        return (databaseExpression, queryContext.ParameterValues);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF calls ExpressionConverter, PlanCompiler and other components to convert expression tree to database command tree. These APIs are not public.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So above Where and Select query’s expression tree can be converted as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompileWhereAndSelectExpressions(AdventureWorks adventureWorks)
{
    Expression linqExpression =adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt; 10)
        .Select(product =&amp;gt; product.Name).Expression;
    (SelectExpression DatabaseExpression, IReadOnlyDictionary&amp;lt;string, object&amp;gt; Parameters) compilation =
        adventureWorks.Compile(linqExpression);
    compilation.DatabaseExpression.WriteLine();
    compilation.Parameters.WriteLines(parameter =&amp;gt; $&quot;{parameter.Key}: {parameter.Value}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiled SelectExpression is the same as the following SelectExpression built on the fly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static SelectExpression WhereAndSelectDatabaseExpressions(AdventureWorks adventureWorks)
{
    QueryCompilationContext compilationContext = adventureWorks.GetService&amp;lt;IQueryCompilationContextFactory&amp;gt;()
        .Create(async: false);
    SelectExpression databaseExpression = new SelectExpression(
        dependencies: new SelectExpressionDependencies(adventureWorks.GetService&amp;lt;IQuerySqlGeneratorFactory&amp;gt;()),
        queryCompilationContext: (RelationalQueryCompilationContext)compilationContext);
    MainFromClause querySource = new MainFromClause(
        itemName: &quot;product&quot;,
        itemType: typeof(Product),
        fromExpression: Expression.Constant(adventureWorks.ProductCategories));
    TableExpression tableExpression = new TableExpression(
        table: nameof(Product),
        schema: AdventureWorks.Production,
        alias: querySource.ItemName,
        querySource: querySource);
    databaseExpression.AddTable(tableExpression);
    IEntityType productEntityType = adventureWorks.Model.FindEntityType(typeof(Product));
    IProperty nameProperty = productEntityType.FindProperty(nameof(Product.Name));
    ColumnExpression nameColumn = new ColumnExpression(
        name: nameof(Product.Name), property: nameProperty, tableExpression: tableExpression);
    databaseExpression.AddToProjection(nameColumn);
    databaseExpression.AddToPredicate(Expression.GreaterThan(
        left: new ExplicitCastExpression(
            operand: new SqlFunctionExpression(
                functionName: &quot;LEN&quot;,
                returnType: typeof(int),
                arguments: new Expression[] { nameColumn }),
            type: typeof(int)),
        right: Expression.Constant(10)));
    return databaseExpression.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This compiled abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression (NodeType = Extension, Type = string)
|_Porjection
| |_ColumnExpression (NodeType = Extension, Type = string)
|   |_Name = &quot;Name&quot;
|   |_Property = Product.Name
|   |_Table
|     |_TableExpression (NodeType = Extension, Type = object)
|     |_Schema = &quot;Production&quot;
|     |_Name = &quot;Product&quot;
|     |_Alias = &quot;product&quot;
|_Tables
| |_TableExpression (NodeType = Extension, Type = object)
|   |_Schema = &quot;Production&quot;
|   |_Name = &quot;Product&quot;
|   |_Alias = &quot;product&quot;
|_Predicate
  |_BinaryExpression (NodeType = GreaterThan, Type = bool)
  |_left
  | |_ExplicitCastExpression (NodeType = Extension, Type = int)
  |   |_Operand
  |     |_SqlFunctionExpression (NodeType = Extension, Type = int)
  |       |_FunctionName = &quot;LEN&quot;
  |       |_Arguments
  |         |_ColumnExpression (NodeType = Extension, Type = string)
  |           |_Name = &quot;Name&quot;
  |           |_Property = Product.Name
  |           |_Table
  |             |_TableExpression (NodeType = Extension, Type = object)
  |               |_Schema = &quot;Production&quot;
  |               |_Name = &quot;Product&quot;
  |               |_Alias = &quot;product&quot;
  |_Right
    |_ConstantExpression (NodeType = Constant, Type = int)
    |_Value = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the compiled command tree above is equivalent to the command tree built below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree WhereAndSelectDatabaseExpressions(AdventureWorks adventureWorks)
{
    MetadataWorkspace metadata = ((IObjectContextAdapter)adventureWorks).ObjectContext.MetadataWorkspace;
    TypeUsage stringTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetPrimitiveTypes(DataSpace.CSpace)
        .Single(type =&amp;gt; type.ClrEquivalentType == typeof(string)));
    TypeUsage nameRowTypeUsage = TypeUsage.CreateDefaultTypeUsage(RowType.Create(
        EnumerableEx.Return(EdmProperty.Create(nameof(Product.Name), stringTypeUsage)),
        Enumerable.Empty&amp;lt;MetadataProperty&amp;gt;()));
    TypeUsage productTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetType(nameof(Product), &quot;CodeFirstDatabaseSchema&quot;, DataSpace.SSpace));
    EntitySet productEntitySet = metadata
        .GetEntityContainer(&quot;CodeFirstDatabase&quot;, DataSpace.SSpace)
        .GetEntitySetByName(nameof(Product), false);

    DbProjectExpression query = DbExpressionBuilder.Project(
        DbExpressionBuilder.BindAs(
            DbExpressionBuilder.Filter(
                DbExpressionBuilder.BindAs(
                    DbExpressionBuilder.Scan(productEntitySet), &quot;Extent1&quot;),
                DbExpressionBuilder.GreaterThan(
                    DbExpressionBuilder.Invoke(
                        ((IObjectCOntextAdapter)adventureWorks).ObjectContext.MetadataWorkspace
                            .GetFunctions(&quot;LEN&quot;, &quot;SqlServer&quot;, DataSpace.SSpace).First(),
                        DbExpressionBuilder.Property(
                            DbExpressionBuilder.Variable(productTypeUsage, &quot;Extent1&quot;), nameof(Product.Name))),
                    DbExpressionBuilder.Constant(10))),
            &quot;Filter1&quot;),
        DbExpressionBuilder.New(
            nameRowTypeUsage,
            DbExpressionBuilder.Property(
                DbExpressionBuilder.Variable(productTypeUsage, &quot;Filter1&quot;), nameof(Product.Name))));
    DbQueryCommandTree result = new DbQueryCommandTree(metadata, DataSpace.SSpace, query);
    return result.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query
  |_DbProjectExpression (ExpressionKind = Project, ResultType = Collection(Row[&apos;Name&apos; = Edm.String]))
    |_Input
    | |_DbExpressionBinding (VariableType = Product)
    |   |_VariableName = &apos;Filter1&apos;
    |   |_Expression
    |     |_DbFilterExpression (ExpressionKind = Filter, ResultType = Product)
    |       |_Input
    |       | |_DbExpressionBinding (VariableType = Product)
    |       |   |_VariableName = &apos;Extent1&apos;
    |       |   |_Expression
    |       |     |_DbScanExpression (ExpressionKind = Scan, ResultType = Collection(Product))
    |       |       |_Target = Products
    |       |_Predicate
    |         |_DbComparisonExpression (ExpressionKind = GreaterThan, ResultType = Edm.Boolean)
    |           |_Left
    |           | |_DbFunctionExpression (ExpressionKind = Function, ResultType = Edm.Int32)
    |           |   |_Function = Edm.Length
    |           |   |_Arguments
    |           |     |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
    |           |       |_Property = ‘Name’
    |           |       |_Instance
    |           |         |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
    |           |           |_VariableName = &apos;Extent1&apos;
    |           |_Right
    |             |_DbConstantExpression (ExpressionKind = Constant, ResultType = Edm.Int32)
    |               |_Value = 10
    |_Projection
      |_DbNewInstanceExpression (ExpressionKind = NewInstance, ResultType = Row[&apos;Name&apos; = Edm.String])
        |_Arguments
          |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
            |_Property = &quot;Name&quot;
            |_Instance
              |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
                |_VariableName = &apos;Filter1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Similarly, the other Select and First query’s expression tree is compiled to abstract syntax tree the same as the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static SelectExpression SelectAndFirstDatabaseExpressions(AdventureWorks adventureWorks)
{
    QueryCompilationContext compilationContext = adventureWorks.GetService&amp;lt;IQueryCompilationContextFactory&amp;gt;()
        .Create(async: false);
    SelectExpression selectExpression = new SelectExpression(
        dependencies: new SelectExpressionDependencies(adventureWorks.GetService&amp;lt;IQuerySqlGeneratorFactory&amp;gt;()),
        queryCompilationContext: (RelationalQueryCompilationContext)compilationContext);
    MainFromClause querySource = new MainFromClause(
        itemName: &quot;product&quot;,
        itemType: typeof(Product),
        fromExpression: Expression.Constant(adventureWorks.ProductCategories));
    TableExpression tableExpression = new TableExpression(
        table: nameof(Product),
        schema: AdventureWorks.Production,
        alias: querySource.ItemName,
        querySource: querySource);
    selectExpression.AddTable(tableExpression);
    IEntityType productEntityType = adventureWorks.Model.FindEntityType(typeof(Product));
    IProperty nameProperty = productEntityType.FindProperty(nameof(Product.Name));
    selectExpression.AddToProjection(new ColumnExpression(
        name: nameof(Product.Name), property: nameProperty, tableExpression: tableExpression));
    selectExpression.Limit = Expression.Constant(1);
    return selectExpression.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SelectExpression (NodeType = Extension, Type = string)
|_Limit
| |_ConstantExpression (NodeType = Constant, Type = int)
|   |_Value = 1
|_Porjection
|   |_ColumnExpression (NodeType = Extension, Type = string)
|   |_Name = &quot;Name&quot;
|   |_Property = Product.Name
|   |_Table
|     |_TableExpression (NodeType = Extension, Type = object)
|     |_Schema = &quot;Production&quot;
|     |_Name = &quot;Product&quot;
|     |_Alias = &quot;product&quot;
|_Tables
  |_TableExpression (NodeType = Extension, Type = object)
    |_Schema = &quot;Production&quot;
    |_Name = &quot;Product&quot;
    |_Alias = &quot;product&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the compiled command tree above is equivalent to the command tree built below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree SelectAndFirstDatabaseExpressions(AdventureWorks adventureWorks)
{
    MetadataWorkspace metadata = ((IObjectContextAdapter)adventureWorks).ObjectContext.MetadataWorkspace;
    TypeUsage stringTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetPrimitiveTypes(DataSpace.CSpace)
        .Single(type =&amp;gt; type.ClrEquivalentType == typeof(string)));
    TypeUsage nameRowTypeUsage = TypeUsage.CreateDefaultTypeUsage(RowType.Create(
        EnumerableEx.Return(EdmProperty.Create(nameof(Product.Name), stringTypeUsage)),
        Enumerable.Empty&amp;lt;MetadataProperty&amp;gt;()));
    TypeUsage productTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetType(nameof(Product), &quot;CodeFirstDatabaseSchema&quot;, DataSpace.SSpace));
    EntitySet productEntitySet = metadata
        .GetEntityContainer(&quot;CodeFirstDatabase&quot;, DataSpace.SSpace)
        .GetEntitySetByName(nameof(Product), false);

    DbProjectExpression query = DbExpressionBuilder.Project(
        DbExpressionBuilder.BindAs(
            DbExpressionBuilder.Limit(
                DbExpressionBuilder.Scan(productEntitySet),
                DbExpressionBuilder.Constant(1)),
            &quot;Limit1&quot;),
        DbExpressionBuilder.New(
            nameRowTypeUsage,
            DbExpressionBuilder.Property(
                DbExpressionBuilder.Variable(productTypeUsage, &quot;Limit1&quot;), nameof(Product.Name))));
    DbQueryCommandTree commandTree = new DbQueryCommandTree(metadata, DataSpace.SSpace, query);
    return commandTree.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query
  |_DbProjectExpression (ExpressionKind = Project, ResultType = Collection(Row[&apos;Name&apos; = Edm.String]))
    |_Input
    | |_DbExpressionBinding (VariableType = Product)
    |   |_VariableName = &apos;Limit1&apos;
    |   |_Expression
    |     |_DbLimitExpression (ExpressionKind = Limit, ResultType = Collection(Product))
    |       |_Argument
    |       | |_DbScanExpression (ExpressionKind = Scan, ResultType = Collection(Product))
    |       |   |_Target = Products
    |       |_Limit
    |         |_DbConstantExpression (ExpressionKind = Constant, ResultType = Edm.Int32)
    |           |_Value = 1
    |_Projection
      |_DbNewInstanceExpression (ExpressionKind = NewInstance, ResultType = Row[&apos;Name&apos; = Edm.String])
        |_Arguments
          |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
            |_Property = ‘Name’
            |_Instance
              |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
                |_VariableName = &apos;Limit1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Compile LINQ query method calls&lt;/h3&gt;
&lt;p&gt;EF Core first calls Remotion.Linq library to compile LINQ query method call nodes to QueryModel. Under Remotion.Linq.Parsing.Structure.IntermediateModel namespace, Remotion.Linq provides IExpressionNode interface, and many types implementing that interface, where each type can process a certain kind of query method call, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MethodCallExpression node representing Queryable.Where call is processed by WhereExpressionNode, and converted to Remotion.Linq.Clauses.WhereClause, which is a part of QueryModel&lt;/li&gt;
&lt;li&gt;MethodCallExpression node representing Queryable.Select call is processed by SelectExpressionNode, and converted to Remotion.Linq.Clauses.SelectClause, which is a part of QueryModel&lt;/li&gt;
&lt;li&gt;MethodCallExpression node representing Queryable.First or Queryable.FirstOrDefault call is processed by FirstExpressionNode, and converted to Remotion.Linq.Clauses.ResultOperators.FirstResultOperator, which is a part of QueryModel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. Then EF Core continues to compile QueryModel to SelectExpression. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WhereClause is converted to predicate child nodes of the SelectExpression&lt;/li&gt;
&lt;li&gt;SelectClause is converted to projection child nodes of the SelectExpression&lt;/li&gt;
&lt;li&gt;FirstResultOperator is converted to limit child node of the SelectExpression&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the fore mentioned ExpressionConverter is a huge type. It has tons of nested translator types for all supported expression tree nodes. For example&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WhereTranslator compiles Queryable.Where node to FilterDbExpression node&lt;/li&gt;
&lt;li&gt;SelectTranslator compiles Queryable.Select node to ProjectDbExpression node&lt;/li&gt;
&lt;li&gt;FirstTranslator compiles Queryable.First or Queryable.FirstOrDefault to LimitDbExpression node&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Compile .NET API calls&lt;/h3&gt;
&lt;p&gt;The above Where query’s predicate has a logic to call string.Length and compare the result to a constant. EF Core provides translator types under Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal namespace to translate these .NET API calls. Here MemberExpression node representing string.Length call is processed by SqlServerStringLengthTranslator, and converted to a SqlFunctionExpression node representing SQL database function LEN call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.Internal
{
    public class SqlServerStringLengthTranslator : IMemberTranslator
    {
        public virtual Expression Translate(MemberExpression memberExpression) =&amp;gt; 
            memberExpression.Expression != null
            &amp;amp;&amp;amp; memberExpression.Expression.Type == typeof(string)
            &amp;amp;&amp;amp; memberExpression.Member.Name == nameof(string.Length)
                ? new SqlFunctionExpression(&quot;LEN&quot;, memberExpression.Type, new Expression[] { memberExpression.Expression })
                : null;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are many other translators to cover other basic .NET APIs of System.String, System.Enum, System.DateTime, System.Guid, System.Math, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MethodCallExpression node representing string.Contains call (e.g. product.Name.Contains(“M”)) is processed by SqlServerContainsOptimizedTranslator, and converted to a BinaryExpression node representing SQL database int comparison, where the left child node is a SqlFunctionExpression node representing SQL database function CHARINDEX call, and the right child node is a ConstantExpression node representing 0 (e.g. CHARINDEX(N&apos;M&apos;, product.Name) &amp;gt; 0)&lt;/li&gt;
&lt;li&gt;MethodCallExpression node representing Math.Ceiling call is processed by SqlServerMathCeilingTranslator, and converted to SqlFunctionExpression node representing SQL database function CEILING call&lt;/li&gt;
&lt;li&gt;MemberExpression node representing DateTime.Now or DateTime.UtcNow property access, is processed by SqlServerDateTimeNowTranslator, and converted to SqlFunctionExpression node representing SQL database function GETDATE or GETUTCDATE call&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;There are also a few other APIs covered with other EF Core components. For example, In Remotion.Linq, MethodCallExpression node representing Enumerable.Contains or List&amp;lt;T&amp;gt;.Contains call is converted to to Remotion.Linq.Clauses.ResultOperators.ContainsResultOperator. Then in EF Core, ContainsResultOperator is processed by Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor. and converted to InExpression node representing SQL database IN operation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As fore mentioned, EF provides nested translator types inside ExpressionConverter.There are also many other translators covering .NET APIs of System.String, Microsoft.VisualBasic.Strings, System.Decimal, System.Enum, System.DateTime, System.DateTimeOffset, Microsoft.VisualBasic.DateAndTime, System.Math, System.Guid, System.Nullable&amp;lt;T&amp;gt;, System.Data.Spatial.DbGeography, System.Data.Spatial.DbGeometry, etc.For example,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MethodCallExpression node representing string.Contains call (e.g. product.Name.Contains(“M”)) is processed by StringContainsTranslator, and converted to a DbLikeExpression node representing SQL database LIKE operation (e.g. product.Name LIKE N&apos;%M%&apos;).&lt;/li&gt;
&lt;li&gt;MethodCallExpression node representing Math.Ceiling call is processed by CanonicalFunctionDefaultTranslator, and converted to DbFunctionExpression node representing SQL database function CEILING call&lt;/li&gt;
&lt;li&gt;MemberExpression node representing DateTime.Now or DateTime.UtcNow property access, is processed by SqlServerDateTimeNowTranslator, and converted to DbFunctionExpression node representing SQL database function SYSDATETIME or SYSUTCDATETIME call&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similar to EF Core, in EF MethodCallExpression node representing Enumerable.Contains or List&amp;lt;T&amp;gt;.Contains call is not processed by translators, but by System.Data.Entity.Core.Objects.ELinq.LinqExpressionNormalizer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Remote API call vs. local API call&lt;/h3&gt;
&lt;p&gt;Apparently EF/Core can only compile the supported .NET API calls, like the above string.Length call. It cannot compile arbitrary API calls. The following example wraps the string.Length call and result comparison with constant into a custom predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static bool FilterName(string name) =&amp;gt; name.Length &amp;gt; 10;

internal static void WhereAndSelectWithCustomPredicate(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .Where(product =&amp;gt; FilterName(product.Name))
        .Select(product =&amp;gt; product.Name); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name]
    // FROM [Production].[Product] AS [product]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At compile time, the predicate expression tree has a MethodCallExpression node representing FilterName call, which apparently cannot be compiled to SQL by EF/Core. In this case, EF Core execute FilterName locally.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When EF fails to compile query, it throws exception. So in EF, the above example throws NotSupportedException: LINQ to Entities does not recognize the method &apos;Boolean FilterName(System.String)&apos; method, and this method cannot be translated into a store expression. To make it work, the Where query has to be manually specified as local LINQ to Objects query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectWithLocalPredicate(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IEnumerable&amp;lt;string&amp;gt; products = source
        .Select(product =&amp;gt; product.Name) // LINQ to Entities.
        .AsEnumerable() // LINQ to Objects.
        .Where(name =&amp;gt; FilterName(name)); // Define query, IEnumerable&amp;lt;string&amp;gt; instead of IQueryable&amp;lt;string&amp;gt;.
    products.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Compile database function call&lt;/h3&gt;
&lt;p&gt;EF Core does not support database function call.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Not all database APIs has .NET built-in APIs to translated from, for example, there is no mapping .NET API for SQL database DATEDIFF function. EF provides mapping methods to address these scenarios. As fore mentioned, EF implements a provider model, and these mapping methods are provides in 2 levels too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In EntityFramework.dll, System.Data.Entity.DbFunctions provides mapping methods supported by all database providers, like DbFunctions.Reverse to reverse a string, DbFunction.AsUnicode to ensure a string is treated as Unicode, etc. These common database functions are also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb738626.aspx&quot;&gt;canonical functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In EntityFramework.SqlServer.dll, System.Data.Entity.SqlServer.SqlFunctions provides mapping methods from SQL database functions, like SqlFunctions.Checksum method for CHECKSUM function, SqlFunctions.CurrentUser for CURRENT_USER function, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following LINQ to Entities query calculates the number of days between current time and photo’s last modified time. In the following LINQ to Entities query expression tree, the MethodCallExpression node representing DbFunctions.DiffDays call can be compiled by EF, and is converted to a DbFunctionExpression node representing canonical function Edm.DiffDays call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DbFunction(AdventureWorks adventureWorks)
{
    var photos = adventureWorks.ProductPhotos.Select(photo =&amp;gt; new
    {
        LargePhotoFileName = photo.LargePhotoFileName,
        UnmodifiedDays = DbFunctions.DiffDays(photo.ModifiedDate, DateTime.UtcNow)
    });
    adventureWorks.Compile(photos.Expression).WriteLine();
    photos.WriteLines();
    // SELECT 
    //    1 AS [C1], 
    //    [Extent1].[LargePhotoFileName] AS [LargePhotoFileName], 
    //    DATEDIFF (day, [Extent1].[ModifiedDate], SysUtcDateTime()) AS [C2]
    //    FROM [Production].[ProductPhoto] AS [Extent1]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example filters the product’s names with a pattern. The SqlFunction.PatIndex call is compiled by EF, and converted to SQL database function SqlServer.PATINDEX call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SqlFunction(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;string&amp;gt; products = adventureWorks.Products
        .Select(product =&amp;gt; product.Name)
        .Where(name =&amp;gt; SqlFunctions.PatIndex(name, &quot;%Touring%50%&quot;) &amp;gt; 0); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE ( CAST(PATINDEX([Extent1].[Name], N&apos;%Touring%50%&apos;) AS int)) &amp;gt; 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Database expression tree to SQL&lt;/h2&gt;
&lt;h3&gt;SQL generator and SQL command&lt;/h3&gt;
&lt;p&gt;The SQL database provider of EF/Core provides a SQL generator to traverse the compiled database query abstract syntactic tree, and generate SQL database specific remote SQL query. EF Core provides SQL generator as Microsoft.EntityFrameworkCore.Query.Sql.IQuerySqlGenerator interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.Query.Sql
{
    public interface IQuerySqlGenerator
    {
        IRelationalCommand GenerateSql(IReadOnlyDictionary&amp;lt;string, object&amp;gt; parameterValues);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is implemented by Microsoft.EntityFrameworkCore.Query.Sql.Internal.SqlServerQuerySqlGenerator. SQL generator wraps a database expression tree inside, and provides a GenerateSql method, which returns Microsoft.EntityFrameworkCore.Storage.IRelationalCommand to represents generated SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore.Storage
{
    public interface IRelationalCommand
    {
        string CommandText { get; }

        IReadOnlyList&amp;lt;IRelationalParameter&amp;gt; Parameters { get; }

        RelationalDataReader ExecuteReader(
            IRelationalConnection connection, IReadOnlyDictionary&amp;lt;string, object&amp;gt; parameterValues);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is generated by Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand in Microsoft.EntityFrameworkCore.Relational package.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Similarly, EF also provides SQL generator with a GenerateSql method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer.SqlGen
{
    internal class SqlGenerator : DbExpressionVisitor&amp;lt;ISqlFragment&amp;gt;
    {
        internal string GenerateSql(DbQueryCommandTree tree, out HashSet&amp;lt;string&amp;gt; paramsToForceNonUnicode);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And EF represents the generated SQL with System.Data.Common.DbCommand in ADO.NET:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Common
{
    public abstract class DbCommand : Component, IDbCommand, IDisposable
    {
        public abstract string CommandText { get; set; }

        public DbParameterCollection Parameters { get; }

        public DbDataReader ExecuteReader();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And EF’s SQL database provider uses ADO.NET type System.Data.SqlClient.SqlCommand, which is derived from DbCommand.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Generate SQL from database expression tree&lt;/h3&gt;
&lt;p&gt;The following extension method of DbContext can take database command tree, and generate SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IRelationalCommand Generate(
    this DbContext dbContext, 
    SelectExpression databaseExpression, 
    IReadOnlyDictionary&amp;lt;string, object&amp;gt; parameters = null)
{
    IQuerySqlGeneratorFactory sqlGeneratorFactory = dbContext.GetService&amp;lt;IQuerySqlGeneratorFactory&amp;gt;();
    IQuerySqlGenerator sqlGenerator = sqlGeneratorFactory.CreateDefault(databaseExpression);
    return sqlGenerator.GenerateSql(parameters ?? new Dictionary&amp;lt;string, object&amp;gt;());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static DbCommand Generate(this DbContext context, DbQueryCommandTree commandTree)
{
    MetadataWorkspace metadataWorkspace = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;
    StoreItemCollection itemCollection = (StoreItemCollection)metadataWorkspace
        .GetItemCollection(DataSpace.SSpace);
    DbCommandDefinition commandDefinition = SqlProviderServices.Instance
        .CreateCommandDefinition(itemCollection.ProviderManifest, commandTree);
    return commandDefinition.CreateCommand();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside the last DbCommandDefinition.CreateCommand call, a SqlGenerator instance is constructed with SQL database’s version (detected with ADO.NET API SqlConnection.ServerVersion), and its GenerateSql method is called to generate SQL, then the generated SQL and parameters (provided by DbQueryCommandTree.Parameters) are wrapped into a DbCommand instance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The above WhereAndSelectDatabaseExpressions and SelectAndFirstDatabaseExpressions method builds database expression trees from scratch. Take them as an example to generate SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectSql(AdventureWorks adventureWorks)
{
    SelectExpression databaseExpression = WhereAndSelectDatabaseExpressions(adventureWorks);
    IRelationalCommand sql = adventureWorks.Generate(databaseExpression: databaseExpression, parameters: null);
    sql.CommandText.WriteLine();
    // SELECT [product].[Name]
    // FROM [Production].[ProductCategory] AS [product]
    // WHERE CAST(LEN([product].[Name]) AS int) &amp;gt; 10
}

internal static void SelectAndFirstSql(AdventureWorks adventureWorks)
{
    SelectExpression databaseExpression = SelectAndFirstDatabaseExpressions(adventureWorks);
    IRelationalCommand sql = adventureWorks.Generate(databaseExpression: databaseExpression, parameters: null);
    sql.CommandText.WriteLine();
    // SELECT TOP(1) [product].[Name]
    // FROM [Production].[Product] AS [product]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SQL generator traverses the command tree nodes, a specific Visit overloads is called for each supported node type. It generates SELECT clause from DbProjectionExpression node, FROM clause from DbScanExpression node, WHERE clause from DbFilterExpression node, LIKE operator from DbLikeExpression, etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, SQL can be generated in similar way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectSql(AdventureWorks adventureWorks)
{
    DbQueryCommandTree databaseExpressionAndParameters = WhereAndSelectDatabaseExpressions(adventureWorks);
    DbCommand sql = adventureWorks.Generate(databaseExpressionAndParameters);
    sql.CommandText.WriteLine();
    // SELECT 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE [Extent1].[Name] LIKE N&apos;M%&apos;
}
        
internal static void SelectAndFirstSql(AdventureWorks adventureWorks)
{
    DbQueryCommandTree databaseExpressionAndParameters = SelectAndFirstDatabaseExpressions(adventureWorks);
    DbCommand sql = adventureWorks.Generate(databaseExpressionAndParameters);
    sql.CommandText.WriteLine();
    // SELECT TOP (1) 
    //    [c].[Name] AS [Name]
    //    FROM [Production].[Product] AS [c]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SQL generator generates TOP expression from DbLimitExpression node, which is an example where SQL database’s version matters. Inside the SqlGenerator.Visit overload for DbLimitExpression, TOP 1 is generated for SQL Server 2000 (8.0), and TOP(1) is generated for later version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So finally LINQ to Entities queries are translated to remote SQL database queries. The next part discusses the query execution and data loading.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (4) Query Methods (Operators)</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-4-query-methods-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-4-query-methods-7/</guid><description>This part discusses how to query SQL database with the defined mapping entities. In EF/Core, LINQ to Entities supports most of the methods provided by Queryable:</description><pubDate>Fri, 15 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Latest EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-4-query-methods&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-4-query-methods&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;EF version of this article: &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-4-query-methods&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-4-query-methods&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This part discusses how to query SQL database with the defined mapping entities. In EF/Core, LINQ to Entities supports most of the methods provided by Queryable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sequence queries: return a new IQueryable&amp;lt;T&amp;gt; source&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Filtering (restriction): Where, OfType*&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select&lt;/li&gt;
&lt;li&gt;Generation: DefaultIfEmpty*&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy*&lt;/li&gt;
&lt;li&gt;Join: Join, GroupJoin, SelectMany, Select&lt;/li&gt;
&lt;li&gt;Concatenation: Concat*&lt;/li&gt;
&lt;li&gt;Set: Distinct, GroupBy*, Union*, Intersect*, Except*&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy*, ThenBy, OrderByDescending*, ThenByDescending, Reverse&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsQueryable&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Value queries: return a single value
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last*, LastOrDefault*, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average*&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In above list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The crossed methods are not supported by LINQ to Entities (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb738550.aspx&quot;&gt;the list provided by MDSN&lt;/a&gt; is not up to date), because they cannot be translated to proper SQL database operations. For example, SQL database has no built-in Zip operation support. Calling these crossed methods throws NotSupportedException at runtime&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The underlined methods have some overloads supported by LINQ to Entities, and other overloads not supported:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except, Contains, the overloads accepting IEqualityComparer&amp;lt;T&amp;gt; parameter are not supported, because apparently IEqualityComparer&amp;lt;T&amp;gt; has no equivalent SQL translation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For OrderBy, ThenBy, OrderByDescending, ThenByDescending, the overloads with IComparer&amp;lt;T&amp;gt; parameter are not supported&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For Where, Select, SelectMany, the indexed overloads are not supported&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In EF Core, the methods marked with * can execute the query locally in some cases, without being translated to SQL.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EF translate all supported query methods to SQL and executed in database.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For LINQ to Entities, apparently these methods enable fluent method chaining, implement the same LINQ query expression pattern as LINQ to Objects and Parallel LINQ. So in this part, most of the LINQ to Entities queries are demonstrated with query methods.&lt;/p&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;p&gt;Similar to the other kinds of LINQ, LINQ to Entities implements deferred execution for these query methods returning IQueryable&amp;lt;T&amp;gt;. The SQL query is translated and executed only when trying to pull the result value from IQueryable&amp;lt;T&amp;gt; for the first time.&lt;/p&gt;
&lt;h3&gt;Filtering (restriction)&lt;/h3&gt;
&lt;p&gt;EF/Core translates Where query method call to WHERE clause in SQL, and translates the predicate expression tree (again, not predicate function) to the condition in WHERE clause. The following example queries categories with ProductCategoryID greater than 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Where(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0); // Define query.
    categories.WriteLines(category =&amp;gt; category.Name); // Execute query.
    // SELECT [category].[ProductCategoryID], [category].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE [category].[ProductCategoryID] &amp;gt; 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When WriteLines executes, it pulls the results from the query represented by IQueryable&amp;lt;ProductCategory&amp;gt;. At this moment, the query is translated to SQL, and executed in database, then SQL execution results are read by EF/Core and yielded.&lt;/p&gt;
&lt;p&gt;The C# || operator in the predicate expression tree is translated to SQL OR operator in WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithOr(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;
        category.ProductCategoryID &amp;lt; 2 || category.ProductCategoryID &amp;gt; 3); // Define query.
    categories.WriteLines(category =&amp;gt; category.Name); // Execute query.
    // SELECT [category].[ProductCategoryID], [category].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE ([category].[ProductCategoryID] &amp;lt; 2) OR ([category].[ProductCategoryID] &amp;gt; 3)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the C# &amp;amp;&amp;amp; operator is translated to SQL AND operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithAnd(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;
        category.ProductCategoryID &amp;gt; 0 &amp;amp;&amp;amp; category.ProductCategoryID &amp;lt; 5); // Define query.
    categories.WriteLines(category =&amp;gt; category.Name); // Execute query.
    // SELECT [category].[ProductCategoryID], [category].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE ([category].[ProductCategoryID] &amp;gt; 0) AND ([category].[ProductCategoryID] &amp;lt; 5)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple Where calls are also translated to one single WHERE clause with AND:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndWhere(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source
        .Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0)
        .Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 5); // Define query.
    categories.WriteLines(category =&amp;gt; category.Name); // Execute query.
    // SELECT [category].[ProductCategoryID], [category].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE ([category].[ProductCategoryID] &amp;gt; 0) AND ([category].[ProductCategoryID] &amp;lt; 5)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other filtering method, OfType, can be used for entity types in inheritance hierarchy. And it is equivalent to Where query with is operator. The following examples both query sales transactions from all transactions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithIs(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;
    IQueryable&amp;lt;TransactionHistory&amp;gt; transactions = source.Where(transaction =&amp;gt; transaction is SalesTransactionHistory); // Define query.
    transactions.WriteLines(transaction =&amp;gt; $&quot;{transaction.GetType().Name} {transaction.TransactionDate} {transaction.ActualCost}&quot;); // Execute query.
    // SELECT [transaction].[TransactionID], [transaction].[ActualCost], [transaction].[ProductID], [transaction].[Quantity], [transaction].[TransactionDate], [transaction].[TransactionType]
    // FROM [Production].[TransactionHistory] AS [transaction]
    // WHERE [transaction].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;) AND ([transaction].[TransactionType] = N&apos;S&apos;)
}

internal static void OfTypeEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;
    IQueryable&amp;lt;WorkTransactionHistory&amp;gt; transactions = source.OfType&amp;lt;WorkTransactionHistory&amp;gt;(); // Define query.
    transactions.WriteLines(transaction =&amp;gt; $&quot;{transaction.GetType().Name} {transaction.TransactionDate} {transaction.ActualCost}&quot;); // Execute query.
    // SELECT [t].[TransactionID], [t].[ActualCost], [t].[ProductID], [t].[Quantity], [t].[TransactionDate], [t].[TransactionType]
    // FROM [Production].[TransactionHistory] AS [t]
    // WHERE [t].[TransactionType] = N&apos;W&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When primitive type is specified for OfType, it works locally. The following example queries products with ProductSubcategoryID not null:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OfTypePrimitive(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;int&amp;gt; products = source.Select(product =&amp;gt; product.ProductSubcategoryID).OfType&amp;lt;int&amp;gt;(); // Define query.
    products.ToArray().Length.WriteLine(); // Execute query.
    // SELECT [p].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [p]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF Core, the above query is translated to a basic SELECT statement without filtering. EF Core executes the translated SQL to query the specified nullable int column of all rows to local, then the int results are locally filtered from all the nullable int results.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not support OfType with primitive type. In EF, the above query throws NotSupportedException: &apos;System.Int32&apos; is not a valid metadata type for type filtering operations. Type filtering is only valid on entity types and complex types.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Mapping (projection)&lt;/h3&gt;
&lt;p&gt;In above queries, Queryable.Select is not called, and the query results are entities. So in the translated SQL, the SELECT clause queries all the mapped columns in order to construct the result entities. When Select is called, the selector expression tree is translated into SELECT clause. The following example queries persons’ full names by concatenating the first name and last name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Select(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Person&amp;gt; source = adventureWorks.People;
    IQueryable&amp;lt;string&amp;gt; names = source.Select(person =&amp;gt;
        person.FirstName + &quot; &quot; + person.LastName); // Define query.
    names.WriteLines(); // Execute query.
    // SELECT ([person].[FirstName] + N&apos; &apos;) + [person].[LastName]
    // FROM [Person].[Person] AS [person]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF/Core, Select also work with anonymous type. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAnonymousType(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source.Select(product =&amp;gt;
        new { Name = product.Name, IsExpensive = product.ListPrice &amp;gt; 1_000 }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], CASE
    //    WHEN [product].[ListPrice] &amp;gt; 1000.0
    //    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    // END
    // FROM [Production].[Product] AS [product]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF Core, Select supports entity type too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; products = source
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 1_000)
        .Select(product =&amp;gt; new Product()
        {
            ProductID = product.ProductID,
            Name = product.Name
        }); // Define query.
    products.WriteLines(product =&amp;gt; $&quot;{product.ProductID}: {product.Name}&quot;); // Execute query.
    // SELECT [product].[ProductID], [product].[Name]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 1000.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, Select does not support entity type. The above query throws NotSupportedException: The entity or complex type &apos;Product&apos; cannot be constructed in a LINQ to Entities query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;As fore mentioned, DefaultIfEmpty is the only built-in generation method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source
        .Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)
        .DefaultIfEmpty(); // Define query.
    categories.ForEach( // Execute query.
        category =&amp;gt; (category == null).WriteLine()); // True
    // SELECT [t].[ProductCategoryID], [t].[Name]
    // FROM (
    //    SELECT NULL AS [empty]
    // ) AS [empty]
    // LEFT JOIN (
    //    SELECT [category].[ProductCategoryID], [category].[Name]
    //    FROM [Production].[ProductCategory] AS [category]
    //    WHERE [category].[ProductCategoryID] &amp;lt; 0
    // ) AS [t] ON 1 = 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above query, Where method is translated to SQL query with WHERE clause. Since DefaultIfEmpty should yield at least 1 entity, it is translated to LEFT JOIN with a single row table on a condition that always holds, so that the final query result is guaranteed to have at least 1 row. Here Where filters out all entities, in another word, the right table of LEFT JOIN has no rows, so the LEFT JOIN results 1 row, where all columns are NULL, including primary key. Therefore, DefaultIfEmpty yields a null entity. Besides entity type, DefaultIfEmpty works with primitive type in the same way.&lt;/p&gt;
&lt;p&gt;The other DefaultIfEmpty overload accepts a specified default value. EF Core does not translate it to SQL, but execute the query logic locally. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyEntity(AdventureWorks adventureWorks)
{
    ProductCategory @default = new ProductCategory() { Name = nameof(ProductCategory) };
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source
        .Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)
        .DefaultIfEmpty(@default); ; // Define query.
    categories.WriteLines( // Execute query.
        category =&amp;gt; category?.Name); // ProductCategory
    // SELECT [category].[ProductCategoryID], [category].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE [category].[ProductCategoryID] &amp;lt; 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the source query for DefaultIfEmpty is translated to SQL and executed, then EF Core reads the results to local, and detect the results locally. If there is no result row, the specified default value is yielded. DefaultIfEmpty works for specified default primitive value locally too.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, DefaultIfEmpty without default value works with entity type and primitive type. In both cases it is translated to a similar left outer join with a single row. Since EF executes query remotely, the overload with specified default value does not work with entity type, and throws NotSupportedException: Unable to create a constant value of type &apos;ProductCategory&apos;. Only primitive types or enumeration types are supported in this context. This overload works with specified default primitive value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyWithDefaultPrimitive(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    IQueryable&amp;lt;int&amp;gt; categories = source
        .Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 0)
        .Select(category =&amp;gt; category.ProductCategoryID)
        .DefaultIfEmpty(-1); // Define query.
    categories.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    CASE WHEN ([Project1].[C1] IS NULL) THEN -1 ELSE [Project1].[ProductCategoryID] END AS [C1]
    //    FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
    //    LEFT OUTER JOIN  (SELECT 
    //        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    //        cast(1 as tinyint) AS [C1]
    //        FROM [Production].[ProductCategory] AS [Extent1]
    //        WHERE [Extent1].[ProductCategoryID] &amp;lt; 0 ) AS [Project1] ON 1 = 1
#else
    // SELECT [category].[ProductCategoryID]
    // FROM [Production].[ProductCategory] AS [category]
    // WHERE [category].[ProductCategoryID] &amp;lt; 0
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the default value –1 is translated into the remote SQL query. It is the query result if the right table of left outer join is empty. So there is no local query or local detection executed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just like in LINQ to Objects, DefaultIfEmpty can also be used to implement outer join, which is discussed later.&lt;/p&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;EF Core execute grouping locally. For example. The following is a simple example that groups the subcategories by category:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupBy(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    IQueryable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; groups = source.GroupBy(
        keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
        elementSelector: subcategory =&amp;gt; subcategory.Name); // Define query.
    groups.WriteLines(group =&amp;gt; $&quot;{group.Key}: {string.Join(&quot;, &quot;, group)}&quot;); // Execute query.
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // ORDER BY [subcategory].[ProductCategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core only translates GroupBy an additional ORDER BY clause with the grouping key, so that when reading the SQL execution results to local, the subcategories appears group by group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF only supports remote grouping. In EF, the above GroupBy is fully translated to SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project2].[ProductCategoryID] AS [ProductCategoryID], 
    [Project2].[C1] AS [C1], 
    [Project2].[Name] AS [Name]
    FROM ( SELECT 
        [Distinct1].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent2].[Name] AS [Name], 
        CASE WHEN ([Extent2].[ProductCategoryID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM   (SELECT DISTINCT 
            [Extent1].[ProductCategoryID] AS [ProductCategoryID]
            FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
        LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
    )  AS [Project2]
    ORDER BY [Project2].[ProductCategoryID] ASC, [Project2].[C1] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to LEFT OUTER JOIN instead of GROUP BY, because above GroupBy returns hierarchical results (a sequence of groups, where each group is a sequence of results). In the translated SQL, the distinct keys are queried with SELECT DISTINCT. Then these keys left outer joins the rows with LEFT OUTER JOIN, and results all available key-row pairs, which are sorted by key with ORDER BY. So eventually EF reads and yields the results group by group.&lt;/p&gt;
&lt;p&gt;When GroupBy returns flattened results (sequence of results), it is translated to GROUP BY clause. This can be done with a GroupBy overload accepting a result selector, or equivalently an additional Select query. The following examples call aggregation query method Count to flatten the results, and they have identical translation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithResultSelector(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    var groups = source.GroupBy(
        keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
        elementSelector: subcategory =&amp;gt; subcategory.Name,
        resultSelector: (key, group) =&amp;gt; new { CategoryID = key, SubcategoryCount = group.Count() }); // Define query.
    groups.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [GroupBy1].[K1] AS [ProductCategoryID], 
    //    [GroupBy1].[A1] AS [C1]
    //    FROM ( SELECT 
    //        [Extent1].[ProductCategoryID] AS [K1], 
    //        COUNT(1) AS [A1]
    //        FROM [Production].[ProductSubcategory] AS [Extent1]
    //        GROUP BY [Extent1].[ProductCategoryID]
    //    )  AS [GroupBy1]
#else
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // ORDER BY [subcategory].[ProductCategoryID]
#endif
}

internal static void GroupByAndSelect(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    var groups = source
        .GroupBy(
            keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
            elementSelector: subcategory =&amp;gt; subcategory.Name)
        .Select(group =&amp;gt; new { CategoryID = group.Key, SubcategoryCount = group.Count() }); // Define query.
    groups.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SelectMany can flatten hierarchical results too. The following GroupBy example does not have aggregation subquery, so it cannot be translated to GROUP BY. It is translated to INNER JOIN::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByAndSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; distinct = source
        .GroupBy(keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID)
        .SelectMany(group =&amp;gt; group); // Define query.
    distinct.WriteLines(subcategory =&amp;gt; subcategory.Name); // Execute query.
#if EF
    // SELECT 
    //    [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    //    [Extent2].[Name] AS [Name], 
    //    [Extent2].[ProductCategoryID] AS [ProductCategoryID]
    //    FROM   (SELECT DISTINCT 
    //        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
    //        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    //    INNER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
#else
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // ORDER BY [subcategory].[ProductCategoryID]
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;GroupBy’s key selector can return anonymous type to support grouping by multiple keys, still locally in EF Core:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByMultipleKeys(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var groups = source.GroupBy(
        keySelector: product =&amp;gt; new { ProductSubcategoryID = product.ProductSubcategoryID, ListPrice = product.ListPrice },
        resultSelector: (key, group) =&amp;gt; new
        {
            ProductSubcategoryID = key.ProductSubcategoryID,
            ListPrice = key.ListPrice,
            Count = group.Count()
        }); // Define query.
    groups.WriteLines(); // Execute query.
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ProductSubcategoryID], [product].[ListPrice]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF properly translates the above query to GROUP BY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [GroupBy1].[K2] AS [ProductSubcategoryID], 
    [GroupBy1].[K1] AS [ListPrice], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
        [Extent1].[ListPrice] AS [K1], 
        [Extent1].[ProductSubcategoryID] AS [K2], 
        COUNT(1) AS [A1]
        FROM [Production].[Product] AS [Extent1]
        GROUP BY [Extent1].[ListPrice], [Extent1].[ProductSubcategoryID]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;h3&gt;Inner join&lt;/h3&gt;
&lt;p&gt;Similar to LINQ to Objects, Join is provided for inner join. The following example simply join the subcategories and categories with foreign key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithJoin(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer.Join(
        inner: inner,
        outerKeySelector: category =&amp;gt; category.ProductCategoryID,
        innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
        resultSelector: (category, subcategory) =&amp;gt;
            new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    join subcategory in inner
    //    on category.ProductCategoryID equals subcategory.ProductCategoryID
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
    // SELECT [category].[Name], [subcategory].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // INNER JOIN [Production].[ProductSubcategory] AS [subcategory] ON [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Join’s key selectors can return anonymous type to join with multiple keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithMultipleKeys(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products;
    IQueryable&amp;lt;TransactionHistory&amp;gt; inner = adventureWorks.Transactions;
    var transactions = outer.Join(
        inner: inner,
        outerKeySelector: product =&amp;gt;
            new { ProductID = product.ProductID, UnitPrice = product.ListPrice },
        innerKeySelector: transaction =&amp;gt;
            new { ProductID = transaction.ProductID, UnitPrice = transaction.ActualCost / transaction.Quantity },
        resultSelector: (product, transaction) =&amp;gt;
            new { Name = product.Name, Quantity = transaction.Quantity }); // Define query.
    // var transactions =
    //    from product in adventureWorks.Products
    //    join transaction in adventureWorks.Transactions
    //    on new { ProductID = product.ProductID, UnitPrice = product.ListPrice }
    //        equals new { ProductID = transaction.ProductID, UnitPrice = transaction.ActualCost / transaction.Quantity }
    //    select new { Name = product.Name, Quantity = transaction.Quantity };
    transactions.WriteLines(); // Execute query.
    // SELECT [product].[Name], [transaction].[Quantity]
    // FROM [Production].[Product] AS [product]
    // INNER JOIN [Production].[TransactionHistory] AS [transaction] ON ([product].[ProductID] = [transaction].[ProductID]) AND ([product].[ListPrice] = ([transaction].[ActualCost] / [transaction].[Quantity]))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like LINQ to Objects, inner join can be done by SelectMany, Select, and GroupJoin as well. In the following example, Select returns hierarchical data, so an additional SelectMany can flatten the result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithSelect(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .Select(category =&amp;gt; new
        {
            Category = category,
            Subcategories = inner
                .Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)
                // LEFT OUTER JOIN if DefaultIfEmpty is called.
        })
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories,
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    select new
    //    {
    //        Category = category,
    //        Subcategories = from subcategory in inner
    //                        where category.ProductCategoryID == subcategory.ProductCategoryID
    //                        select subcategory
    //    } into category
    //    from subcategory in category.Subcategories
    //    select new { Category = category.Category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
    // SELECT [category].[Name], [subcategory].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // CROSS JOIN [Production].[ProductSubcategory] AS [subcategory]
    // WHERE [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core translates the above query to CROOS JOIN with WHERE clause, which is equivalent to the previous INNER JOIN query, with the same query plan.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF still translates above query to INNER JOIN.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The following example implement the same inner join directly with SelectMany. Its SQL translation is the same INNER JOIN as the first Join example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .SelectMany(
            collectionSelector: category =&amp;gt; inner
                .Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID),
                // LEFT OUTER JOIN if DefaultIfEmpty is called.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //   from category in outer
    //   from subcategory in (from subcategory in inner
    //                        where category.ProductCategoryID == subcategory.ProductCategoryID
    //                        select subcategory)
    //   select new { Category = category.Name, Subcategory = subcategory.Name };
    // Or equivalently:
    // var categorySubcategories =
    //    from category in outer
    //    from subcategory in inner
    //    where category.ProductCategoryID == subcategory.ProductCategoryID
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above Select and SelectMany has a Where subquery to filter the related entities to join with. The Where subquery can be substituted by collection navigation property. After the substitution, the queries are translated to the same INNER JOIN as the first Join example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithSelectAndRelationship(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    var categorySubcategories = outer
        .Select(category =&amp;gt; new { Category = category, Subcategories = category.ProductSubcategories })
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories,
            // LEFT OUTER JOIN if DefaultIfEmpty is missing.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    select new { Category = category, Subcategories = category.ProductSubcategories } into category
    //    from subcategory in category.Subcategories
    //    select new { Category = category.Category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}

internal static void InnerJoinWithSelectManyAndRelationship(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    var categorySubcategories = outer.SelectMany(
        collectionSelector: category =&amp;gt; category.ProductSubcategories,
        // LEFT OUTER JOIN if DefaultIfEmpty is missing.
        resultSelector: (category, subcategory) =&amp;gt;
            new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    from subcategory in category.ProductSubcategories
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupJoin also returns hierarchical result, so again an additional SelectMany can flatten the result. The following example still has the same INNER JOIN translation as the first Join example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithGroupJoinAndSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .GroupJoin(
            inner: inner,
            outerKeySelector: category =&amp;gt; category.ProductCategoryID,
            innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
            resultSelector: (category, subcategories) =&amp;gt;
                new { Category = category, Subcategories = subcategories })
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories,
            // LEFT OUTER JOIN if DefaultIfEmpty is called.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    join subcategory in inner
    //    on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories
    //    from subcategory in subcategories
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Navigation property makes it very easy to join entities with relationship. The following example inner joins 3 entity types, where 2 entity types have many-to-many relationship with a junction entity type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MultipleInnerJoinsWithRelationship(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var productPhotos = source.SelectMany(
        collectionSelector: product =&amp;gt; product.ProductProductPhotos,
        resultSelector: (product, productProductPhoto) =&amp;gt; new
        {
            Product = product.Name,
            Photo = productProductPhoto.ProductPhoto.LargePhotoFileName
        }); // Define query.
    // var productPhotos =
    //    from product in source
    //    from productProductPhoto in product.ProductProductPhotos
    //    select new { Product = product.Name, Photo = productProductPhoto.ProductPhoto.LargePhotoFileName };
    productPhotos.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product.ProductProductPhotos.ProductPhoto].[LargePhotoFileName]
    // FROM [Production].[Product] AS [product]
    // INNER JOIN [Production].[ProductProductPhoto] AS [product.ProductProductPhotos] ON [product].[ProductID] = [product.ProductProductPhotos].[ProductID]
    // INNER JOIN [Production].[ProductPhoto] AS [product.ProductProductPhotos.ProductPhoto] ON [product.ProductProductPhotos].[ProductPhotoID] = [product.ProductProductPhotos.ProductPhoto].[ProductPhotoID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Left outer join&lt;/h3&gt;
&lt;p&gt;GroupJoin is provided for left outer join. The following example have categories to left outer join subcategories with foreign key, and the results have all categories with or without matching subcategories. It is translated to LEFT JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoin(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .GroupJoin(
            inner: inner,
            outerKeySelector: category =&amp;gt; category.ProductCategoryID,
            innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
            resultSelector: (category, subcategories) =&amp;gt;
                new { Category = category, Subcategories = subcategories }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    join subcategory in inner
    //    on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories
    //    select new { Category = category, Subcategories = subcategories };
    categorySubcategories.WriteLines(categorySubcategory =&amp;gt;
        $@&quot;{categorySubcategory.Category.Name}: {string.Join(
            &quot;, &quot;, categorySubcategory.Subcategories.Select(subcategory =&amp;gt; subcategory.Name))}&quot;); // Execute query.
    // SELECT [category].[ProductCategoryID], [category].[Name], [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductCategory] AS [category]
    // LEFT JOIN [Production].[ProductSubcategory] AS [subcategory] ON [category].[ProductCategoryID] = [subcategory].[ProductCategoryID]
    // ORDER BY [category].[ProductCategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupJoin returns hierarchical results. So here the translated SQL also sorts the result by the key, so that EF/Core can read the query results group by group. To have flattened results from GroupJoin, SelectMany can be called. As discussed in the LINQ to Objects chapter, an DefaultIfEmpty subquery is required (It becomes inner join if DefaultIfEmpty is missing). The following example has the same SQL translation as above, it just yields result by result instead of group by group.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoinAndSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .GroupJoin(
            inner: inner,
            outerKeySelector: category =&amp;gt; category.ProductCategoryID,
            innerKeySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
            resultSelector: (category, subcategories) =&amp;gt;
                new { Category = category, Subcategories = subcategories }) // Define query.
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories
                .DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category, Subcategory = subcategory }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    join subcategory in inner
    //    on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories
    //    from subcategory in subcategories.DefaultIfEmpty()
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(categorySubcategory =&amp;gt;
        $&quot;{categorySubcategory.Category.Name} {categorySubcategory.Subcategory?.Name}&quot;); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to inner join, left outer join can be done with Select and SelectMany too, with a DefaultIfEmpty subquery. The following queries have the same SQL translation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithSelect(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .Select(category =&amp;gt; new
        {
            Category = category,
            Subcategories = inner
                .Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)
        })
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories
                .DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    select new
    //    {
    //        Category = category,
    //        Subcategories = from subcategory in inner
    //                        where subcategory.ProductCategoryID == category.ProductCategoryID
    //                        select subcategory
    //    } into category
    //    from subcategory in category.Subcategories.DefaultIfEmpty()
    //    select new { Category = category.Category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
    // SELECT [category].[Name], [t1].[Name]
    // FROM [Production].[ProductCategory] AS [category]
    // CROSS APPLY (
    //    SELECT [t0].*
    //    FROM (
    //        SELECT NULL AS [empty]
    //    ) AS [empty0]
    //    LEFT JOIN (
    //        SELECT [subcategory0].*
    //        FROM [Production].[ProductSubcategory] AS [subcategory0]
    //        WHERE [category].[ProductCategoryID] = [subcategory0].[ProductCategoryID]
    //    ) AS [t0] ON 1 = 1
    // ) AS [t1]
}

internal static void LeftOuterJoinWithSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = adventureWorks.ProductSubcategories;
    var categorySubcategories = outer
        .SelectMany(
            collectionSelector: category =&amp;gt; inner
                .Where(subcategory =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)
                .DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    from subcategory in (from subcategory in inner
    //                         where category.ProductCategoryID == subcategory.ProductCategoryID
    //                         select subcategory).DefaultIfEmpty()
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF Core, the above 2 queries are both translated to CROSS APPLY, but this is logically equivalent to LEFT JOIN of the GroupJoin example.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, these translation are the same LEFT OUTER JOIN as previous GroupJoin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As demonstrated for inner join, in the above Select and SelectMany queries, the Where subquery is equivalent to collection navigation property. EF/Core support collection navigation property for left outer join with Select and SelectMany. The following queries are translated to the same LEFT JOIN query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithSelectAndRelationship(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    var categorySubcategories = outer
        .Select(category =&amp;gt; new { Category = category, Subcategories = category.ProductSubcategories })
        .SelectMany(
            collectionSelector: category =&amp;gt; category.Subcategories
                .DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            resultSelector: (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    select new { Category = category, Subcategories = category.ProductSubcategories } into category
    //    from subcategory in category.Subcategories.DefaultIfEmpty()
    //    select new { Category = category.Category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
    // SELECT [category].[Name] AS [Category], [category.ProductSubcategories].[Name] AS [Subcategory]
    // FROM [Production].[ProductCategory] AS [category]
    // LEFT JOIN [Production].[ProductSubcategory] AS [category.ProductSubcategories] ON [category].[ProductCategoryID] = [category.ProductSubcategories].[ProductCategoryID]
}

internal static void LeftOuterJoinWithSelectManyAndRelationship(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = adventureWorks.ProductCategories;
    var categorySubcategories = outer.SelectMany(
        collectionSelector: category =&amp;gt; category.ProductSubcategories
            .DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
        resultSelector: (category, subcategory) =&amp;gt;
            new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    // var categorySubcategories =
    //    from category in outer
    //    from subcategory in category.ProductSubcategories.DefaultIfEmpty()
    //    select new { Category = category.Name, Subcategory = subcategory.Name };
    categorySubcategories.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Cross join&lt;/h3&gt;
&lt;p&gt;Just like LINQ to Objects, cross join can be done with SelectMany and Join. The following example queries the expensive products (list price greater than 2000) and cheap products (list price less than 100), and then cross join them to get all possible product bundles, where each bundle has one expensive product and one cheap product:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithSelectMany(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles = outer.SelectMany(
        collectionSelector: expensiveProduct =&amp;gt; inner,
        resultSelector: (expensiveProduct, cheapProduct) =&amp;gt;
            new { Expensive = expensiveProduct.Name, Cheap = cheapProduct.Name }); // Define query.
    // var bundles =
    //    from outerProduct in outer
    //    from innerProduct in inner
    //    select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name };
    bundles.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product0].[Name]
    // FROM [Production].[Product] AS [product]
    // CROSS JOIN [Production].[Product] AS [product0]
    // WHERE ([product].[ListPrice] &amp;gt; 2000.0) AND ([product0].[ListPrice] &amp;lt; 100.0)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following implementation with Join is equivalent, just have the 2 key selectors always return equal values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithJoin(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; outer = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles = outer.Join(
        inner: inner,
        outerKeySelector: product =&amp;gt; 1,
        innerKeySelector: product =&amp;gt; 1,
        resultSelector: (outerProduct, innerProduct) =&amp;gt;
            new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }); // Define query.
    // var bundles =
    //    from outerProduct in outer
    //    join innerProduct in inner
    //    on 1 equals 1
    //    select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name };
    bundles.WriteLines(); // Execute query.
    // SELECT [product].[Name], [t].[Name]
    // FROM [Production].[Product] AS [product]
    // INNER JOIN (
    //    SELECT [product1].*
    //    FROM [Production].[Product] AS [product1]
    //    WHERE [product1].[ListPrice] &amp;lt; 100.0
    // ) AS [t] ON 1 = 1
    // WHERE [product].[ListPrice] &amp;gt; 2000.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to INNER JOIN, which is equivalent to previous CROSS JOIN, with the same query plan.&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;EF Core does not support Concat for entity.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF translates Concat to UNION ALL. The following example concatenates the cheap products and the expensive products, and query the products’ names:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcatEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;string&amp;gt; concat = first
        .Concat(second)
        .Select(product =&amp;gt; product.Name); // Define query.
    concat.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [UnionAll1].[Name] AS [C1]
    //    FROM  (SELECT 
    //        [Extent1].[Name] AS [Name]
    //        FROM [Production].[Product] AS [Extent1]
    //        WHERE [Extent1].[ListPrice] &amp;lt; cast(100 as decimal(18))
    //    UNION ALL
    //        SELECT 
    //        [Extent2].[Name] AS [Name]
    //        FROM [Production].[Product] AS [Extent2]
    //        WHERE [Extent2].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AS [UnionAll1]
#else
    // ArgumentException: Expression of type &apos;System.Collections.Generic.IEnumerable`1[Product]&apos; cannot be used for parameter of type &apos;System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer]&apos; of method &apos;System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer] Concat[ValueBuffer](System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer], System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer])&apos; Parameter name: arg1
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF Core supports Concat for primitive type, locally. In the above example, Select is called after Concat. It is logically equivalent to call Select before Concat, which works in EF Core:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcatPrimitive(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;string&amp;gt; first = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt; 100)
        .Select(product =&amp;gt; product.Name);
    IQueryable&amp;lt;string&amp;gt; second = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)
        .Select(product =&amp;gt; product.Name);
    IQueryable&amp;lt;string&amp;gt; concat = first.Concat(second); // Define query.
    concat.WriteLines(); // Execute query.
    // SELECT [product].[Name]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;lt; 100.0

    // SELECT [product0].[Name]
    // FROM [Production].[Product] AS [product0]
    // WHERE [product0].[ListPrice] &amp;gt; 2000.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core translates Concat’s 2 data sources to 2 SQL queries, reads the query results to local, and concatenates them locally.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, this above query has identical UNION ALL translation as the first Concat example.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;Distinct works with entity type and primitive type. It is translated to the DISTINCT keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; distinct = source
        .Select(subcategory =&amp;gt; subcategory.ProductCategory)
        .Distinct(); // Define query.
    distinct.WriteLines(category =&amp;gt; $&quot;{category.ProductCategoryID}: {category.Name}&quot;); // Execute query.
    // SELECT DISTINCT [subcategory.ProductCategory].[ProductCategoryID], [subcategory.ProductCategory].[Name]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // INNER JOIN [Production].[ProductCategory] AS [subcategory.ProductCategory] ON [subcategory].[ProductCategoryID] = [subcategory.ProductCategory].[ProductCategoryID]
}

internal static void DistinctPrimitive(AdventureWorks adventureWorks)
{    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    IQueryable&amp;lt;int&amp;gt; distinct = source
        .Select(subcategory =&amp;gt; subcategory.ProductCategoryID)
        .Distinct(); // Define query.
    distinct.WriteLines(); // Execute query.
    // SELECT DISTINCT [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupBy returns groups with distinct keys, so in theory it can be used to query the same result as Distinct:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctWithGroupBy(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = adventureWorks.ProductSubcategories;
    IQueryable&amp;lt;int&amp;gt; distinct = source.GroupBy(
        keySelector: subcategory =&amp;gt; subcategory.ProductCategoryID,
        resultSelector: (key, group) =&amp;gt; key); // Define query.
    distinct.WriteLines(); // Execute query.
    // SELECT [subcategory].[ProductSubcategoryID], [subcategory].[Name], [subcategory].[ProductCategoryID]
    // FROM [Production].[ProductSubcategory] AS [subcategory]
    // ORDER BY [subcategory].[ProductCategoryID]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, as fore mentioned, in EF Core, GroupBy executes locally. The above example only queries grouping keys, however it reads all rows of the table to local, which can be a performance issue.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF always execute queries remotely, so above GroupBy is properly translated to SELECT DISATINCT query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;GroupBy can also be used for more complex scenarios. The following example queries the full product entities with distinct list price:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctWithGroupByAndFirstOrDefault(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; distinct = source.GroupBy(
        keySelector: product =&amp;gt; product.ListPrice,
        resultSelector: (key, group) =&amp;gt; group.FirstOrDefault()); // Define query.
    distinct.WriteLines(); // Execute query.
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ListPrice]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, EF Core does not translate grouping to SQL. In this example, only 1 entities for each key is queried, but EF Core reads all rows to local, and execute the grouping logic locally.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF properly translates the above query to SELECT DISTINCT to query the unique keys, then outer applies each key to one row with OUTER APPLY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[ProductID] AS [ProductID], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ListPrice] AS [ListPrice], 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    FROM   (SELECT DISTINCT 
        [Extent1].[ListPrice] AS [ListPrice]
        FROM [Production].[Product] AS [Extent1] ) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) 
        [Extent2].[ProductID] AS [ProductID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ListPrice] AS [ListPrice], 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID]
        FROM [Production].[Product] AS [Extent2]
        WHERE [Distinct1].[ListPrice] = [Extent2].[ListPrice] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF Core supports Union for entity and primitive types locally.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF translates Union to Union ALL with SELECT DISTINCT, so eventually each result is unique.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UnionEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100);
    IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products
        .Where(product =&amp;gt; product.ProductSubcategoryID == 1);
    IQueryable&amp;lt;Product&amp;gt; union = first.Union(second); // Define query.
    union.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [Distinct1].[C1] AS [C1], 
    //    [Distinct1].[C2] AS [C2], 
    //    [Distinct1].[C3] AS [C3], 
    //    [Distinct1].[C4] AS [C4], 
    //    [Distinct1].[C5] AS [C5]
    //    FROM ( SELECT DISTINCT 
    //        [UnionAll1].[ProductID] AS [C1], 
    //        [UnionAll1].[Name] AS [C2], 
    //        [UnionAll1].[ListPrice] AS [C3], 
    //        [UnionAll1].[ProductSubcategoryID] AS [C4]
    //        FROM  (SELECT 
    //            [Extent1].[ProductID] AS [ProductID], 
    //            [Extent1].[Name] AS [Name], 
    //            [Extent1].[ListPrice] AS [ListPrice], 
    //            [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    //            FROM [Production].[Product] AS [Extent1]
    //            WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    //        UNION ALL
    //            SELECT 
    //            [Extent2].[ProductID] AS [ProductID], 
    //            [Extent2].[Name] AS [Name], 
    //            [Extent2].[ListPrice] AS [ListPrice], 
    //            [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID]
    //            FROM [Production].[Product] AS [Extent2]
    //            WHERE 1 = [Extent2].[ProductSubcategoryID]) AS [UnionAll1]
    //    )  AS [Distinct1]
#else
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 100.0

    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // [product0].[ProductSubcategoryID] = 1
#endif
}

internal static void UnionPrimitive(AdventureWorks adventureWorks)
{
    var first = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var second = adventureWorks.Products
        .Where(product =&amp;gt; product.ProductSubcategoryID == 1)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var union = first.Union(second); // Define query.
    union.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [Distinct1].[C1] AS [C1], 
    //    [Distinct1].[C2] AS [C2], 
    //    [Distinct1].[C3] AS [C3]
    //    FROM ( SELECT DISTINCT 
    //        [UnionAll1].[C1] AS [C1], 
    //        [UnionAll1].[Name] AS [C2], 
    //        [UnionAll1].[ListPrice] AS [C3]
    //        FROM  (SELECT 
    //            1 AS [C1], 
    //            [Extent1].[Name] AS [Name], 
    //            [Extent1].[ListPrice] AS [ListPrice]
    //            FROM [Production].[Product] AS [Extent1]
    //            WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    //        UNION ALL
    //            SELECT 
    //            1 AS [C1], 
    //            [Extent2].[Name] AS [Name], 
    //            [Extent2].[ListPrice] AS [ListPrice]
    //            FROM [Production].[Product] AS [Extent2]
    //            WHERE 1 = [Extent2].[ProductSubcategoryID]) AS [UnionAll1]
    //    )  AS [Distinct1]
#else
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 100.0

    // SELECT [product0].[Name], [product0].[ListPrice]
    // FROM [Production].[Product] AS [product0]
    // WHERE [product0].[ProductSubcategoryID] = 1
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF Core executes Intersect and Except locally as well.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF translates Intersect to INTERSECT operator, and translates Except to EXCEPT operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IntersectEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; first = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100);
    IQueryable&amp;lt;Product&amp;gt; second = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt; 2000);
    IQueryable&amp;lt;Product&amp;gt; intersect = first.Intersect(second); // Define query.
    intersect.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [Intersect1].[ProductID] AS [C1], 
    //    [Intersect1].[Name] AS [C2], 
    //    [Intersect1].[ListPrice] AS [C3]
    //    FROM  (SELECT 
    //        [Extent1].[ProductID] AS [ProductID], 
    //        [Extent1].[Name] AS [Name], 
    //        [Extent1].[ListPrice] AS [ListPrice], 
    //        [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    //        FROM [Production].[Product] AS [Extent1]
    //        WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    //    INTERSECT
    //        SELECT 
    //        [Extent2].[ProductID] AS [ProductID], 
    //        [Extent2].[Name] AS [Name], 
    //        [Extent2].[ListPrice] AS [ListPrice], 
    //        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID]
    //        FROM [Production].[Product] AS [Extent2]
    //        WHERE [Extent2].[ListPrice] &amp;lt; cast(2000 as decimal(18))) AS [Intersect1]
#else
    // SELECT [product0].[ProductID], [product0].[ListPrice], [product0].[Name], [product0].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product0]
    // WHERE [product0].[ListPrice] &amp;lt; 2000.0

    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 100.0
#endif
}

internal static void ExceptPrimitive(AdventureWorks adventureWorks)
{
    var first = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var second = adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var except = first.Except(second); // Define query.
    except.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //    [Except1].[C1] AS [C1], 
    //    [Except1].[Name] AS [C2], 
    //    [Except1].[ListPrice] AS [C3]
    //    FROM  (SELECT 
    //        1 AS [C1], 
    //        [Extent1].[Name] AS [Name], 
    //        [Extent1].[ListPrice] AS [ListPrice]
    //        FROM [Production].[Product] AS [Extent1]
    //        WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    //    EXCEPT
    //        SELECT 
    //        1 AS [C1], 
    //        [Extent2].[Name] AS [Name], 
    //        [Extent2].[ListPrice] AS [ListPrice]
    //        FROM [Production].[Product] AS [Extent2]
    //        WHERE [Extent2].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AS [Except1]
#else
    // SELECT [product0].[Name], [product0].[ListPrice]
    // FROM [Production].[Product] AS [product0]
    // WHERE [product0].[ListPrice] &amp;gt; 2000.0

    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 100.0
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Skip is translate to OFFSET filter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Skip(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; names = source
        .Select(product =&amp;gt; product.Name)
        .Skip(10); // Define query.
    names.WriteLines(); // Execute query.
    // exec sp_executesql N&apos;SELECT [product].[Name]
    // FROM [Production].[Product] AS [product]
    // ORDER BY (SELECT 1)
    // OFFSET @__p_0 ROWS&apos;,N&apos;@__p_0 int&apos;,@__p_0=10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SQL, OFFSET is considered to be a part of the ORDER BY clause, so here EF Core generates ORDERBY (SELECT 1) clause.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not automatically generate ORDER BY clause, and the above query throws NotSupportedException: The method &apos;Skip&apos; is only supported for sorted input in LINQ to Entities. The method &apos;OrderBy&apos; must be called before the method &apos;Skip&apos;. The following is the equivalent query works in both EF Core and EF:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndSkip(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; names = source
        .Select(product =&amp;gt; product.Name)
        .OrderBy(product =&amp;gt; 1)
        .Skip(10); // Define query.
    names.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;When Take is called without Skip, it is translate to TOP filter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Take(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .Take(10)
        .Select(product =&amp;gt; product.Name); // Define query.
    products.WriteLines(); // Execute query.
    // exec sp_executesql N&apos;SELECT [t].[Name]
    // FROM (
    //    SELECT TOP(@__p_0) [p0].*
    //    FROM [Production].[Product] AS [p0]
    // ) AS [t]&apos;,N&apos;@__p_0 int&apos;,@__p_0=10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Take is called with Skip, they are translated to FETCH and OFFSET filters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SkipAndTake(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .OrderBy(product =&amp;gt; product.Name)
        .Skip(20)
        .Take(10)
        .Select(product =&amp;gt; product.Name); // Define query.
    products.WriteLines(); // Execute query.
    // exec sp_executesql N&apos;SELECT [t].[Name]
    // FROM (
    //    SELECT [product0].*
    //    FROM [Production].[Product] AS [product0]
    //    ORDER BY [product0].[Name]
    //    OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
    // ) AS [t]&apos;,N&apos;@__p_0 int,@__p_1 int&apos;,@__p_0=20,@__p_1=10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The above OrderBy is required for Skip and Take only in EF.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;OrderBy/OrderByDescending are translated to ORDER BY clause with without/with DESC, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderBy(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ListPrice]
}

internal static void OrderByDescending(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source
        .OrderByDescending(product =&amp;gt; product.ListPrice)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ListPrice] DESC
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To sort with multiple keys, call OrderBy/OrderByDescending and ThenBy/ThenByDescending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndThenBy(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .ThenBy(product =&amp;gt; product.Name)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ListPrice], [product].[Name]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF Core, when the key selector returns anonymous type to sort by multiple keys, the sorting is executed locally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByMultipleKeys(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; new { ListPrice = product.ListPrice, Name = product.Name })
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // ORDER BY (SELECT 1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, similar to GroupBy/Join/GroupJoin, the ordering query methods’ key selector returning anonymous type is properly translated. The above query is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice]
    FROM ( SELECT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [Project1]
    ORDER BY [Project1].[ListPrice] ASC, [Project1].[Name] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Multiple OrderBy/OrderByDescending calls are translated to SQL reversely. The following example sort all products by list price, then sort all products again by subcategory, which is equivalent to sort all products by subcategory first, then sort products in the same subcategory by list price:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndOrderBy(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .OrderBy(product =&amp;gt; product.ProductSubcategoryID)
        .Select(product =&amp;gt; new
        {
            Name = product.Name,
            ListPrice = product.ListPrice,
            Subcategory = product.ProductSubcategoryID
        }); // Define query.
    products.WriteLines(); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // ORDER BY [product].[ProductSubcategoryID], [product].[ListPrice]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In the above example, EF only translates the last OrderBy call, and ignore the others.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Cast can work with entity type. The following example casts base entity to derived entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;
    IQueryable&amp;lt;TransactionHistory&amp;gt; transactions = source
        .Where(product =&amp;gt; product.ActualCost &amp;gt; 500)
        .Cast&amp;lt;SalesTransactionHistory&amp;gt;(); // Define query.
    transactions.WriteLines(transaction =&amp;gt;
        $&quot;{transaction.GetType().Name}: {transaction.TransactionDate}&quot;); // Execute query.
    // SELECT [product].[TransactionID], [product].[ActualCost], [product].[ProductID], [product].[Quantity], [product].[TransactionDate], [product].[TransactionType]
    // FROM [Production].[TransactionHistory] AS [product]
    // WHERE [product].[TransactionType] IN (N&apos;W&apos;, N&apos;S&apos;, N&apos;P&apos;) AND ([product].[ActualCost] &amp;gt; 500.0)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core does not support Cast for primitive type.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not support casting entity type. The above query throws NotSupportedException: Unable to cast the type &apos;TransactionHistory&apos; to type &apos;SalesTransactionHistory&apos;. LINQ to Entities only supports casting EDM primitive or enumeration types. EF supports casting primitive type. The following example casts decimal to string, which is translated to CAST function call, casting money to (nvarchar(MAX)):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastPrimitive(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; listPrices = source
        .Select(product =&amp;gt; product.ListPrice)
        .Cast&amp;lt;string&amp;gt;(); // Define query.
    listPrices.WriteLines(); // Execute query.
#if EF
    // SELECT 
    //     CAST( [Extent1].[ListPrice] AS nvarchar(max)) AS [C1]
    //    FROM [Production].[Product] AS [Extent1]
#else
    // InvalidOperationException: No coercion operator is defined between types &apos;System.Decimal&apos; and &apos;System.String&apos;.
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Queryable has a new query method, AsQueryable, which accepts IEnumerable&amp;lt;T&amp;gt; and returns IQueryable&amp;lt;T&amp;gt;. Remember Enumerable.AsEnumerable can convert more derived sequence (like List&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt;, etc.) to IEnumerable&amp;lt;T&amp;gt;. So the Queryable.AsQueryable/Eumerable.AsEnumerable methods look familiar to the ParallelEnumerable.AsParallel/ParallelEnumerable.AsSequential methods, which convert between sequential and parallel local queries at any point. However, AsQueryable/AsEnumerable usually do not convert freely between local and remote queries. The following is the implementation of AsEnumerable and AsQueryable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; source;
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TElement&amp;gt; AsQueryable&amp;lt;TElement&amp;gt;(this IEnumerable&amp;lt;TElement&amp;gt; source) =&amp;gt;
            source as IQueryable&amp;lt;TElement&amp;gt; ?? new EnumerableQuery&amp;lt;TElement&amp;gt;(source);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsQueryable accepts an IEnumerable&amp;lt;T&amp;gt; source. If the source is indeed an IQueryable&amp;lt;T&amp;gt; source, then do nothing and just return it; if not, wrap the source into an System.Linq.EnumerableQuery&amp;lt;T&amp;gt; instance, and return it. EnumerableQuery&amp;lt;T&amp;gt; is a special implementation of IQueryable&amp;lt;T&amp;gt;. If an IQueryable&amp;lt;T&amp;gt; query is an EnumerableQuery&amp;lt;T&amp;gt; instance, when this query is executed, it internally calls System.Linq.EnumerableRewriter to translate itself to local query, then execute the translated query locally. For example, AdventureWorks.Products return IQueryable&amp;lt;Product&amp;gt;, which is actually a DbSet&amp;lt;T&amp;gt; instance, so calling AsQueryable with AdventureWorks.Products does nothing and returns the DbSet&amp;lt;Product&amp;gt; instance itself, which can have its following query method calls to be translated to SQL by EF Core. In contrast, calling AsQueryable with a T[] array returns an EnumerableQuery&amp;lt;T&amp;gt; wrapper, which is a local mocking of remote query and can have its following query methods to be translated to local queries, As a result, AsEnumerable can always convert a remote LINQ to Entities query to local LINQ to Objects query, but AsQueryable cannot always convert arbitrary local LINQ to Objects query to a remote LINQ to Entities query (and logically, an arbitrary local .NET data source cannot be converted to a remote data source like SQL database). For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsEnumerableAsQueryable(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var remoteAndLocal = source // DbSet&amp;lt;T&amp;gt;.
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return EntityQueryable&amp;lt;T&amp;gt;.
        .AsEnumerable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 0) // Enumerable.Where. Return a generator wrapping the EntityQueryable&amp;lt;T&amp;gt; source.
        .AsQueryable() // Return an EnumerableQuery&amp;lt;T&amp;gt; instance wrapping the source generator.
        .OrderBy(product =&amp;gt; product.Name); // Queryable.OrderBy. Return EnumerableQuery&amp;lt;T&amp;gt;.
    remoteAndLocal.WriteLines();
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]

    var remote = source // DbSet&amp;lt;T&amp;gt;.
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return EntityQueryable&amp;lt;T&amp;gt;.
        .AsEnumerable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.
        .AsQueryable() // Do nothing. Directly return the EntityQueryable&amp;lt;T&amp;gt; source.
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 0) // Still LINQ to Entities. Return EntityQueryable&amp;lt;T&amp;gt;.
        .OrderBy(product =&amp;gt; product.Name); // Still LINQ to Entities. Return EntityQueryable&amp;lt;T&amp;gt;.
    remote.WriteLines();
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 0.0
    // ORDER BY [product].[Name]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the first query, the LINQ to Entities source is chained with Select, then AsEnumerable returns IEnumerable&amp;lt;T&amp;gt;, so the following Where is Enumerable.Where, and it returns a generator. Then AsQueryable detects if the generator is IQueryable&amp;lt;T&amp;gt;. Since the generator is not IQueryable&amp;lt;T&amp;gt;, AsQueryable returns a EnumerableQuery&amp;lt;T&amp;gt; wrapper, which can have the following OrderBy translated to local query. So in this entire query chaining, only Select, which is before AsEnumerable, can be translated to SQL and executed remotely, all the other query methods are executed locally.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The source is a DbSet&amp;lt;T&amp;gt; instance, which implements IQueryable&amp;lt;T&amp;gt; and represents the LINQ to Entities data source - rows in remote SQL database table.&lt;/li&gt;
&lt;li&gt;Queryable.Select is called on DbSet&amp;lt;T&amp;gt; source, in this case it returns a Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable&amp;lt;T&amp;gt; instance in EF Core (System.Data.Entity.DbQuery&amp;lt;T&amp;gt; instance in EF), which implements IQueryable&amp;lt;T&amp;gt; and represents LINQ to Entities query.&lt;/li&gt;
&lt;li&gt;Enumerable.AsEnumerable does nothing and directly returns its source, the EntityQueryable&amp;lt;T&amp;gt; (DbQuery&amp;lt;T&amp;gt; for EF) instance&lt;/li&gt;
&lt;li&gt;Enumerable.Where is called, since AsEnumerable returns IEnumerable&amp;lt;T&amp;gt; type. Where returns a generator wrapping its source, the EntityQueryable&amp;lt;T&amp;gt; (DbQuery&amp;lt;T&amp;gt; for EF) instance.&lt;/li&gt;
&lt;li&gt;Queryable.AsQueryable is called. Its source, the generator from Where, implements IEnumerable&amp;lt;T&amp;gt;, not IQueryable&amp;lt;T&amp;gt;, so AsQueryable return an EnumerableQuery&amp;lt;T&amp;gt; instance wrapping the generator. As fore mentioned, EnumerableQuery&amp;lt;T&amp;gt; has nothing to do with database.&lt;/li&gt;
&lt;li&gt;Queryable.OrderBy is called with EnumerableQuery&amp;lt;T&amp;gt; instance, in this case it returns another EnumerableQuery&amp;lt;T&amp;gt; instance, which has nothing to do with database either.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the first query is a hybrid query. When it is executed, only Select is remote LINQ to Entities query and is translated to SQL. After AsEnumerable, Where goes local, then AsQueryable cannot convert back to remote LINQ to Entities query anymore. So, Where and OrderBy are both local queries, and not translated to SQL.&lt;/p&gt;
&lt;p&gt;The second query is a special case, where AsEnumerable is chained with AsQueryable right away. In this case, AsEnumerable and AsQueryable both do nothing at all. The following Where and OrderBy are both LINQ to Entities queries, and translated to SQL along with Select.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, AsEnumerable can be useful for special case. As fore mentioned, in EF, Select does not support entity type. With AsEnumerable, this can be done with LINQ to Objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectLocalEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    IEnumerable&amp;lt;Product&amp;gt; products = source
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 1_000) // LINQ to Entities.
        .AsEnumerable() // Do nothing.
        .Select(product =&amp;gt; new Product()
        {
            ProductID = product.ProductID,
            Name = product.Name
        }); // LINQ to Objects: Enumerable.Select&amp;gt;. Return a generator.
    products.WriteLines(product =&amp;gt; $&quot;{product.ProductID}: {product.Name}&quot;); // Execute query.
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 1000.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Value query&lt;/h2&gt;
&lt;p&gt;Query methods in this category accepts an IQueryable&amp;lt;T&amp;gt; source and returns a single value. When they are called at the end of a LINQ to Entities query, they executes the query immediately.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, value queries can be used in the subqueries of the above sequence queries. For example, as demonstrated above, the aggregation subquery of GroupBy flattens hierarchical data, which is translated to SQL aggregation function with GROUP BY.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;First and FirstOrDefault execute the LINQ to Entities queries immediately. They are translated to TOP(1) filter in the SELECT clause. If a predicate is provided, the predicate is translated to WHERE clause. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void First(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    string first = source
        .Select(product =&amp;gt; product.Name)
        .First() // Execute query.
        .WriteLine();
    // SELECT TOP(1) [product].[Name]
    // FROM [Production].[Product] AS [product]
}

internal static void FirstOrDefault(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var firstOrDefault = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .FirstOrDefault(product =&amp;gt; product.ListPrice &amp;gt; 5000); // Execute query.
    firstOrDefault?.Name.WriteLine();
    // SELECT TOP(1) [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 5000.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in LINQ to Objects, Single and SingleOrDefault are more strict. They are translated to TOP(2) filter, so that, if there are 0 or more than 1 results, InvalidOperationException is thrown. Similar to First and FirstOrDefault, if a predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Single(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var single = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .Single(product =&amp;gt; product.ListPrice &amp;lt; 50); // Execute query.
    $&quot;{single.Name}: {single.ListPrice}&quot;.WriteLine();
    // SELECT TOP(2) [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;lt; 50.0
}

internal static void SingleOrDefault(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var singleOrDefault = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .SingleOrDefault(product =&amp;gt; product.ListPrice &amp;lt; 1); // Execute query.
    singleOrDefault?.Name.WriteLine();
    // SELECT TOP(2) [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;lt; 1.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core supports Last and LastOrDefault, locally. Again, if a predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Last(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    Product last = source.Last(); // Execute query.
    // SELECT [p].[ProductID], [p].[ListPrice], [p].[Name], [p].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [p]
    $&quot;{last.Name}: {last.ListPrice}&quot;.WriteLine();
}

internal static void LastOrDefault(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    var lastOrDefault = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .LastOrDefault(product =&amp;gt; product.ListPrice &amp;lt;= 0); // Execute query.
    // SELECT [product].[Name], [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;lt;= 0.0
    (lastOrDefault == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above examples can read many results from remote database to locally, and try to query the last result locally, which can be a performance issue.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not support Last or LastOrDefault, and the above queries throw NotSupportedException.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Count/LongCount are translated to SQL aggregate functions COUNT/COUNT_BIG. if a is provided, it is translated to WHERE clause. The following examples query the System.Int32 count of categories, and the System.Int64 count of the products with list price greater than 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Count(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories;
    int count = source.Count().WriteLine(); // Execute query.
    // SELECT COUNT(*)
    // FROM [Production].[ProductCategory] AS [p]
}

internal static void LongCount(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    long longCount = source.LongCount(product =&amp;gt; product.ListPrice &amp;gt; 0).WriteLine(); // Execute query.
    // SELECT COUNT_BIG(*)
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] &amp;gt; 0.0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max/Min/Sum are translated to MAX/MIN/SUM functions. The following examples query the latest ModifiedDate of photos, the lowest list price of products, and the total cost of transactions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Max(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductPhoto&amp;gt; source = adventureWorks.ProductPhotos;
    DateTime max = source.Select(photo =&amp;gt; photo.ModifiedDate).Max().WriteLine(); // Execute query.
    // SELECT MAX([photo].[ModifiedDate])
    // FROM [Production].[ProductPhoto] AS [photo]
}

internal static void Min(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    decimal min = source.Min(product =&amp;gt; product.ListPrice).WriteLine(); // Execute query.
    // SELECT MIN([product].[ListPrice])
    // FROM [Production].[Product] AS [product]
}

internal static void Sum(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;TransactionHistory&amp;gt; source = adventureWorks.Transactions;
    decimal sum = source.Sum(transaction =&amp;gt; transaction.ActualCost).WriteLine(); // Execute query.
    // SELECT SUM([transaction].[ActualCost])
    // FROM [Production].[TransactionHistory] AS [transaction]
    // WHERE ([transaction].[TransactionType] = N&apos;W&apos;) OR (([transaction].[TransactionType] = N&apos;S&apos;) OR ([transaction].[TransactionType] = N&apos;P&apos;))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF Core support Average locally.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Average(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    decimal average = source.Select(product =&amp;gt; product.ListPrice).Average().WriteLine(); // Execute query.
    // SELECT [product].[ListPrice]
    // FROM [Production].[Product] AS [product]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF translates Average to AVG function. In EF, the above query is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        AVG([Extent1].[ListPrice]) AS [A1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;EF Core supports Contains for entity type, locally.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ContainsEntity(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    Product single = source.Single(product =&amp;gt; product.ListPrice == 20.24M); // Execute query.
    // SELECT TOP(2) [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ListPrice] = 20.24
    bool contains = source
        .Where(product =&amp;gt; product.ProductSubcategoryID == 7)
        .Contains(single).WriteLine(); // Execute query.
    // SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID]
    // FROM [Production].[Product] AS [product]
    // WHERE [product].[ProductSubcategoryID] = 7
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not support Contains for entity type. The above query throws NotSupportedException: Unable to create a constant value of type &apos;Product&apos;. Only primitive types or enumeration types are supported in this context.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF/Core both support Contains for primitive types. In this case, Contains is translated to EXISTS predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ContainsPrimitive(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    bool contains = source
        .Select(product =&amp;gt; product.ListPrice).Contains(100)
        .WriteLine(); // Execute query.
    // SELECT CASE
    //    WHEN EXISTS (
    //        SELECT 1
    //        FROM [Production].[Product] AS [product]
    //        WHERE [product].[ListPrice] = 100.0)
    //    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    // END
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Any is also translated to EXISTS. If predicate is provided, it is translated to WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Any(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    bool any = source.Any().WriteLine(); // Execute query.
    // SELECT CASE
    //    WHEN EXISTS (
    //        SELECT 1
    //        FROM [Production].[Product] AS [p])
    //    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    // END
}

internal static void AnyWithPredicate(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    bool any = source.Any(product =&amp;gt; product.ListPrice &amp;gt; 10).WriteLine(); // Execute query.
    // SELECT CASE
    //    WHEN EXISTS (
    //        SELECT 1
    //        FROM [Production].[Product] AS [product]
    //        WHERE [product].[ListPrice] &amp;gt; 10.0)
    //    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    // END
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All is translated to NOT EXISTS, with the predicate translated to reverted condition in WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AllWithPredicate(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products;
    bool all = source.All(product =&amp;gt; product.ListPrice &amp;gt; 10).WriteLine(); // Execute query.
    // SELECT CASE
    //    WHEN NOT EXISTS (
    //        SELECT 1
    //        FROM [Production].[Product] AS [product]
    //        WHERE [product].[ListPrice] &amp;lt;= 10.0)
    //    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    // END
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (3) Logging and Tracing Queries</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries-7/</guid><description>EF version of this i</description><pubDate>Wed, 13 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Latest EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-3-logging&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-3-logging&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;EF version of this i&lt;/p&gt;
&lt;p&gt;As fore mentioned, LINQ to Entities queries are translated to database queries. To understand how EF/Core work with databases, it is important to uncover the actual underlying operations to the SQL database, which can be traced or logged in C# application side and in SQL database.&lt;/p&gt;
&lt;h2&gt;Application side logging&lt;/h2&gt;
&lt;p&gt;EF Core follows the ASP.NET Core logging infrastructure. To log EF Core operations, a logger (implementing Microsoft.Extensions.Logging.ILogger) and a logger provider (implementing Microsoft.Extensions.Logging.ILoggerProvider) can be defined. The following is a simple example to simply trace everything:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TraceLogger : ILogger
{
    private readonly string categoryName;

    public TraceLogger(string categoryName) =&amp;gt; this.categoryName = categoryName;

    public bool IsEnabled(LogLevel logLevel) =&amp;gt; true;

    public void Log&amp;lt;TState&amp;gt;(
        LogLevel logLevel,
        EventId eventId,
        TState state,
        Exception exception,
        Func&amp;lt;TState, Exception, string&amp;gt; formatter)
    {
        Trace.WriteLine($&quot;{DateTime.Now.ToString(&quot;o&quot;)} {logLevel} {eventId.Id} {this.categoryName}&quot;);
        Trace.WriteLine(formatter(state, exception));
    }

    public IDisposable BeginScope&amp;lt;TState&amp;gt;(TState state) =&amp;gt; null;
}

public class TraceLoggerProvider : ILoggerProvider
{
    public ILogger CreateLogger(string categoryName) =&amp;gt; new TraceLogger(categoryName);

    public void Dispose() { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the logger provider can be hooked up with EF Core:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        LoggerFactory loggerFactory = new LoggerFactory();
        loggerFactory.AddProvider(new TraceLoggerProvider());
        optionsBuilder.UseLoggerFactory(loggerFactory);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is a simple example of LINQ to Entities query. It pulls all ProductCategory entities from AdventureWorks.ProductCategories data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Tracing
{
    internal static void TraceLogger()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
            source.ForEach(); // Execute query.
        }
        // 2017-01-11T22:15:43.4625876-08:00 Debug 2 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
        // Compiling query model: 
        // &apos;from ProductCategory &amp;lt;generated&amp;gt;_0 in DbSet&amp;lt;ProductCategory&amp;gt;
        // select &amp;lt;generated&amp;gt;_0&apos;

        // 2017-01-11T22:15:43.4932882-08:00 Debug 3 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
        // Optimized query model: 
        // &apos;from ProductCategory &amp;lt;generated&amp;gt;_0 in DbSet&amp;lt;ProductCategory&amp;gt;
        // select &amp;lt;generated&amp;gt;_0&apos;

        // 2017-01-11T22:15:43.6179834-08:00 Debug 5 Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory
        // TRACKED: True
        // (QueryContext queryContext) =&amp;gt; IEnumerable&amp;lt;ProductCategory&amp;gt; _ShapedQuery(
        //    queryContext: queryContext, 
        //    shaperCommandContext: SelectExpression: 
        //        SELECT [p].[ProductCategoryID], [p].[Name]
        //        FROM [Production].[ProductCategory] AS [p]
        //    , 
        //    shaper: UnbufferedEntityShaper&amp;lt;ProductCategory&amp;gt;
        // )

        // 2017-01-11T22:15:43.7272876-08:00 Debug 3 Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerConnection
        // Opening connection to database &apos;AdventureWorks&apos; on server &apos;tcp:dixin.database.windows.net,1433&apos;.

        // 2017-01-11T22:15:44.1024201-08:00 Information 1 Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory
        // Executed DbCommand (66ms) [Parameters=[], CommandType=&apos;Text&apos;, CommandTimeout=&apos;30&apos;]
        // SELECT [p].[ProductCategoryID], [p].[Name]
        // FROM [Production].[ProductCategory] AS [p]

        // 2017-01-11T22:15:44.1505353-08:00 Debug 4 Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerConnection
        // Closing connection to database &apos;AdventureWorks&apos; on server &apos;tcp:dixin.database.windows.net,1433&apos;.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The logs uncovers that a SELECT statement is executed in database to query all categories. The logs also uncovers how exactly EF Core execute the operation – it compiles LINQ to Entities query and generates SQL, then opens a connection to SQL database, execute the generated SQL in database, and close the connection. This mechanism is discussed in the query translation part.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF has different logging APIs. It provides 3 options: LINQ to Entities query’s ToString method, database façade’s Log property, and IDbInterceptor.&lt;/p&gt;
&lt;p&gt;In EF, the easiest way is to call the query’s ToString method. In EF, LINQ to Entities query represented by IQueryable&amp;lt;T&amp;gt; is actually implemented with System.Data.Entity.Infrastructure.DbQuery&amp;lt;T&amp;gt;. The fore mentioned DbSet&amp;lt;T&amp;gt; type representing table is derived from DbQuery&amp;lt;T&amp;gt; too. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Tracing
{
    internal static void DbQueryToString()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
            source.ToString().WriteLine();
            // SELECT 
            //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
            //    [Extent1].[Name] AS [Name]
            //    FROM [Production].[ProductCategory] AS [Extent1]
            source.ForEach(); // Execute query.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The DbContext type has a Database property to expose a System.Data.Entity.Database instance, where a log function of type string –&amp;gt; void can be specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class DbContext : IDisposable, IObjectContextAdapter
    {
        public Database Database { get; }

        // Other members.
    }

    public class Database
    {
        public Action&amp;lt;string&amp;gt; Log { get; set; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The logger function is called with message for all database operations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DatabaseLog()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.Database.Log = log =&amp;gt; Trace.Write(log);
        IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
        source.ForEach(); // Execute query.
    }
    // Opened connection at 5/21/2016 12:33:34 AM -07:00
    // SELECT 
    //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[ProductCategory] AS [Extent1]
    // -- Executing at 5/21/2016 12:31:58 AM -07:00
    // -- Completed in 11 ms with result: SqlDataReader4
    // Closed connection at 5/21/2016 12:33:35 AM -07:00
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF also introduces interceptors for lower level logging control. Under System.Data.Entity.Infrastructure.Interception namespace, EF defines the IDbInterceptor interfaces, which is an empty interface inherited by IDbConfigurationInterceptor, IDbCommandInterceptor, IDbConnectionInterceptor, IDbTransactionInterceptor, and IDbCommandTreeInterceptor. For example, the following is the definition of IDbCommandInterceptor, whose methods are called before and after the execution of the translated SQL queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure.Interception
{
    public interface IDbCommandInterceptor : IDbInterceptor // IDbInterceptor is an empty interface.
    {
        void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext);

        void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext);

        void ReaderExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext);

        void ReaderExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext);

        void ScalarExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext);

        void ScalarExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF provides a number of built-in interceptor implementations. For example, the DatabaseLogFormatter type under the same namespace implements IDbCommandInterceptor, IDbConnectionInterceptor and IDbTransactionInterceptor. And it has a lot of virtual members to be overridden with custom logging logic. An interceptor has to be registered with DbInterception.Add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Interceptor()
{
    DatabaseLogFormatter interceptor = new DatabaseLogFormatter(writeAction: log =&amp;gt; Trace.WriteLine(log));
    DbInterception.Add(interceptor);
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
        source.ForEach(); // Execute query.
    }
    // Opened connection at 1/11/2017 11:51:06 PM -08:00
    // SELECT 
    // [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    // [Extent1].[Name] AS [Name]
    // FROM [Production].[ProductCategory] AS [Extent1]
    // -- Executing at 1/11/2017 11:51:06 PM -08:00
    // -- Completed in 10 ms with result: SqlDataReader
    // Closed connection at 1/11/2017 11:51:06 PM -08:00
    DbInterception.Remove(interceptor);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Database side tracing with Extended Events&lt;/h2&gt;
&lt;p&gt;SQL database provides variant mechanisms to collect the information of executed operations. Extended Events is such a feature available in all cloud and on-premise SQL database editions. For Windows, SQL Server Management Studio is a rich tools to setup and views the event tracing. And this can also be done from other platform. In any SQL tool (like &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;mssql extension&lt;/a&gt; for Visual Studio Code, which works on Linux, Mac, and Windows), connect to the Azure SQL database (or SQL Server on-premise database), and execute the following SQL to create an Extended Events session called Queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EVENT SESSION [Queries] ON DATABASE -- ON SERVER for SQL Server on-premise database.
ADD EVENT sqlserver.begin_tran_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.commit_tran_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.error_reported(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.rollback_tran_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.rpc_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.sp_statement_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text)), 
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.client_app_name, sqlserver.client_connection_id, sqlserver.client_hostname, sqlserver.client_pid, sqlserver.database_name, sqlserver.request_id, sqlserver.session_id, sqlserver.sql_text))
ADD TARGET package0.ring_buffer(SET max_events_limit = (100)) -- Most recent 100 events.
WITH (STARTUP_STATE = OFF);
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It traces the transactions, SQL executions, and errors, etc. To start the session and collect events, execute the following SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER EVENT SESSION [Queries] ON DATABASE -- ON SERVER for SQL Server on-premise database.
    STATE = START;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The collected events data is stored as XML, the following query formats the XML data to a statistics table, along with an event table which has the operations requested by .NET Core (or .NET Framework) application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DECLARE @target_data XML = 
(SELECT CONVERT(XML, [targets].[target_data])
FROM sys.dm_xe_database_session_targets AS [targets] -- sys.dm_xe_session_targets for SQL Server on-premise database.
INNER JOIN sys.dm_xe_database_sessions AS [sessions] -- sys.dm_xe_sessions for SQL Server on-premise database.
    ON [sessions].[address] = [targets].[event_session_address]
WHERE [sessions].[name] = N&apos;Queries&apos;);

SELECT
    @target_data.value(&apos;(RingBufferTarget/@truncated)[1]&apos;, &apos;bigint&apos;) AS [truncated],
    @target_data.value(&apos;(RingBufferTarget/@processingTime)[1]&apos;, &apos;bigint&apos;) AS [processingTime],
    @target_data.value(&apos;(RingBufferTarget/@totalEventsProcessed)[1]&apos;, &apos;bigint&apos;) AS [totalEventsProcessed],
    @target_data.value(&apos;(RingBufferTarget/@eventCount)[1]&apos;, &apos;bigint&apos;) AS [eventCount],
    @target_data.value(&apos;(RingBufferTarget/@droppedCount)[1]&apos;, &apos;bigint&apos;) AS [droppedCount],
    @target_data.value(&apos;(RingBufferTarget/@memoryUsed)[1]&apos;, &apos;bigint&apos;) AS [memoryUsed];

SELECT
    [event].value(&apos;@timestamp[1]&apos;, &apos;datetime&apos;) AS [timestamp],
    [event].value(&apos;(action[@name=&quot;client_hostname&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [client_hostname],
    [event].value(&apos;(action[@name=&quot;client_pid&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [client_pid],
    [event].value(&apos;(action[@name=&quot;client_connection_id&quot;]/value)[1]&apos;, &apos;uniqueidentifier&apos;) AS [client_connection_id],
    [event].value(&apos;(action[@name=&quot;session_id&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [session_id],
    [event].value(&apos;(action[@name=&quot;request_id&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [request_id],
    [event].value(&apos;(action[@name=&quot;database_name&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [database_name],
    [event].value(&apos;@name[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [name],
    [event].value(&apos;(data[@name=&quot;duration&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [duration],
    [event].value(&apos;(data[@name=&quot;result&quot;]/text)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [result],
    [event].value(&apos;(data[@name=&quot;row_count&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [row_count],
    [event].value(&apos;(data[@name=&quot;cpu_time&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [cpu_time],
    [event].value(&apos;(data[@name=&quot;logical_reads&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [logical_reads],
    [event].value(&apos;(data[@name=&quot;physical_reads&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [physical_reads],
    [event].value(&apos;(data[@name=&quot;writes&quot;]/value)[1]&apos;, &apos;bigint&apos;) as [writes],
    [event].value(&apos;(action[@name=&quot;sql_text&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [sql_text],
    [event].value(&apos;(data[@name=&quot;statement&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [statement],
    [event].value(&apos;(data[@name=&quot;error_number&quot;]/value)[1]&apos;, &apos;bigint&apos;) AS [error_number],
    [event].value(&apos;(data[@name=&quot;message&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) AS [message]
FROM @target_data.nodes(&apos;//RingBufferTarget/event&apos;) AS [Rows]([event])
WHERE [event].value(&apos;(action[@name=&quot;client_app_name&quot;]/value)[1]&apos;, &apos;nvarchar(MAX)&apos;) = N&apos;Core .Net SqlClient Data Provider&apos; -- N&apos;.Net SqlClient Data Provider&apos; for .NET Framework.
ORDER BY [timestamp];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is an example of how the traced database operations look like:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_3115/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_3115/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (2) Modeling Database: Object-Relational Mapping</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping-7/</guid><description>.NET and SQL database and have 2 different data type systems. For example, .NET has System.Int64 and System.String, while SQL database has bigint and nvarchar; .NET has sequences and objects, while SQ</description><pubDate>Tue, 12 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Latest EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-3-logging&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-3-logging&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;.NET and SQL database and have 2 different data type systems. For example, .NET has System.Int64 and System.String, while SQL database has bigint and nvarchar; .NET has sequences and objects, while SQL database has tables and rows;, etc. Object-relational mapping is a popular technology to map and convert between application data objects and database relational data. In LINQ to Entities, the queries are based on Object-relational mapping.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF provides &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms178359.aspx#dbfmfcf&quot;&gt;3 options&lt;/a&gt; to build the mapping between C#/.NET and SQL database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-in/data/ff830362.aspx&quot;&gt;Model first&lt;/a&gt;: The entity data models (a .edmx diagram consists of entities, entity properties, entity associations, etc.) are first created in EF, typically by the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/cc716685.aspx&quot;&gt;ADO.NET Entity Data Model Designer&lt;/a&gt; tool in Visual Studio. Then, EF can use the models to generate database and the mapping .NET types. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb_thumb_thumb.png&quot; alt=&quot;image_thumb_thumb&quot; title=&quot;image_thumb_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj206878.aspx&quot;&gt;Database first&lt;/a&gt;: From an existing database, EF can generate the entity data models (.edmx diagram) and the mapping .NET types., typically by Entity Data Model Wizard too: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb5_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb5_thumb_thumb.png&quot; alt=&quot;image_thumb5_thumb&quot; title=&quot;image_thumb5_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Code first: The mapping .NET types are coded to enabled LINQ to Entities queries and other operations. EF generates the entity data models at runtime, so there is no .edmx diagram at design time in the code base. If the database exits, the .NET types are just mapped to the existing database; if not, EF can generate the database. &lt;a href=&quot;http://blogs.msdn.com/b/adonet/archive/2014/10/21/ef7-what-does-code-first-only-really-mean.aspx&quot;&gt;“Code first” is not an intuitive naming&lt;/a&gt;. It does not mean code is created before the database. It is just code-based modeling for &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj200620&quot;&gt;existing database&lt;/a&gt; or &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj193542&quot;&gt;new database&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Comparing to code generation from entity data models (.edmx), it is more intuitive and transparent to build code from scratch. Also, regarding EF Core does not support entity data models (.edmx) and only supports code first, this tutorial follows the code first approach.&lt;/p&gt;
&lt;h2&gt;Data types&lt;/h2&gt;
&lt;p&gt;EF/Core can map most SQL data types to .NET types:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;771&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;SQL type category&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;SQL type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;.NET type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;C# primitive&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Exact numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;bit&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Boolean&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;bool&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;tinyint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Byte&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;byte&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;smallint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Int16&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;short&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;int&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Int32&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;int&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;bigint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Int64&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;long&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;smallmoney, money, decimal, numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Decimal&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;decimal&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Approximate numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;real&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Single&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;float&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;float&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Double&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;double&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Character string&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;char, varchar, text&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;nchar, nvarchar, ntext&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Binary string&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;binary, varbinary&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;image&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;rowversion (timestamp)&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Date time&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;date&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.DateTime&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;time&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.TimeSpan&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;smalldatetime, datetime, datetime2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.DateTime&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;datetimeoffset&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.DateTimeOffset&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Spatial type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;geography&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Data.Entity.Spatial.DbGeography*&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;geometry&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Data.Entity.Spatial.DbGeometry*&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;Other&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;hierarchyid&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;No built-in mapping or support&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;xml&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;uniqueidentifier&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;System.Guid&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;151&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;260&quot;&amp;gt;sql_variant&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;264&quot;&amp;gt;No built-in mapping or support&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Currently the spatial types marked with * are only supported by EF.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Database&lt;/h2&gt;
&lt;p&gt;A SQL database is mapped to a type derived from DbContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks : DbContext { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbContext is provided as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.EntityFrameworkCore
{
    public class DbContext : IDisposable, IInfrastructure&amp;lt;IServiceProvider&amp;gt;
    {
        public DbContext(DbContextOptions options);

        public virtual ChangeTracker ChangeTracker { get; }

        public virtual DatabaseFacade Database { get; }

        public virtual void Dispose();

        public virtual int SaveChanges();

        public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;

        protected internal virtual void OnModelCreating(ModelBuilder modelBuilder);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the members of DbContext and DbContext have slightly different signatures::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class DbContext : IDisposable, IObjectContextAdapter
    {
        public DbContext(DbConnection existingConnection, bool contextOwnsConnection);

        public DbChangeTracker ChangeTracker { get; }

        public Database Database { get; }

        public void Dispose();

        public virtual int SaveChanges();

        public virtual DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class;

        protected virtual void OnModelCreating(DbModelBuilder modelBuilder);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;DbContext implements IDisposable. Generally, a database instance should be constructed and disposed for each &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt; - a collection of data operations that should succeed or fail as a unit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Dispose()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        // Unit of work.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In EF/Core, most of the object-relational mapping can be implemented declaratively, and the rest of the mapping can be implemented imperatively by overriding DbContext.OnModelCreating, which is called by EF/Core when initializing the entity models:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        MapCompositePrimaryKey(modelBuilder);
        MapManyToMany(modelBuilder);
        MapDiscriminator(modelBuilder);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above MapCompositePrimaryKey, MapManyToMany, MapDiscriminator methods are implemented soon later.&lt;/p&gt;
&lt;h3&gt;Connection resiliency and execution retry strategy&lt;/h3&gt;
&lt;p&gt;As the mapping of the database, AdventureWorks also manages the connection to the database, which can be injected from the constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public AdventureWorks(DbConnection connection = null)
        : base(new DbContextOptionsBuilder&amp;lt;AdventureWorks&amp;gt;().UseSqlServer(
            connection: connection ?? new SqlConnection(ConnectionStrings.AdventureWorks),
            sqlServerOptionsAction: options =&amp;gt; options.EnableRetryOnFailure(
                maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null)).Options) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here when database connection is not provided to the constructor, a new database connection is created with the previously defined connection string. Also, regarding the connection between application and SQL database may be interrupted (because of network, etc.), EF/Core support connection resiliency for SQL database. This is especially helpful for Azure SQL database deployed in the cloud instead of local network. In the above example, EF Core is specified to automatically retries up to 5 times with the retry interval of 30 seconds.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, the database connection can be injected through constructor too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public AdventureWorks(DbConnection connection = null) : base(
        existingConnection: connection ?? new SqlConnection(ConnectionStrings.AdventureWorks),
        contextOwnsConnection: connection == null) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The connection resiliency needs to be specified as part of the EF configuration, which must be a type derived from System.Data.Entity.DbConfiguration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class RetryConfiguration : DbConfiguration
{
    public RetryConfiguration()
    {
        this.SetExecutionStrategy(
            providerInvariantName: SqlProviderServices.ProviderInvariantName,
            getExecutionStrategy: () =&amp;gt; ExecutionStrategy.DisableExecutionStrategy
                ? new DefaultExecutionStrategy() : ExecutionStrategy.Create());
    }
}

public partial class ExecutionStrategy
{
    public static bool DisableExecutionStrategy
    {
        get =&amp;gt; (bool?)CallContext.LogicalGetData(nameof(DisableExecutionStrategy)) ?? false;
        set =&amp;gt; CallContext.LogicalSetData(nameof(DisableExecutionStrategy), value);
    }

    public static IDbExecutionStrategy Create() =&amp;gt;
        new SqlAzureExecutionStrategy(maxRetryCount: 5, maxDelay: TimeSpan.FromSeconds(30));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At runtime, EF discovers and instantiates the above RetryConfiguration type with reflection, so that RetryConfiguration constructor is called. Here ExecutionStrategy.DisableExecutionStrategy can be used to turn on/off the above default retry logic: when ExecutionStrategy.DisableExecutionStrategy is true, a System.Data.Entity.Infrastructure.DefaultExecutionStrategy instance specifies EF do not retry; when it is false, a System.Data.Entity.SqlServer.SqlAzureExecutionStrategy instance specified EF to retry up to 5 times with the retry interval of 30 seconds.&lt;/p&gt;
&lt;p&gt;Why not simply leave the retry enabled all the time? The reason is, EF connection resiliency does not directly work with custom transactions. So this switch is introduced to disable default retry logic for custom transactions, which is discussed in the transaction part.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Tables&lt;/h2&gt;
&lt;p&gt;There are tens of tables in the AdventureWorks database, but don’t panic, this tutorial only involves a few tables, and a few columns of these tables. In EF/Core, a table definition can be mapped to an entity type definition, where each column is mapped to a entity property. For example, the AdventureWorks database has a Production.ProductCategory table, which is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE SCHEMA [Production];
GO

CREATE TYPE [dbo].[Name] FROM nvarchar(50) NULL;
GO

CREATE TABLE [Production].[ProductCategory](
    [ProductCategoryID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductCategory_ProductCategoryID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [rowguid] uniqueidentifier ROWGUIDCOL NOT NULL -- Ignored in mapping.
        CONSTRAINT [DF_ProductCategory_rowguid] DEFAULT (NEWID()),
    
    [ModifiedDate] datetime NOT NULL -- Ignored in mapping.
        CONSTRAINT [DF_ProductCategory_ModifiedDate] DEFAULT (GETDATE()));
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This table definition can be mapped to a ProductCategory entity definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public const string Production = nameof(Production); // Production schema.
}

[Table(nameof(ProductCategory), Schema = AdventureWorks.Production)]
public partial class ProductCategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductCategoryID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    // Other columns are ignored.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The [Table] attribute specifies the table name and schema. [Table] can be omitted when the table name is the same as the entity name, and the table is under the default dbo schema. In the table-entity mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ProductCategoryID column of int type is mapped to a System.Int32 property with the same name. The [Key] attribute indicates it is a primary key. EF/Core requires a table to have primary key to be mapped. [DatabaseGenerated] indicates it is an identity column, with value generated by database.&lt;/li&gt;
&lt;li&gt;The Name column is of dbo.Name type. which is actually nvarchar(50), so it is mapped to Name property of type System.String. The [MaxLength] attribute indicates the max length of the string value is 50. [Required] indicates it should not be null or empty string or whitespace string.&lt;/li&gt;
&lt;li&gt;The other columns rowguid and ModifiedDate are not mapped. They are not used in this tutorial to keep the code examples simple.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At runtime, each row of Production.ProductCategory table is mapped to a ProductCategory instance.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF by default does not directly instantiate ProductCategory. It dynamically defines another proxy type derived from ProductCategory, with a name like System.Data.Entity.DynamicProxies.Product_F84B0F952ED22479EF48782695177D770E63BC4D8771C9DF78343B4D95926AE8. This proxy type is where EF injects more logic like lazy loading, so that at design time the mapping entity type can be clean and declarative.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The rows of the entire table can be mapped to objects in an IQueryable&amp;lt;T&amp;gt; data source, exposed as a property of the database type. DbSet&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt;, and is provided to represent a table data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;ProductCategory&amp;gt; ProductCategories { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Relationships&lt;/h2&gt;
&lt;p&gt;In SQL database, tables can have &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms189049.aspx&quot;&gt;foreign key relationships&lt;/a&gt;, including one-to-one, one-to-many, and many-to-many relationships.&lt;/p&gt;
&lt;h3&gt;One-to-one&lt;/h3&gt;
&lt;p&gt;The following Person.Person table and HumanResources.Employee table has a one-to-one relationship:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb4_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb4_thumb.png&quot; alt=&quot;image_thumb4&quot; title=&quot;image_thumb4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;HumanResources.Employee table’s BusinessEntityID column is a foreign key that refers to Person.Person table’s primary key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Person].[Person](
    [BusinessEntityID] int NOT NULL
        CONSTRAINT [PK_Person_BusinessEntityID] PRIMARY KEY CLUSTERED,

    [FirstName] [dbo].[Name] NOT NULL,

    [LastName] [dbo].[Name] NOT NULL

    /* Other columns. */);
GO

CREATE TABLE [HumanResources].[Employee](
    [BusinessEntityID] int NOT NULL
        CONSTRAINT [PK_Employee_BusinessEntityID] PRIMARY KEY CLUSTERED
        CONSTRAINT [FK_Employee_Person_BusinessEntityID] FOREIGN KEY
        REFERENCES [Person].[Person] ([BusinessEntityID]),
    
    [JobTitle] nvarchar(50) NOT NULL,

    [HireDate] date NOT NULL

    /* Other columns. */);
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So each row in HumanResources.Employee table refers to one row in Person.Person table (an employee must be a person). On the other hand, each row in Person.Person table can be referred by 0 or 1 row in HumanResources.Employee table (a person can be an employee, or not). This relationship can be represented by navigation property of entity type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public const string Person = nameof(Person);

    public const string HumanResources = nameof(HumanResources);

    public DbSet&amp;lt;Person&amp;gt; People { get; set; }

    public DbSet&amp;lt;Employee&amp;gt; Employees { get; set; }
}

[Table(nameof(Person), Schema = AdventureWorks.Person)]
public partial class Person
{
    [Key]
    public int BusinessEntityID { get; set; }

    [Required]
    [MaxLength(50)]
    public string FirstName { get; set; }

    [Required]
    [MaxLength(50)]
    public string LastName { get; set; }

    public virtual Employee Employee { get; set; } // Reference navigation property.
}

[Table(nameof(Employee), Schema = AdventureWorks.HumanResources)]
public partial class Employee
{
    [Key]
    [ForeignKey(nameof(Person))]
    public int BusinessEntityID { get; set; }
        
    [Required]
    [MaxLength(50)]
    public string JobTitle { get; set; }

    public DateTime HireDate { get; set; }

    public virtual Person Person { get; set; } // Reference navigation property.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The [ForeignKey] attribute indicates Employee entity’s BusinessEntityID property is the foreign key for the relationship represented by navigation property. Here Person is called the primary entity, and Employee is called the dependent entity. Their navigation properties are called reference navigation properties, because each navigation property can refer to a single entity.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For EF, the navigation property needs to be virtual to enable proxy entity to implement lazy loading. This will be discussed in the lazy loading part. EF Core does not support lazy loading, so the virtual keyword does not make difference for EF Core.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;One-to-many&lt;/h3&gt;
&lt;p&gt;The Production.ProductCategory and Production.ProductSubcategory tables have a one-to-many relationship, so are Production.ProductSubcategory and Production.Product:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb3_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb3_thumb.png&quot; alt=&quot;image_thumb3&quot; title=&quot;image_thumb3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each row in Production.ProductCategory table can refer to many rows in Production.ProductSubcategory table (category can have many subcategories), and each row in Production.ProductSubcategory table can refer to many rows in Production.Product table (ubcategory can have many products):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductSubcategory](
    [ProductSubcategoryID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductSubcategory_ProductSubcategoryID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [ProductCategoryID] int NOT NULL
        CONSTRAINT [FK_ProductSubcategory_ProductCategory_ProductCategoryID] FOREIGN KEY
        REFERENCES [Production].[ProductCategory] ([ProductCategoryID]),

    /* Other columns. */)
GO

CREATE TABLE [Production].[Product](
    [ProductID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [ListPrice] money NOT NULL,

    [ProductSubcategoryID] int NULL
        CONSTRAINT [FK_Product_ProductSubcategory_ProductSubcategoryID] FOREIGN KEY
        REFERENCES [Production].[ProductSubcategory] ([ProductSubcategoryID])
    
    /* Other columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These one-to-many relationships can be represented by navigation property of type ICollection&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductCategory
{
    public virtual ICollection&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; } // Collection navigation property.
}

[Table(nameof(ProductSubcategory), Schema = AdventureWorks.Production)]
public partial class ProductSubcategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductSubcategoryID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    public int ProductCategoryID { get; set; }

    public virtual ProductCategory ProductCategory { get; set; } // Reference navigation property.

    public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; } // Collection navigation property.
}

[Table(nameof(Product), Schema = AdventureWorks.Production)]
public partial class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    public decimal ListPrice { get; set; }

    public int? ProductSubcategoryID { get; set; }

    public virtual ProductSubcategory ProductSubcategory { get; set; } // Reference navigation property.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice Production.Product table’s ProductSubcategoryID column is nullable, so it is mapped to a System.Nullable&amp;lt;int&amp;gt; property. Here [ForeignKey] attribute is omitted, because the dependent entities’ foreign keys are different from their primary keys, and each foreign key have the same name as its primary key, so they can be automatically discovered by EF/Core.&lt;/p&gt;
&lt;h3&gt;Many-to-many&lt;/h3&gt;
&lt;p&gt;Production.Product and Production.ProductPhoto tables has many-to-many relationship.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Entity-FrameworkCore-and-LINQ-to-Entitie_2797/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is implemented by 2 one-to-many relationships with another Production.ProductProductPhoto junction table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductPhoto](
    [ProductPhotoID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductPhoto_ProductPhotoID] PRIMARY KEY CLUSTERED,

    [LargePhotoFileName] nvarchar(50) NULL,
    
    [ModifiedDate] datetime NOT NULL 
        CONSTRAINT [DF_ProductPhoto_ModifiedDate] DEFAULT (GETDATE())

    /* Other columns. */)
GO

CREATE TABLE [Production].[ProductProductPhoto](
    [ProductID] int NOT NULL
        CONSTRAINT [FK_ProductProductPhoto_Product_ProductID] FOREIGN KEY
        REFERENCES [Production].[Product] ([ProductID]),

    [ProductPhotoID] int NOT NULL
        CONSTRAINT [FK_ProductProductPhoto_ProductPhoto_ProductPhotoID] FOREIGN KEY
        REFERENCES [Production].[ProductPhoto] ([ProductPhotoID]),

    CONSTRAINT [PK_ProductProductPhoto_ProductID_ProductPhotoID] PRIMARY KEY NONCLUSTERED ([ProductID], [ProductPhotoID])
    
    /* Other columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the many-to-many relationship can be mapped to 2 one-to-many relationships with the junction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } // Collection navigation property.
}

[Table(nameof(ProductPhoto), Schema = AdventureWorks.Production)]
public partial class ProductPhoto
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductPhotoID { get; set; }

    [MaxLength(50)]
    public string LargePhotoFileName { get; set; }

    [ConcurrencyCheck]
    public DateTime ModifiedDate { get; set; }

    public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } // Collection navigation property.
}

[Table(nameof(ProductProductPhoto), Schema = AdventureWorks.Production)]
public partial class ProductProductPhoto
{
    [Key]
    [Column(Order = 0)]
    public int ProductID { get; set; }

    [Key]
    [Column(Order = 1)]
    public int ProductPhotoID { get; set; }

    public virtual Product Product { get; set; } // Reference navigation property.

    public virtual ProductPhoto ProductPhoto { get; set; } // Reference navigation property.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ProductPhoto.ModifiedDate has a [ConcurrencyCheck] attribute for concurrency conflict check, which is discussed in the concurrency part. Production.ProductProductPhoto table has a composite primary key. As a junction table, each row in the table has a unique combination of ProductID and ProductPhotoID. EF Core requires additional information for composite primary key, which can be provided as anonymous type in OnModelCreating:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    private static void MapCompositePrimaryKey(ModelBuilder modelBuilder) // Called by OnModelCreating.
    {
        modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
            .HasKey(productProductPhoto =&amp;gt; new
            {
                ProductID = productProductPhoto.ProductID,
                ProductPhotoID = productProductPhoto.ProductPhotoID
            });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;EF does not require above anonymous type to represent composite primary key, but it requires the ordering, which can be simply provided by the [Column] attribute.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF Core also requires additional information for many-to-many relationship represented by 2 one-to-many relationships, which can be provided in OnModelCreating as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    private static void MapManyToMany(ModelBuilder modelBuilder) // Called by OnModelCreating.
    {
        modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
            .HasOne(productProductPhoto =&amp;gt; productProductPhoto.Product)
            .WithMany(product =&amp;gt; product.ProductProductPhotos)
            .HasForeignKey(productProductPhoto =&amp;gt; productProductPhoto.ProductID);

        modelBuilder.Entity&amp;lt;ProductProductPhoto&amp;gt;()
            .HasOne(productProductPhoto =&amp;gt; productProductPhoto.ProductPhoto)
            .WithMany(photo =&amp;gt; photo.ProductProductPhotos)
            .HasForeignKey(productProductPhoto =&amp;gt; productProductPhoto.ProductPhotoID);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The above code in MapCompositePrimaryKey and MapManyToMany methods are not needed by EF.&lt;/p&gt;
&lt;p&gt;EF also provides another option to directly map the many-to-many relationship with API calls. With the this approach, the above ProductProductPhoto entity and one-to-many navigation properties are not needed. Just define 2 collection navigation properties, and specified the mapping in OnModelCreating:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    public virtual ICollection&amp;lt;ProductPhoto&amp;gt; ProductPhotos { get; set; }
}

public partial class ProductPhoto
{
    public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; }
}

public partial class AdventureWorks
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity&amp;lt;Product&amp;gt;()
            .HasMany(product =&amp;gt; product.ProductPhotos)
            .WithMany(photo =&amp;gt; photo.Products)
            .Map(mapping =&amp;gt; mapping
                .ToTable(nameof(ProductProductPhoto), Production)
                .MapLeftKey(nameof(Product.ProductID))
                .MapRightKey(nameof(ProductPhoto.ProductPhotoID)));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Finally, the rows of each above table can be expose as an IQueryable&amp;lt;T&amp;gt; data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;Person&amp;gt; People { get; set; }

    public DbSet&amp;lt;Employee&amp;gt; Employees { get; set; }

    public DbSet&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; }

    public DbSet&amp;lt;Product&amp;gt; Products { get; set; }

    public DbSet&amp;lt;ProductPhoto&amp;gt; ProductPhotos { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Inheritance&lt;/h2&gt;
&lt;p&gt;EF/Core also supports inheritance for entity types.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF supports 3 types of inheritance for the mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.4&quot;&gt;Table per hierarchy (TPH)&lt;/a&gt;: 1 table is mapped with each base entity type and derived entity type in the inheritance hierarchy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.5&quot;&gt;Table per type (TPT)&lt;/a&gt;: 1 table is mapped with one single entity type in the hierarchy&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.6&quot;&gt;Table per concrete type (TPC)&lt;/a&gt;: one table is mapped with one non-abstract entity type in the hierarchy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;EF Core supports table per hierarchy (TPH) inheritance, which is also the default strategy of EF. With TPH, rows in 1 table is mapped to many entities in the inheritance hierarchy, so a discriminator column is needed to identify each specific row’s mapping entity. Take the following Production.TransactionHistory table as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[TransactionHistory](
    [TransactionID] int IDENTITY(100000,1) NOT NULL
        CONSTRAINT [PK_TransactionHistory_TransactionID] PRIMARY KEY CLUSTERED,

    [ProductID] int NOT NULL
        CONSTRAINT [FK_TransactionHistory_Product_ProductID] FOREIGN KEY
        REFERENCES [Production].[Product] ([ProductID]),

    [TransactionDate] datetime NOT NULL,

    [TransactionType] nchar(1) NOT NULL
        CONSTRAINT [CK_Product_Style] 
        CHECK (UPPER([TransactionType]) = N&apos;P&apos; OR UPPER([TransactionType]) = N&apos;S&apos; OR UPPER([TransactionType]) = N&apos;W&apos;),

    [Quantity] int NOT NULL,

    [ActualCost] money NOT NULL

    /* Other columns. */);
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its TransactionType column allows value “P”, “S”, or “W” to indicate each row representing a purchase transaction, sales transaction, or work transaction. So the mapping hierarchy can be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(TransactionHistory), Schema = AdventureWorks.Production)]
public abstract class TransactionHistory
{
    [Key]
    public int TransactionID { get; set; }

    public int ProductID { get; set; }

    public DateTime TransactionDate { get; set; }

    public int Quantity { get; set; }

    public decimal ActualCost { get; set; }
}

public class PurchaseTransactionHistory : TransactionHistory { }

public class SalesTransactionHistory : TransactionHistory { }

public class WorkTransactionHistory : TransactionHistory { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the discriminator must be specified via OnModelCreating. The EF and EF Core APIs are different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum TransactionType { P, S, W }

public partial class AdventureWorks
{
    private static void MapDiscriminator(ModelBuilder modelBuilder) // Called by OnModelCreating.
    {
#if EF
        modelBuilder
            .Entity&amp;lt;TransactionHistory&amp;gt;()
            .Map&amp;lt;PurchaseTransactionHistory&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(TransactionType))
                .HasValue(nameof(TransactionType.P)))
            .Map&amp;lt;SalesTransactionHistory&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(TransactionType))
                .HasValue(nameof(TransactionType.S)))
            .Map&amp;lt;WorkTransactionHistory&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(TransactionType))
                .HasValue(nameof(TransactionType.W)));
#else
        modelBuilder.Entity&amp;lt;TransactionHistory&amp;gt;()
            .HasDiscriminator&amp;lt;string&amp;gt;(nameof(TransactionType))
            .HasValue&amp;lt;PurchaseTransactionHistory&amp;gt;(nameof(TransactionType.P))
            .HasValue&amp;lt;SalesTransactionHistory&amp;gt;(nameof(TransactionType.S))
            .HasValue&amp;lt;WorkTransactionHistory&amp;gt;(nameof(TransactionType.W));
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now these entities can all be exposed as data sources:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;TransactionHistory&amp;gt; Transactions { get; set; }

    public DbSet&amp;lt;PurchaseTransactionHistory&amp;gt; PurchaseTransactions { get; set; }

    public DbSet&amp;lt;SalesTransactionHistory&amp;gt; SalesTransactions { get; set; }

    public DbSet&amp;lt;WorkTransactionHistory&amp;gt; WorkTransactions { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Views&lt;/h2&gt;
&lt;p&gt;A view can also be mapped as if it is a table, if the view has one or more columns which can be viewed as primary key. Take the Production.vEmployee view as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE VIEW [HumanResources].[vEmployee] 
AS 
SELECT 
    e.[BusinessEntityID],
    p.[FirstName],
    p.[LastName],
    e.[JobTitle]  
    -- Other columns.
FROM [HumanResources].[Employee] e
    INNER JOIN [Person].[Person] p
    ON p.[BusinessEntityID] = e.[BusinessEntityID]
    /* Other tables. */;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The BusinessEntityID is unique and can be viewed as primary key. So it can be mapped to the following entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(vEmployee), Schema = AdventureWorks.HumanResources)]
public class vEmployee
{
    [Key]
    public int BusinessEntityID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string JobTitle { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then expose as data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;vEmployee&amp;gt; vEmployees { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Stored procedures and functions&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;EF can also mapping stored procedures and functions in SQL database, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stored procedures, with single result type, multiple result types, output parameter&lt;/li&gt;
&lt;li&gt;Table-valued functions&lt;/li&gt;
&lt;li&gt;Scalar-valued functions, composable or non-composable&lt;/li&gt;
&lt;li&gt;Aggregate functions&lt;/li&gt;
&lt;li&gt;Built-in functions&lt;/li&gt;
&lt;li&gt;Niladic functions&lt;/li&gt;
&lt;li&gt;Model defined functions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These contents are covered by a separate article: &lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions&quot;&gt;EntityFramework.Functions: Code First Functions for Entity Framework&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Entity Framework/Core and LINQ to Entities (1) Remote Query</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-1-remote-query-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-1-remote-query-7/</guid><description>The previous chapters discussed LINQ to Objects, LINQ to XML (objects), and Parallel LINQ (to Objects). All of these LINQ technologies query local in-memory objects managed by .NET. This chapter discu</description><pubDate>Mon, 11 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Latest EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-1-remote-query&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-1-remote-query&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-1-remote-query&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-1-remote-query&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;Entity Framework and Entity Framework Core&lt;/h2&gt;
&lt;p&gt;The previous chapters discussed LINQ to Objects, LINQ to XML (objects), and Parallel LINQ (to Objects). All of these LINQ technologies query local in-memory objects managed by .NET. This chapter discusses a different kind of LINQ technology, LINQ to Entities, which queries relational data managed by databases. LINQ to Entities was provided by Entity Framework (EF), a Microsoft library released since .NET Framework 3.5 Service Pack 1. In 2016, Microsoft also released the cross platform version, Entity Framework Core (EF Core), along with with .NET Core 1.0. EF and EF Core both implement a provider model, so that LINQ to Entitiescan be implemented by different providers to work with different kinds of databases, including SQL Server (on-premise database) and Azure SQL Database (cloud database, aka SQL Azure), &lt;a href=&quot;https://www.devart.com/dotconnect/db2/&quot;&gt;DB2&lt;/a&gt;, &lt;a href=&quot;https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html&quot;&gt;MySQL&lt;/a&gt;, &lt;a href=&quot;http://download.oracle.com/oll/obe/EntityFrameworkOBE/EntityFrameworkOBE.htm&quot;&gt;Oracle&lt;/a&gt;, &lt;a href=&quot;https://www.devart.com/dotconnect/postgresql/articles/tutorial_ef.html&quot;&gt;PostgreSQL&lt;/a&gt;, &lt;a href=&quot;https://www.devart.com/dotconnect/sqlite/&quot;&gt;SQLLite&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;EF is a library for .NET Framework so it only works on Windows. EF Core is provided for both .NET Framework and .NET Core, so it works cross-platform. This tutorial focuses on cross platform EF Core. It also covers EF, regarding after many years EF has been stabilized, with many rich tools and solutions available. For the scenarios where EF Core and EF work differently, the conditional compilation symbol EF is used to identify EF code.&lt;/p&gt;
&lt;p&gt;EF Core APIs are under Microsoft.EntityFrameworkCore namespace, and EF APIs are under System.Data.Entity namespace. Some APIs share the same name, and some are slightly different:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;866&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;EF Core&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;EF&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.DbContext&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.DbContext&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.DbSet&amp;lt;TEntity&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.DbSet&amp;lt;TEntity&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.ModelBuilder&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.DbModelBuilder&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.Database&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.Infrastructure.DbChangeTracker*&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.Infrastructure.DbEntityEntry*&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.ChangeTracking.PropertyEntry&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.Infrastructure.DbPropertyEntry*&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.DbContextTransaction*&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;426&quot;&amp;gt;Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;438&quot;&amp;gt;System.Data.Entity.Infrastructure.DbUpdateConcurrencyException&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;This tutorial follows the EF Core API names, and assumes the following aliases are defined for EF types marked with *:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#if EF
using ModelBuilder = System.Data.Entity.DbModelBuilder;
using DatabaseFacade = System.Data.Entity.Database;
using ChangeTracker = System.Data.Entity.Infrastructure.DbChangeTracker;
using EntityEntry = System.Data.Entity.Infrastructure.DbEntityEntry;
using PropertyEntry = System.Data.Entity.Infrastructure.DbPropertyEntry;
using IDbContextTransaction = System.Data.Entity.DbContextTransaction;
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SQL database&lt;/h2&gt;
&lt;p&gt;To demonstrate LINQ to Entities queries and other database operations, this tutorial uses the classic sample SQL database AdventureWorks provided by Microsoft as the data source, because this sample database has a very intuitive structure, it also works with Azure SQL Database and all SQL Server &lt;a href=&quot;http://download.microsoft.com/download/D/7/D/D7D64E12-C8E5-4A8C-A104-C945C188FA99/SQL_Server_2014_Datasheet.pdf&quot;&gt;editions&lt;/a&gt;. The full sample database provided by Microsoft is relatively large, so a trimmed version is provided for this tutorial in the code samples repo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AdventureWorks.bacpac: about 3M, for Azure SQL Database&lt;/li&gt;
&lt;li&gt;AdventureWorks_Data.mdf and AdventureWorks_Log.ldf: about 30M, for SQL Server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Microsoft SQL database is available in the cloud, and on premise (Windows and Linux). There are many free options to setup, just follow any one of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Azure SQL Database in the cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Sign up &lt;a href=&quot;https://azure.com/free&quot;&gt;Azure free trial&lt;/a&gt; program, or sign up &lt;a href=&quot;https://www.visualstudio.com/dev-essentials/&quot;&gt;Visual Studio Dev Essentials&lt;/a&gt; program, to get free Azure account and free credits.&lt;/li&gt;
&lt;li&gt;Sign in to Azure portal, create a storage account, then create a container, and upload the AdventureWorks.bacpac file into the container.&lt;/li&gt;
&lt;li&gt;In Azure portal, create a SQL Database server, then add local IP address to the server’s firewall settings to enable access.&lt;/li&gt;
&lt;li&gt;In Azure portal, import the uploaded AdventureWorks.bacpac from the storage account to the server, and create a SQL database. There the many pricing tier options for the database creation, where the Basic tier only costs about $5 per months, which is totally covered by the free credit.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server on Windows &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/e1962de25213_106EC/image_thumb111_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/e1962de25213_106EC/image_thumb111_thumb.png&quot; alt=&quot;image_thumb111&quot; title=&quot;image_thumb111&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;There are several free options to install SQL Server:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server LocalDB: the easiest option, since no configuration is required for setup.&lt;/li&gt;
&lt;li&gt;SQL Server Express Core&lt;/li&gt;
&lt;li&gt;SQL Server Express with Advanced Services&lt;/li&gt;
&lt;li&gt;SQL Server Developer Edition: free after signing up &lt;a href=&quot;https://www.visualstudio.com/dev-essentials/&quot;&gt;Visual Studio Dev Essentials&lt;/a&gt; program&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Install free tools. Microsoft provides rich tools on Windows, any tool of the following works:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt204009.aspx&quot;&gt;SQL Server Data Tools&lt;/a&gt; for Visual Studio is a free Visual Studio extension enabling SQL database management inside Visual Studio&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt238290.aspx&quot;&gt;SQL Server Management Tools&lt;/a&gt;, which includes &lt;a href=&quot;https://en.wikipedia.org/wiki/SQL_Server_Management_Studio&quot;&gt;SQL Server Management Studio&lt;/a&gt; (a free integration environment to manage SQL Server and SQL database), &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms181091.aspx&quot;&gt;SQL Server Profiler&lt;/a&gt; (a free tracing tool), and other tools.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;mssql extension&lt;/a&gt; for Visual Studio Code&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Use the installed ool to attach AdventureWorks_Data.mdf and AdventureWorks_Log.ldf to SQL Server&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server on Linux&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Install SQL Server for Linux evaluation edition, which is free and available for Red Hat and Ubuntu&lt;/li&gt;
&lt;li&gt;Install SQL Server Tools for Linux, or &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;mssql extension&lt;/a&gt; for Visual Studio Code&lt;/li&gt;
&lt;li&gt;Use the installed tool to attach AdventureWorks_Data.mdf and AdventureWorks_Log.ldf to SQL Server.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server Docker image on Linux, Mac, or Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Install Docker, then in preferences, &lt;a href=&quot;https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-docker&quot;&gt;change the memory&lt;/a&gt; to 4GB or more&lt;/li&gt;
&lt;li&gt;Pull the SQL Server Docker image (microsoft/mssql-server-linux or microsoft/mssql-server-windows), and run&lt;/li&gt;
&lt;li&gt;For Linux or Windows, install tools mentioned above; For Mac, install &lt;a href=&quot;https://www.npmjs.com/package/sql-cli&quot;&gt;sql-cli&lt;/a&gt; tool from npm, or &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;mssql extension&lt;/a&gt; for Visual Studio Code.&lt;/li&gt;
&lt;li&gt;Use the tool to attach AdventureWorks_Data.mdf and AdventureWorks_Log.ldf to SQL Server.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the sample database is ready, save the database connection string. For .NET Core, the connection string can be saved for the application as a JSON file, for example, App.json:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;ConnectionStrings&quot;: {
    &quot;AdventureWorks&quot;: &quot;Server=tcp:dixin.database.windows.net,1433;Initial Catalog=AdventureWorks;Persist Security Info=False;User ID=***;Password=***;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For .NET Framework, the connection string can be saved in the application’s App.config file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;connectionStrings&amp;gt;
    &amp;lt;add name=&quot;AdventureWorks&quot; connectionString=&quot;Server=tcp:dixin.database.windows.net,1433;Initial Catalog=AdventureWorks;Persist Security Info=False;User ID=***;Password=***;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;&quot; /&amp;gt;
  &amp;lt;/connectionStrings&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the connection string can be read by C# code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class ConnectionStrings
{
    internal static string AdventureWorks { get; } =
#if NETFX
        ConfigurationManager.ConnectionStrings[nameof(AdventureWorks)].ConnectionString;
#else
        new ConfigurationBuilder().AddJsonFile(&quot;App.json&quot;).Build()
            .GetConnectionString(nameof(AdventureWorks));
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Remote query vs. local query&lt;/h2&gt;
&lt;p&gt;LINQ to Objects, Parallel LINQ query .NET objects in current .NET application’s local memory, these queries are called local queries. LINQ to XML queries XML data source, which are local .NET objects representing XML structures as well, so LINQ to XML queries are also local queries. As demonstrated at the beginning of this tutorial, LINQ can also query data in other data domains, like tweets in Twitter, rows in database tables, etc. Apparently, these data source are not .NET objects directly available in local memory. These queries are called remote queries.&lt;/p&gt;
&lt;p&gt;Local data sources and local queries are represented by IEnumerable&amp;lt;T&amp;gt;. Remote LINQ data sources, like a table in database, and remote queries, are represented by System.Linq.IQueryable&amp;lt;T&amp;gt;. Similar to ParallelQuery&amp;lt;T&amp;gt; discussed in the Parallel LINQ chapter, IQueryable&amp;lt;T&amp;gt; is another parity with IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;table cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;542&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;290&quot;&amp;gt;LINQ to (local) Objects&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;250&quot;&amp;gt;LINQ to (remote) Entities&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;290&quot;&amp;gt;System.Collections.IEnumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;250&quot;&amp;gt;System.Linq.IQueryable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;290&quot;&amp;gt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;250&quot;&amp;gt;System.Linq.IQueryable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;290&quot;&amp;gt;System.Linq.IOrderedEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;250&quot;&amp;gt;System.Linq.IOrderedQueryable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;290&quot;&amp;gt;System.Linq.Enumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;250&quot;&amp;gt;System.Linq.Queryable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable : IEnumerable
    {
        Expression Expression { get; }

        Type ElementType { get; }

        IQueryProvider Provider { get; }
    }

    public interface IOrderedQueryable : IQueryable, IEnumerable { }

    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable { }

    public interface IOrderedQueryable&amp;lt;out T&amp;gt; : IQueryable&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IOrderedQueryable, IQueryable, IEnumerable { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; has many implementations, like T[] array, Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt;, etc. EF Core provides IQueryable&amp;lt;T&amp;gt; implementations, including Microsoft.EntityFrameworkCore.DbSet&amp;lt;T&amp;gt;, Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable&amp;lt;T&amp;gt;, etc. Please see the LINQ to Objects chapter for the detailed list and inheritance hierarchy for types implementing IEnumerable&amp;lt;T&amp;gt;, ParallelQuery&amp;lt;T&amp;gt;, and IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EF provides IQueryable&amp;lt;T&amp;gt; implementations including System.Data.Entity.DbSet&amp;lt;T&amp;gt;, System.Data.Entity.Infrastructure.DbQuery&amp;lt;T&amp;gt;, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;System.Linq.Queryable static class provides all the query methods for IQueryable&amp;lt;T&amp;gt;, which are parities with Enumerable query methods. For example, the following are the local and remote Where/Select/Concat/Cast methods side by side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);

        public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);

        // Other members.
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);

        public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector);

        public static IQueryable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source1, IEnumerable&amp;lt;TSource&amp;gt; source2);

        public static IQueryable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IQueryable source);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For each remote query method, the type of generic source sequence and result sequence is simply replaced by IQueryable&amp;lt;T&amp;gt;, the type of non-generic sequence is replaced by Queryable, and the call back functions are replaced by expression trees representing those functions. Similarly, the following are the ordering methods side by side, where the type of ordered source sequence and result sequence is replaced by IOrderedQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
    }

    public static class Queryable
    {
        public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this design, fluent method chaining and the LINQ query expressions pattern are implemented for remote LINQ queries.&lt;/p&gt;
&lt;p&gt;Queryable does not provide the following query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Empty/Range/Repeat: it does not make sense for .NET to locally generate a remote data source or remote query on the fly; the other generation method, DefaultIfEmpty, is available, because DefaultIfEmpty works with an IQueryable&amp;lt;T&amp;gt; source.&lt;/li&gt;
&lt;li&gt;AsEnumerable: it returns IEnumerable&amp;lt;T&amp;gt; representing a local sequence of .NET objects, and this conversion is already provided by Enumerable in LINQ to Objects&lt;/li&gt;
&lt;li&gt;ToArray/ToDictionary/ToList/ToLookup: these methods creates local .NET collections, and these conversions are already provided by local LINQ to Objects.&lt;/li&gt;
&lt;li&gt;Max/Min overloads for .NET primary types: these .NET primitive types belongs to local .NET application, not the remote data domain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Queryable also provides an additional query method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AsQueryable: unlike AsSequential/AsParallel switching between sequential and parallel query, AsEnumerable/AsQueryable cannot freely switch between local and remote query. This method is discussed later.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Function vs. expression tree&lt;/h2&gt;
&lt;p&gt;Enumerable query methods accept functions, and Queryable methods accept expression trees. As discussed in the Functional Programming chapter, functions are executable .NET code, and expression trees are data structures representing abstract syntax tree of functions, which can be translated to other domain-specific language. The Functional Programming chapter also demonstrates compiling an arithmetic expression tree into CIL code at runtime, and executing it dynamically. The same approach can be used to translate arithmetic expression tree to SQL query, and execute it in a remote SQL database. The following example reuses the previously defined BinaryArithmeticExpressionVisitor&amp;lt;T&amp;gt; type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class InfixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;string&amp;gt;
{
    internal override string VisitBody(LambdaExpression expression) =&amp;gt; $&quot;SELECT {base.VisitBody(expression)};&quot;;

    protected override string VisitAdd(
        BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, &quot;+&quot;, expression);

    protected override string VisitConstant(
        ConstantExpression constant, LambdaExpression expression) =&amp;gt; constant.Value.ToString();

    protected override string VisitDivide(
        BinaryExpression divide, LambdaExpression expression) =&amp;gt; this.VisitBinary(divide, &quot;/&quot;, expression);

    protected override string VisitMultiply(
        BinaryExpression multiply, LambdaExpression expression) =&amp;gt; this.VisitBinary(multiply, &quot;*&quot;, expression);

    protected override string VisitParameter(
        ParameterExpression parameter, LambdaExpression expression) =&amp;gt; $&quot;@{parameter.Name}&quot;;

    protected override string VisitSubtract(
        BinaryExpression subtract, LambdaExpression expression) =&amp;gt; this.VisitBinary(subtract, &quot;-&quot;, expression);

    private string VisitBinary(
        BinaryExpression binary, string @operator, LambdaExpression expression) =&amp;gt;
            $&quot;({this.VisitNode(binary.Left, expression)} {@operator} {this.VisitNode(binary.Right, expression)})&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can traverse an arithmetic expression tree, and compile it to a SQL SELECT statement with infix arithmetic expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void Sql()
    {
        InfixVisitor infixVisitor = new InfixVisitor();
        Expression&amp;lt;Func&amp;lt;double, double, double&amp;gt;&amp;gt; expression1 = (a, b) =&amp;gt; a * a + b * b;
        string infixExpression1 = infixVisitor.VisitBody(expression1);
        infixExpression1.WriteLine(); // SELECT ((@a * @a) + (@b * @b));

        Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression2 =
            (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
        string infixExpression2 = infixVisitor.VisitBody(expression2);
        infixExpression2.WriteLine(); // SELECT (((@a + @b) - ((@c * @d) / 2)) + (@e * 3));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here @ is prepended to each parameter name, which is the SQL syntax.&lt;/p&gt;
&lt;p&gt;The following ExecuteScalar method is defined to execute the compiled SQL statement with SQL parameters and SQL database connection string provided, and return a single result value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class BinaryArithmeticTranslator
{
    internal static double ExecuteScalar(
        string connection,
        string command,
        IDictionary&amp;lt;string, double&amp;gt; parameters)
    {
        using (SqlConnection sqlConnection = new SqlConnection(connection))
        using (SqlCommand sqlCommand = new SqlCommand(command, sqlConnection))
        {
            sqlConnection.Open();
            parameters.ForEach(parameter =&amp;gt; sqlCommand.Parameters.AddWithValue(parameter.Key, parameter.Value));
            return (double)sqlCommand.ExecuteScalar();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following Sql method is defined wrap the entire work. It accept an arithmetic expression tree, call the above InfixVisitor.VisitBody to compile it to SQL, then emit a dynamic function, which extracts the parameters and calls above ExecuteScalar method to execute the SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class BinaryArithmeticTranslator
{
    private static readonly InfixVisitor InfixVisitor = new InfixVisitor();

    public static TDelegate Sql&amp;lt;TDelegate&amp;gt;(Expression&amp;lt;TDelegate&amp;gt; expression, string connection) where TDelegate : class
    {
        DynamicMethod dynamicMethod = new DynamicMethod(
            string.Empty,
            expression.ReturnType,
            expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
            typeof(BinaryArithmeticTranslator).Module);
        EmitIL(dynamicMethod.GetILGenerator(), InfixVisitor.VisitBody(expression), expression, connection);
        return (TDelegate)(object)dynamicMethod.CreateDelegate(typeof(TDelegate));
    }

    private static void EmitIL&amp;lt;TDelegate&amp;gt;(
        ILGenerator ilGenerator, string infixExpression, Expression&amp;lt;TDelegate&amp;gt; expression, string connection)
    {
        // Dictionary&amp;lt;string, double&amp;gt; dictionary = new Dictionary&amp;lt;string, double&amp;gt;();
        ilGenerator.DeclareLocal(typeof(Dictionary&amp;lt;string, double&amp;gt;));
        ilGenerator.Emit(
            OpCodes.Newobj,
            typeof(Dictionary&amp;lt;string, double&amp;gt;).GetConstructor(Array.Empty&amp;lt;Type&amp;gt;()));
        ilGenerator.Emit(OpCodes.Stloc_0);

        for (int index = 0; index &amp;lt; expression.Parameters.Count; index++)
        {
            // dictionary.Add($&quot;@{expression.Parameters[i].Name}&quot;, args[i]);
            ilGenerator.Emit(OpCodes.Ldloc_0); // dictionary.
            ilGenerator.Emit(OpCodes.Ldstr, $&quot;@{expression.Parameters[index].Name}&quot;);
            ilGenerator.Emit(OpCodes.Ldarg_S, index);
            ilGenerator.Emit(
                OpCodes.Callvirt,
                typeof(Dictionary&amp;lt;string, double&amp;gt;).GetMethod(
                    nameof(Dictionary&amp;lt;string, double&amp;gt;.Add),
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod));
        }

        // BinaryArithmeticTanslator.ExecuteSql(connection, expression, dictionary);
        ilGenerator.Emit(OpCodes.Ldstr, connection);
        ilGenerator.Emit(OpCodes.Ldstr, infixExpression);
        ilGenerator.Emit(OpCodes.Ldloc_0);
        ilGenerator.Emit(
            OpCodes.Call,
            typeof(BinaryArithmeticTranslator).GetMethod(
                nameof(ExecuteScalar),
                BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod));

        // Returns the result of ExecuteSql.
        ilGenerator.Emit(OpCodes.Ret);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, .NET built-in Expression&amp;lt;TDelegate&amp;gt;.Compile method compiles expression tree to CIL, and emits a function to execute the CIL locally with current .NET application process. In contrast, here BinaryArithmeticTranslator.Sql compiles the arithmetic expression tree to SQL, and emits a function to execute the SQL in a specified remote SQL database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExecuteSql()
{
    Expression&amp;lt;Func&amp;lt;double, double, double&amp;gt;&amp;gt; expression1 = (a, b) =&amp;gt; a * a + b * b;
    Func&amp;lt;double, double, double&amp;gt; local1 = expression1.Compile();
    local1(1, 2).WriteLine(); // 5
    Func&amp;lt;double, double, double&amp;gt; remote1 = expression1.Sql(ConnectionStrings.AdventureWorks);
    remote1(1, 2).WriteLine(); // 5

    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression2 =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
    Func&amp;lt;double, double, double, double, double, double&amp;gt; local2 = expression2.Compile();
    local2(1, 2, 3, 4, 5).WriteLine(); // 12
    Func&amp;lt;double, double, double, double, double, double&amp;gt; remote2 = expression2.Sql(ConnectionStrings.AdventureWorks);
    remote2(1, 2, 3, 4, 5).WriteLine(); // 12
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# 8.0 in-depth: Understanding index and range, and working with LINQ and IEnumerable&lt;T&gt;</title><link>https://dixin.github.io/posts/c-8-0-in-depth-understanding-index-and-range-and-working-with-linq-and-ienumerable-t/</link><guid isPermaLink="true">https://dixin.github.io/posts/c-8-0-in-depth-understanding-index-and-range-and-working-with-linq-and-ienumerable-t/</guid><description>C# 8.0 introduces index and range for array. This part discussed the index and range types, syntax, compilation, and how to apply them with LINQ for any type that implements IEnumerable&lt;T&gt;.</description><pubDate>Sun, 24 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# 8.0 introduces index and range for array. This part discussed the index and range types, syntax, compilation, and how to apply them with LINQ for any type that implements IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Index and Range types and C# syntax&lt;/h2&gt;
&lt;p&gt;The System.Index and System.Range structures are introduced to the new .NET Standard. Index is a wrapper of int index value (non-negative int means index from start, negative int means index from the end), and Range is a tuple of start Index and end Index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public readonly struct Index : IEquatable&amp;lt;Index&amp;gt;
{
    private readonly int _value;

    public Index(int value, bool fromEnd)
    {
        if (value &amp;lt; 0)
        {
            ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
        }
        this._value = fromEnd ? ~value : value;
    }

    public int Value =&amp;gt; this._value &amp;gt;= 0 ? this._value : ~this._value;

    public bool FromEnd =&amp;gt; _value &amp;lt; 0;

    public static implicit operator Index(int value) =&amp;gt; new Index(value, false);

    // Other members.
}

public readonly struct Range : IEquatable&amp;lt;Range&amp;gt;
{
    private Range(Index start, Index end)
    {
        this.Start = start; this.End = end;
    }

    public Index Start { get; }

    public Index End { get; }

    public static Range Create(Index start, Index end) =&amp;gt; 
        new Range(start, end);
    
    public static Range All() =&amp;gt; 
        new Range(new Index(0, false), new Index(0, true));

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 8.0 introduces the index and range syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index index1 = 1; // Index 1 from start.
Index index2 = ^2; // Index 2 from end.
Range range1 = 1..10; // Start index is 1 from start, end index is 10 from start.
Range range2 = 10..^5; // Start index is 1 from start, end index is 5 from end.
Range range3 = ^10..; // Start index is 10 from end, end index is 0 from end.
Range range4 = ..; // Start index is 0 from start, end index is 0 from end.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are syntactic sugars, which are compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index index3 = 1;
Index index2 = new Index(2, true);
Range range5 = Range.Create(1, 10);
Range range4 = Range.Create(10, new Index(5, true));
Range range3 = Range.FromStart(new Index(10, true));
Range range2 = Range.All();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Index and Range for array&lt;/h2&gt;
&lt;p&gt;C# introduces syntactic sugars to enable Index with array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int value = array[^1];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is compiled to normal int indexer access:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Index index = new Index(1, true);
int value = index.FromEnd ? array[array.Length - index.Value] : array[index.Value];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the range syntactic sugar for array slice:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] slice = array[^9..7];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is compiled to array copy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Range range = Range.Create(new Index(9, true), 7);
int startIndex = range.Start.FromEnd ? array.Length - range.Start.Value : range.Start.Value;
int rangeLength = (range.End.FromEnd ? array.Length - range.End.Value : range.End.Value) - startIndex;
int[] slice = new int[rangeLength];
Array.Copy(sourceArray: array, sourceIndex: startIndex, destinationArray: slice, destinationIndex: 0, length: rangeLength);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;LINQ queries - Index and Range for IEnumerable&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;Currently (v3.0.0-preview2/SDK 3.0.100-preview-010184), the index and range work with array, and do not work with other types, like List&amp;lt;T&amp;gt;. It is natural and convenient to support index and range in LINQ, so they can work with any type that implements IEnumerable&amp;lt;T&amp;gt;. The goals of these LINQ APIs are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use index to locate an element in sequence, use range to slice sequence. The usage is the same as index/range for array, but with deferred execution for slice with range.&lt;/li&gt;
&lt;li&gt;Use range to start fluent LINQ query.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This enables the index and range to work with any type that implements IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;LINQ already has ElementAt(int index) and ElementOrDefault(int index) query operator. It would be natural to have a overload for System.Index: ElementAt(Index index) and ElementOrDefault(Index index), and a new method ElementsIn(Range range), so that LINQ can seamlessly work with C# 8.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index index = ...;
var element1 = source1.ElementAt(index);
var element2 = source2.ElementAtOrDefault(^ 5);
Range range = ...;
var slice1 = source3.ElementsIn(range);
var slice2 = source4.ElementsIn(2..^ 2)
var slice2 = source5.ElementsIn(^ 10..);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following Range overload and AsEnumerable overload for System.Range convert it to a sequence, so that LINQ query can be started fluently from c# range:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index index = ...;
var element1 = source1.ElementAt(index);
var element2 = source2.ElementAtOrDefault(^ 5);
Range range = ...;
var slice1 = source3.ElementsIn(range);
var slice2 = source4.ElementsIn(2..^ 2)
var slice2 = source5.ElementsIn(^ 10..);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;APIs&lt;/h3&gt;
&lt;p&gt;For LINQ to Objects, ideally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static partial class Queryable
    {
        public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

        public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

        public static IEnumerable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Range range) { throw null; }

        public static IEnumerable&amp;lt;TSource&amp;gt; Range&amp;lt;TSource&amp;gt;(Range range) { throw null; }

        public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this Range source) { throw null; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For remote LINQ, ideally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static partial class Queryable
    {
        public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

        public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

        public static IQueryable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Range range) { throw null; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Implementation details&lt;/h3&gt;
&lt;p&gt;These APIs&apos; implementation is self-contained so that the code can be just copied to use.&lt;/p&gt;
&lt;p&gt;The implementation of ElementAt(Index), ElementOrDefault(Index) and ElementsIn(Range) for IQueryable&amp;lt;T&amp;gt; is straightforward. They just create an expression tree.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class QueryableExtensions
{
    public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index)
    {
        if (source == null)
            // throw Error.ArgumentNull(nameof(source));
            throw new ArgumentNullException(nameof(source));
        return source.Provider.Execute&amp;lt;TSource&amp;gt;(
            Expression.Call(
                null,
                CachedReflectionInfo.ElementAt_TSource_2(typeof(TSource)),
                source.Expression, Expression.Constant(index)
                ));
    }

    public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index)
    {
        if (source == null)
            // throw Error.ArgumentNull(nameof(source));
            throw new ArgumentNullException(nameof(source));
        return source.Provider.Execute&amp;lt;TSource&amp;gt;(
            Expression.Call(
                null,
                CachedReflectionInfo.ElementAtOrDefault_TSource_2(typeof(TSource)),
                source.Expression, Expression.Constant(index)
                ));
    }

    public static IQueryable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Range range)
    {
        if (source == null)
            // throw Error.ArgumentNull(nameof(source));
            throw new ArgumentNullException(nameof(source));

        return source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(
            Expression.Call(
                null,
                CachedReflectionInfo.ElementsIn_TSource_2(typeof(TSource)),
                source.Expression, Expression.Constant(range)));
    }
}

internal static class CachedReflectionInfo
{
    private static MethodInfo s_ElementAt_TSource_2;

    public static MethodInfo ElementAt_TSource_2(Type TSource) =&amp;gt;
         (s_ElementAt_TSource_2 ??
         (s_ElementAt_TSource_2 = new Func&amp;lt;IQueryable&amp;lt;object&amp;gt;, Index, object&amp;gt;(QueryableExtensions.ElementAt).GetMethodInfo().GetGenericMethodDefinition()))
          .MakeGenericMethod(TSource);

    private static MethodInfo s_ElementAtOrDefault_TSource_2;

    public static MethodInfo ElementAtOrDefault_TSource_2(Type TSource) =&amp;gt;
         (s_ElementAtOrDefault_TSource_2 ??
         (s_ElementAtOrDefault_TSource_2 = new Func&amp;lt;IQueryable&amp;lt;object&amp;gt;, Index, object&amp;gt;(QueryableExtensions.ElementAtOrDefault).GetMethodInfo().GetGenericMethodDefinition()))
          .MakeGenericMethod(TSource);

    private static MethodInfo s_ElementsIn_TSource_2;

    public static MethodInfo ElementsIn_TSource_2(Type TSource) =&amp;gt;
         (s_ElementsIn_TSource_2 ??
         (s_ElementsIn_TSource_2 = new Func&amp;lt;IQueryable&amp;lt;object&amp;gt;, Range, IQueryable&amp;lt;object&amp;gt;&amp;gt;(QueryableExtensions.ElementsIn).GetMethodInfo().GetGenericMethodDefinition()))
          .MakeGenericMethod(TSource);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods for IEnumerable&amp;lt;T&amp;gt; are straightforward as well, I just followed the behavior and exceptions of array with range. See unit tests &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/blob/master/Linq.Range/Linq.Range.Tests/ElementsInTests.cs&quot;&gt;https://github.com/Dixin/CodeSnippets/blob/master/Linq.Range/Linq.Range.Tests/ElementsInTests.cs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;ElementAt(Index) and ElementAtOrDefault(Index):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index)
{
    if (source == null)
    {
        // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
        throw new ArgumentNullException(nameof(source));
    }

    if (!index.FromEnd)
    {
        return source.ElementAt(index.Value);
    }

    int indexFromEnd = index.Value;
    if (indexFromEnd &amp;gt; 0)
    {
        if (source is IList&amp;lt;TSource&amp;gt; list)
        {
            return list[list.Count - indexFromEnd];
        }

        using (IEnumerator&amp;lt;TSource&amp;gt; e = source.GetEnumerator())
        {
            if (e.MoveNext())
            {
                Queue&amp;lt;TSource&amp;gt; queue = new Queue&amp;lt;TSource&amp;gt;();
                queue.Enqueue(e.Current);
                while (e.MoveNext())
                {
                    if (queue.Count == indexFromEnd)
                    {
                        queue.Dequeue();
                    }

                    queue.Enqueue(e.Current);
                }

                if (queue.Count == indexFromEnd)
                {
                    return queue.Dequeue();
                }
            }
        }
    }

    // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
    throw new ArgumentOutOfRangeException(nameof(index));
    return default!;
}

public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index)
{
    if (source == null)
    {
        // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
        throw new ArgumentNullException(nameof(source));

    }

    if (!index.FromEnd)
    {
        return source.ElementAtOrDefault(index.Value);
    }

    int indexFromEnd = index.Value;
    if (indexFromEnd &amp;gt; 0)
    {
        if (source is IList&amp;lt;TSource&amp;gt; list)
        {
            int count = list.Count;
            if (count &amp;gt;= indexFromEnd)
            {
                return list[count - indexFromEnd];
            }
        }

        using (IEnumerator&amp;lt;TSource&amp;gt; e = source.GetEnumerator())
        {
            if (e.MoveNext())
            {
                Queue&amp;lt;TSource&amp;gt; queue = new Queue&amp;lt;TSource&amp;gt;();
                queue.Enqueue(e.Current);
                while (e.MoveNext())
                {
                    if (queue.Count == indexFromEnd)
                    {
                        queue.Dequeue();
                    }

                    queue.Enqueue(e.Current);
                }

                if (queue.Count == indexFromEnd)
                {
                    return queue.Dequeue();
                }
            }
        }
    }

    return default!;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ElementsIn(Range):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Range range)
{
    if (source == null)
    {
        // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
        throw new ArgumentNullException(nameof(source));
    }

    return ElementsInIterator(source, range);
}

private static IEnumerable&amp;lt;TSource&amp;gt; ElementsInIterator&amp;lt;TSource&amp;gt;(IEnumerable&amp;lt;TSource&amp;gt; source, Range range)
{
    Index start = range.Start;
    Index end = range.End;

    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        int count = list.Count;
        if (count == 0 &amp;amp;&amp;amp; range.Equals(System.Range.All()))
        {
            yield break;
        }

        int firstIndex = start.FromEnd ? count - start.Value : start.Value;
        int lastIndex = (end.FromEnd ? count - end.Value : end.Value) - 1;
        if (lastIndex &amp;lt; firstIndex - 1)
        {
            // ThrowHelper.ThrowOverflowException();
            throw new OverflowException(); // Following the behavior of array with range.
        }

        if (firstIndex &amp;lt; 0 || lastIndex &amp;lt; 0)
        {
            // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.range);
            throw new ArgumentOutOfRangeException(nameof(range)); // Following the behavior of array with range.
        }

        if (firstIndex &amp;gt;= count || lastIndex &amp;gt;= count)
        {
            // ThrowHelper.ThrowArgumentException(ExceptionArgument.range);
            throw new ArgumentException(nameof(range)); // Following the behavior of array with range.
        }

        for (int currentIndex = firstIndex; currentIndex &amp;lt;= lastIndex; currentIndex++)
        {
            yield return list[currentIndex];
        }
        yield break;
    }

    using (IEnumerator&amp;lt;TSource&amp;gt; e = source.GetEnumerator())
    {
        int currentIndex = -1;
        if (start.FromEnd)
        {
            if (!e.MoveNext())
            {
                const int count = 0;
                int firstIndex = count - start.Value;
                int lastIndex = (end.FromEnd ? count - end.Value : end.Value) - 1;
                if (lastIndex &amp;lt; firstIndex - 1)
                {
                    // ThrowHelper.ThrowOverflowException();
                    throw new OverflowException(); // Following the behavior of array with range.
                }

                // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.range);
                throw new ArgumentOutOfRangeException(nameof(range));
            }
            else
            {
                Queue&amp;lt;TSource&amp;gt; queue = new Queue&amp;lt;TSource&amp;gt;();
                queue.Enqueue(e.Current);
                currentIndex++;

                int takeLastCount = start.Value;
                while (e.MoveNext())
                {
                    if (queue.Count == takeLastCount)
                    {
                        queue.Dequeue();
                    }

                    queue.Enqueue(e.Current);
                    currentIndex++;
                }

                if (queue.Count &amp;lt; takeLastCount)
                {
                    // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.range);
                    throw new ArgumentOutOfRangeException(nameof(range));
                }

                int firstIndex = currentIndex + 1 - takeLastCount;
                int lastIndex = end.FromEnd ? currentIndex - end.Value : end.Value - 1;
                if (lastIndex &amp;lt; firstIndex - 1)
                {
                    // ThrowHelper.ThrowOverflowException();
                    throw new OverflowException(); // Following the behavior of array with range.
                }

                for (int index = firstIndex; index &amp;lt;= lastIndex; index++)
                {
                    yield return queue.Dequeue();
                }
            }
        }
        else
        {
            int firstIndex = start.Value;
            if (!e.MoveNext())
            {
                if (range.Equals(System.Range.All()))
                {
                    yield break;
                }

                const int count = 0;
                int lastIndex = (end.FromEnd ? count - end.Value : end.Value) - 1;
                if (lastIndex &amp;lt; firstIndex - 1)
                {
                    // ThrowHelper.ThrowOverflowException();
                    throw new OverflowException(); // Following the behavior of array with range.
                }
                // ThrowHelper.ThrowArgumentException(ExceptionArgument.range);
                throw new ArgumentException(nameof(range)); // Following the behavior of array with range.
            }

            currentIndex++;
            while (currentIndex &amp;lt; firstIndex &amp;amp;&amp;amp; e.MoveNext())
            {
                currentIndex++;
            }

            if (currentIndex != firstIndex)
            {
                // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.range);
                throw new ArgumentOutOfRangeException(nameof(range));
            }

            if (end.FromEnd)
            {
                int skipLastCount = end.Value;
                if (skipLastCount &amp;gt; 0)
                {
                    Queue&amp;lt;TSource&amp;gt; queue = new Queue&amp;lt;TSource&amp;gt;();
                    do
                    {
                        if (queue.Count == skipLastCount)
                        {
                            yield return queue.Dequeue();
                        }

                        queue.Enqueue(e.Current);
                        currentIndex++;
                    }
                    while (e.MoveNext());
                }
                else
                {
                    do
                    {
                        yield return e.Current;
                        currentIndex++;
                    }
                    while (e.MoveNext());
                }

                if (firstIndex + skipLastCount &amp;gt; currentIndex)
                {
                    // ThrowHelper.ThrowOverflowException();
                    throw new OverflowException(); // Following the behavior of array with range.
                }
            }
            else
            {
                int lastIndex = end.Value - 1;
                if (lastIndex &amp;lt; firstIndex - 1)
                {
                    // ThrowHelper.ThrowOverflowException();
                    throw new OverflowException(); // Following the behavior of array with range.
                }

                if (lastIndex == firstIndex - 1)
                {
                    yield break;
                }

                yield return e.Current;
                while (currentIndex &amp;lt; lastIndex &amp;amp;&amp;amp; e.MoveNext())
                {
                    currentIndex++;
                    yield return e.Current;
                }

                if (currentIndex != lastIndex)
                {
                    // ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.range);
                    throw new ArgumentOutOfRangeException(nameof(range));
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Range(Range) and AsEnumerable(Range), the question is: what does Range&apos;s start Index and end Index mean when the index is from the end? For example, 10..20 can be easily converted to a sequence of 10, 11,12, ... 19, but how about ^20...^10? In my current implementation, regarding Index&apos;s value can be from 0 to int.MaxValue, I assume a virtual &quot;full range&quot; 0..2147483648, and any Range instance is a slice of that &quot;full range&quot;. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ranges .. and 0.. and ..^0 and 0..^0 are converted to &quot;full sequence&quot; 0, 1, .. 2147483647&lt;/li&gt;
&lt;li&gt;Range 100..^47 is converted to sequence 100, 101, .. 2147483600&lt;/li&gt;
&lt;li&gt;Range ^48..^40 is converted to sequence 2147483600, 2147483601 .. 2147483607&lt;/li&gt;
&lt;li&gt;Range 10..10 is converted to empty sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; Range(Range range)
{
    Index startIndex = range.Start;
    Index endIndex = range.End;
    int firstValue = startIndex.FromEnd ? int.MaxValue - startIndex.Value + 1 : startIndex.Value;
    int lastValue = endIndex.FromEnd ? int.MaxValue - endIndex.Value : endIndex.Value - 1;
    if (lastValue &amp;lt; firstValue - 1)
    {
        // ThrowHelper.ThrowOverflowException();
        throw new OverflowException(); // Following the behavior of array with range.
    }

    if (lastValue == firstValue - 1)
    {
        return Enumerable.Empty&amp;lt;int&amp;gt;();
    }

    return RangeIterator(firstValue, lastValue);
}

private static IEnumerable&amp;lt;int&amp;gt; RangeIterator(int firstValue, int lastValue)
{
    for (int value = firstValue; value &amp;lt;= lastValue; value = checked(value + 1))
    {
        yield return value;
        if (value == int.MaxValue)
        {
            yield break;
        }
    }
}

public static IEnumerable&amp;lt;int&amp;gt; AsEnumerable(this Range range)
{
    int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int[] slice = array[^ 9..7];
    return Range(range);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See unit tests of AsEnumerable(Range) &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/blob/master/Linq.Range/Linq.Range.Tests/AsEnumerableTests.cs&quot;&gt;https://github.com/Dixin/CodeSnippets/blob/master/Linq.Range/Linq.Range.Tests/AsEnumerableTests.cs&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>C# 8.0 in-depth: Setup C# 8.0 and .NET Core 3.0</title><link>https://dixin.github.io/posts/c-8-0-in-depth-setup-c-8-0-and-net-core-3-0/</link><guid isPermaLink="true">https://dixin.github.io/posts/c-8-0-in-depth-setup-c-8-0-and-net-core-3-0/</guid><description>Currently, Microsoft has the second preview of C# 8.0 and .NET Core 3.0, with a lot of new features and new APIs. This part of C# 8.0 series demonstrates how to setup the environment.</description><pubDate>Thu, 21 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Currently, Microsoft has the second preview of C# 8.0 and .NET Core 3.0, with a lot of new features and new APIs. This part of C# 8.0 series demonstrates how to setup the environment.&lt;/p&gt;
&lt;p&gt;One way to setup the environment is to install Visual Studio 2019 preview (&lt;a href=&quot;https://visualstudio.microsoft.com/vs/preview/&quot;&gt;https://visualstudio.microsoft.com/vs/preview/&lt;/a&gt;). However, if you use Linux or macOS, or you do not have tons of space on your hard drive, you can go with Visual Studio Code. After all it is just a text editor.&lt;/p&gt;
&lt;h2&gt;Setup .NET Core preview SDK&lt;/h2&gt;
&lt;p&gt;First, install the latest SDK of .NET Core 3.0 for your operating system from the official website: &lt;a href=&quot;https://dotnet.microsoft.com/download/dotnet-core/3.0&quot;&gt;https://dotnet.microsoft.com/download/dotnet-core/3.0&lt;/a&gt;. Currently v3.0.0-preview2/SDK 3.0.100-preview-010184 is the latest. Then run the following command to verify the installation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet --version
3.0.100-preview-010184
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, the dotnet CLI uses the latest SDK installed for dotnet build and dotnet new, etc.. If you want to go back to the previous stable SDK, use the global.json to specify the stable SDK version for your directory. First, run dotnet –list-sdks to view all the installed SDKs, then run dotnet new globaljson –skd-version {version} to create the global.json file. Then run dotnet –version to verify the changed SDK version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\dixin&amp;gt;dotnet --list-sdks
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.2.100 [C:\Program Files\dotnet\sdk]
3.0.100-preview-010184 [C:\Program Files\dotnet\sdk]

C:\Users\dixin&amp;gt;d:

d:\&amp;gt;cd User\GitHub\CodeSnippets\Linq.Range\Test

d:\User\GitHub\CodeSnippets\Linq.Range\Test&amp;gt;dotnet new globaljson --sdk-version 2.2.100
The template &quot;global.json file&quot; was created successfully.

d:\User\GitHub\CodeSnippets\Linq.Range\Test&amp;gt;type global.json
{
  &quot;sdk&quot;: {
    &quot;version&quot;: &quot;2.2.100&quot;
  }
}
d:\User\GitHub\CodeSnippets\Linq.Range\Test&amp;gt;dotnet --version
2.2.100
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Setup Visual Studio Code with preview C# extension&lt;/h2&gt;
&lt;p&gt;Now Visual Studio Code should work with dotnet CLI, since it is just a text editor. The latest preview C# extension can be installed for a little better experience with C# 8.0. Go to its GitHub repo: &lt;a href=&quot;https://github.com/OmniSharp/omnisharp-vscode/releases&quot;&gt;https://github.com/OmniSharp/omnisharp-vscode/releases&lt;/a&gt;. Currently the latest preview is v1.18.0-beta7. Download the .vsix installer, then load it to Visual Studio Code:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-8.0-in-depth-Setup-C-8.0-and-.NET-Co.0_A434/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-8.0-in-depth-Setup-C-8.0-and-.NET-Co.0_A434/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After that, the extensions version shows 1.18.0-beta7:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-8.0-in-depth-Setup-C-8.0-and-.NET-Co.0_A434/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-8.0-in-depth-Setup-C-8.0-and-.NET-Co.0_A434/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup project&lt;/h2&gt;
&lt;p&gt;Now create a new console app project with dotnet CLI: dotnet new console. Then open the created .csproj file, enable C# 8.0 by adding &amp;lt;LangVersion&amp;gt;8.0&amp;lt;/LangVersion&amp;gt;, and enable C# 8.0 nullable reference type check by adding &amp;lt;NullableContextOptions&amp;gt;enable&amp;lt;/NullableContextOptions&amp;gt;. The .csproj file becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;
    &amp;lt;TargetFramework&amp;gt;netcoreapp3.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;LangVersion&amp;gt;8.0&amp;lt;/LangVersion&amp;gt;
    &amp;lt;NullableContextOptions&amp;gt;enable&amp;lt;/NullableContextOptions&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In preview 1, &amp;lt;NullableReferenceTypes&amp;gt;true&amp;lt;/NullableReferenceTypes&amp;gt; was used. Now it is changed to &amp;lt;NullableContextOptions&amp;gt;. Then you can start coding C# 8.0 and .NET Core 3.0, and press F5 to start debugging with Visual Studio Code.&lt;/p&gt;
&lt;p&gt;If you create a library project, the default target framework is TargetFramework is netstandard2.0. It must be changed to netcoreapp3.0. The entire .csproj becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;netcoreapp3.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;LangVersion&amp;gt;8.0&amp;lt;/LangVersion&amp;gt;
    &amp;lt;NullableContextOptions&amp;gt;enable&amp;lt;/NullableContextOptions&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is no &amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ via C#</title><link>https://dixin.github.io/posts/book/</link><guid isPermaLink="true">https://dixin.github.io/posts/book/</guid><description>C#, .NET Core, Azure, Functional Programming, Lambda Calculus, Category Theory, LINQ, LINQ to Objects, LINQ to XML, Parallel LINQ, LINQ to Entities, Entity Framework Core, Azure SQL Database.</description><pubDate>Tue, 19 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;[Latest version: &lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;https://weblogs.asp.net/dixin/linq-via-csharp&lt;/a&gt;]&lt;/h3&gt;
&lt;h3&gt;Keywords&lt;/h3&gt;
&lt;p&gt;C#, .NET Core, Azure, Functional Programming, Lambda Calculus, Category Theory, LINQ, LINQ to Objects, LINQ to XML, Parallel LINQ, LINQ to Entities, Entity Framework Core, Azure SQL Database.&lt;/p&gt;
&lt;h3&gt;Abstract&lt;/h3&gt;
&lt;p&gt;This is a latest, in-depth, cross-platform book on functional programming and LINQ programming via C# language. It discusses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Elegant functional programming via C#&lt;/li&gt;
&lt;li&gt;Use functional LINQ to work with local data, and cloud data in Azure SQL Database&lt;/li&gt;
&lt;li&gt;The internal implementation and underlying mathematics theories&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Contents at a Glance&lt;/h3&gt;
&lt;p&gt;The contents are organized as the following chapters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1 Code&lt;/strong&gt; - covers functional programming via C#, and fundamentals of LINQ.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 1 Functional programming and LINQ paradigm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;What is LINQ, how LINQ uses language to work with many different data domains.&lt;/li&gt;
&lt;li&gt;Programming paradigm, imperative vs. declarative programming, object-oriented vs. functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 2 Functional programming in depth&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C# fundamentals for beginners.&lt;/li&gt;
&lt;li&gt;Aspects of functional programming via C#, including function type, named/anonymous/local function, closure, lambda, higher-order function, currying, partial application, first class function, function composition, query expression, covariance/contravariance, immutability, tuple, purity, async function, pattern matching, etc., including how C# is processed at compile time and runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 2 Data&lt;/strong&gt; - covers how to use functional LINQ to work with different data domains in the real world, and how LINQ works internally.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 3 LINQ to Objects&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use functional LINQ queries to work with objects, covering all LINQ and Ix.&lt;/li&gt;
&lt;li&gt;How the LINQ to Objects query methods are implemented, how to implement useful custom LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 4 LINQ to XML&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to modeling XML data, and use functional LINQ queries to work with XML data.&lt;/li&gt;
&lt;li&gt;How to use the other LINQ to XML APIs to manipulate XML data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 5 Parallel LINQ&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use parallelized functional LINQ queries to work with objects.&lt;/li&gt;
&lt;li&gt;Performance analysis for parallel/sequential LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 6 Entity Framework/Core and LINQ to Entities&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to model database with object-relational mapping, and use functional LINQ queries to work with relational data in database.&lt;/li&gt;
&lt;li&gt;How the C# LINQ to Entities queries are implemented to work with database.&lt;/li&gt;
&lt;li&gt;How to change data in database, and handle concurrent conflicts.&lt;/li&gt;
&lt;li&gt;Performance tips and asynchrony.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 3 Theories&lt;/strong&gt; - demystifies the abstract mathematics theories, which are the rationale and foundations of LINQ and functional programming.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 7 Lambda Calculus via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of lambda calculus, bound and free variables, reduction (α-conversion, β-reduction, η-conversion), etc.&lt;/li&gt;
&lt;li&gt;How to use lambda functions to represent values, data structures and computation, including Church Boolean, Church numbers, Church pair, Church list, and their operations.&lt;/li&gt;
&lt;li&gt;Combinators and combinatory logic, including SKI combinator calculus, fixed point combinator for function recursion, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 8 Category Theory via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of category theory, including category, object, morphism, monoid, functor, natural transformation, applicative functor, monad, and their laws.&lt;/li&gt;
&lt;li&gt;How these concepts are applied in functional programming and LINQ.&lt;/li&gt;
&lt;li&gt;How to manage I/O, state, exception handling, shared environment, logging, and continuation, etc., in functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial delivers highly reusable knowledge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It covers C# language in depth, which can be generally applied in any programming paradigms besides functional programming.&lt;/li&gt;
&lt;li&gt;It is a cross platform tutorial, covering both .NET Framework for Windows and .NET Core for Windows, Mac, Linux.&lt;/li&gt;
&lt;li&gt;It demonstrates both usage and implementation of LINQ for mainstream data domains, which also enables developer to use the LINQ technologies for other data domains, or build custom LINQ APIs for specific data scenarios.&lt;/li&gt;
&lt;li&gt;It also demystifies the abstract mathematics knowledge for functional programming, which applies to general functional programming, so it greatly helps developers understanding any other functional languages too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a fun of functional programming, LINQ, C#, and .NET technologies, hope this helps.&lt;/p&gt;
&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;p&gt;All code examples are available on GitHub: https://github.com/Dixin/CodeSnippets.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;Functional programming and LINQ paradigm&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-via-csharp-introduction-7&quot;&gt;Getting started with .NET/Core, C# and LINQ&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cross platform .NET, C# and LINQ
&lt;ul&gt;
&lt;li&gt;.NET Framework&lt;/li&gt;
&lt;li&gt;Parallel LINQ&lt;/li&gt;
&lt;li&gt;.NET Core, UWP, Mono, Xamarin and Unity&lt;/li&gt;
&lt;li&gt;.NET Standard&lt;/li&gt;
&lt;li&gt;C# functional programming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This tutorial&lt;/li&gt;
&lt;li&gt;Author&lt;/li&gt;
&lt;li&gt;Code examples&lt;/li&gt;
&lt;li&gt;Start coding
&lt;ul&gt;
&lt;li&gt;Start coding with Visual Studio (Windows)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio Code (Windows, macOS and Linux)&lt;/li&gt;
&lt;li&gt;Start coding with Visual Studio for Mac (macOS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-3-waht-is-functional-programming-7&quot;&gt;Programming paradigms and functional programming&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Programming paradigms&lt;/li&gt;
&lt;li&gt;Imperative programming vs. declarative programming&lt;/li&gt;
&lt;li&gt;Object-oriented programming vs. functional programming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/introducing-linq-2-what-is-linq-7&quot;&gt;LINQ Overview&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One language for different data domains
&lt;ul&gt;
&lt;li&gt;LINQ to Objects&lt;/li&gt;
&lt;li&gt;Parallel LINQ&lt;/li&gt;
&lt;li&gt;LINQ to XML&lt;/li&gt;
&lt;li&gt;LINQ to DataSets&lt;/li&gt;
&lt;li&gt;LINQ to Entities&lt;/li&gt;
&lt;li&gt;LINQ to SQL&lt;/li&gt;
&lt;li&gt;LINQ to NoSQL (LINQ to CosmosDB)&lt;/li&gt;
&lt;li&gt;LINQ to JSON&lt;/li&gt;
&lt;li&gt;LINQ to Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Productivity&lt;/li&gt;
&lt;li&gt;Local query vs. remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Functional programming in-depth&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals-7&quot;&gt;C# language fundamentals&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Types and members
&lt;ul&gt;
&lt;li&gt;Built-in types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reference type vs. value type
&lt;ul&gt;
&lt;li&gt;default literal expression&lt;/li&gt;
&lt;li&gt;ref structure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static class&lt;/li&gt;
&lt;li&gt;Partial type&lt;/li&gt;
&lt;li&gt;Interface and implementation
&lt;ul&gt;
&lt;li&gt;IDisposable interface and using statement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generic type
&lt;ul&gt;
&lt;li&gt;Type parameter&lt;/li&gt;
&lt;li&gt;Type parameter constraints&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nullable value type&lt;/li&gt;
&lt;li&gt;Auto property&lt;/li&gt;
&lt;li&gt;Property initializer&lt;/li&gt;
&lt;li&gt;Object initializer&lt;/li&gt;
&lt;li&gt;Collection initializer&lt;/li&gt;
&lt;li&gt;Index initializer&lt;/li&gt;
&lt;li&gt;Null coalescing operator&lt;/li&gt;
&lt;li&gt;Null conditional operator&lt;/li&gt;
&lt;li&gt;throw expression&lt;/li&gt;
&lt;li&gt;Exception filter&lt;/li&gt;
&lt;li&gt;String interpolation&lt;/li&gt;
&lt;li&gt;nameof operator&lt;/li&gt;
&lt;li&gt;Digit separator and leading underscore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-type-and-delegate-7&quot;&gt;Named Function and function polymorphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Constructor, static constructor and finalizer&lt;/li&gt;
&lt;li&gt;Static method and instance method&lt;/li&gt;
&lt;li&gt;Extension method&lt;/li&gt;
&lt;li&gt;More named functions&lt;/li&gt;
&lt;li&gt;Function polymorphisms
&lt;ul&gt;
&lt;li&gt;Ad hoc polymorphism: method overload&lt;/li&gt;
&lt;li&gt;Parametric polymorphism: generic method
&lt;ul&gt;
&lt;li&gt;Type argument inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Static import&lt;/li&gt;
&lt;li&gt;Partial method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure-7&quot;&gt;Local function and closure&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Local function&lt;/li&gt;
&lt;li&gt;Closure
&lt;ul&gt;
&lt;li&gt;Outer variable&lt;/li&gt;
&lt;li&gt;Implicit reference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-parameter-and-return-value-7&quot;&gt;Function input and output&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pass by value vs. pass by reference (ref parameter)
&lt;ul&gt;
&lt;li&gt;Pass by read only reference (in parameter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Output parameter (out parameter) and out variable&lt;/li&gt;
&lt;li&gt;Parameter array&lt;/li&gt;
&lt;li&gt;Positional argument vs. named argument&lt;/li&gt;
&lt;li&gt;Required parameter vs. optional parameter&lt;/li&gt;
&lt;li&gt;Caller information parameter&lt;/li&gt;
&lt;li&gt;Return by value vs. return by reference
&lt;ul&gt;
&lt;li&gt;Return by read only reference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-local-function-and-closure-7&quot;&gt;Delegate: function type, instance, and group&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Delegate type as function type
&lt;ul&gt;
&lt;li&gt;Function type&lt;/li&gt;
&lt;li&gt;Generic delegate type&lt;/li&gt;
&lt;li&gt;Unified built-in delegate types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delegate instance as function instance
&lt;ul&gt;
&lt;li&gt;Delegate class and delegate instance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delegate instance as function group
&lt;ul&gt;
&lt;li&gt;Event and event handler&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-anonymous-function-and-lambda-expression-7&quot;&gt;Anonymous function and lambda expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Anonymous method&lt;/li&gt;
&lt;li&gt;Lambda expression&lt;/li&gt;
&lt;li&gt;Call anonymous function&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;li&gt;Expression bodied function member&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-as-data-and-expression-tree-7&quot;&gt;Expression tree: Function as data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lambda expression as expression tree
&lt;ul&gt;
&lt;li&gt;Code as data&lt;/li&gt;
&lt;li&gt;.NET expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Compile expression tree at runtime
&lt;ul&gt;
&lt;li&gt;Traverse expression tree&lt;/li&gt;
&lt;li&gt;Expression tree to CIL at runtime&lt;/li&gt;
&lt;li&gt;Expression tree to executable function at runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Expression tree and LINQ remote query&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-higher-order-function-currying-and-first-class-function-7&quot;&gt;Higher-order function, currying and first class function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First order and higher-order function&lt;/li&gt;
&lt;li&gt;Curry function&lt;/li&gt;
&lt;li&gt;=&amp;gt; associativity&lt;/li&gt;
&lt;li&gt;Partial apply function&lt;/li&gt;
&lt;li&gt;Uncurry function&lt;/li&gt;
&lt;li&gt;First-class function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-function-composition-and-method-chaining-7&quot;&gt;Function composition and chaining&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Forward and backward composition&lt;/li&gt;
&lt;li&gt;Forward pipe&lt;/li&gt;
&lt;li&gt;Fluent chaining
&lt;ul&gt;
&lt;li&gt;Fluent extension methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ query method composition&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-query-expression-7&quot;&gt;LINQ query Expression&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Syntax and compilation&lt;/li&gt;
&lt;li&gt;Query expression pattern&lt;/li&gt;
&lt;li&gt;LINQ query expression&lt;/li&gt;
&lt;li&gt;Query expression vs. query method&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-covariance-and-contravariance-7&quot;&gt;Covariance and contravariance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Non-generic function type&lt;/li&gt;
&lt;li&gt;Generic function type&lt;/li&gt;
&lt;li&gt;Generic interface&lt;/li&gt;
&lt;li&gt;Generic higher-order function type&lt;/li&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;li&gt;Variances in .NET and LINQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-immutability-anonymous-type-and-tuple-7&quot;&gt;Immutability, anonymous type and tuple&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Immutable value
&lt;ul&gt;
&lt;li&gt;Constant&lt;/li&gt;
&lt;li&gt;using statement and foreach statement&lt;/li&gt;
&lt;li&gt;this reference for class&lt;/li&gt;
&lt;li&gt;Function’s readonly parameter and readonly return&lt;/li&gt;
&lt;li&gt;Local variable by readonly reference (ref readonly variable)&lt;/li&gt;
&lt;li&gt;Immutable value in LINQ query expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable state (immutable data type)
&lt;ul&gt;
&lt;li&gt;Type with constant field&lt;/li&gt;
&lt;li&gt;Immutable class with readonly instance field&lt;/li&gt;
&lt;li&gt;Immutable structure (readonly structure)&lt;/li&gt;
&lt;li&gt;Immutable anonymous type&lt;/li&gt;
&lt;li&gt;Immutable tuple vs. mutable tuple
&lt;ul&gt;
&lt;li&gt;Construction and element name&lt;/li&gt;
&lt;li&gt;Deconstruction&lt;/li&gt;
&lt;li&gt;Tuple assignment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Immutable collection vs. readonly collection&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pure-function-7&quot;&gt;Pure function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Referential transparency and side effect free&lt;/li&gt;
&lt;li&gt;PureAttribute and code contracts&lt;/li&gt;
&lt;li&gt;Purity in .NET&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-asynchronous-function-7&quot;&gt;Asynchronous function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Task, Task&amp;lt;TResult&amp;gt; and asynchrony&lt;/li&gt;
&lt;li&gt;Named async function&lt;/li&gt;
&lt;li&gt;Awaitable-awaiter pattern&lt;/li&gt;
&lt;li&gt;Async state machine&lt;/li&gt;
&lt;li&gt;Generalized async return type and async method builder
&lt;ul&gt;
&lt;li&gt;ValueTask&amp;lt;TResult&amp;gt; and performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Runtime context capture&lt;/li&gt;
&lt;li&gt;Anonymous async function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/functional-csharp-pattern-matching-7&quot;&gt;Pattern matching&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Is expression&lt;/li&gt;
&lt;li&gt;Switch statement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;LINQ to Objects: Querying objects in memory&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-local-sequential-query-7&quot;&gt;Local Sequential LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Iteration pattern and foreach statement&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;EnumerableAssert utility&lt;/li&gt;
&lt;li&gt;foreach loop vs. for loop&lt;/li&gt;
&lt;li&gt;Non-generic sequence vs. generic sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LINQ to Objects queryable types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-operators-and-query-expressions-7&quot;&gt;LINQ to Objects standard queries and query expressions&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Return a new IEnumerable&amp;lt;T&amp;gt; sequence
&lt;ul&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType, where&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany, from, let, select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy, group, by, into&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, join, on, equals&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, join, into, on, equals&lt;/li&gt;
&lt;li&gt;Cross join: SelectMany, Join, from select, join, on, equals&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse, orderby, ascending, descending, into&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return a new collection
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return a single value
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queries in other languages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-generator-7&quot;&gt;Generator&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Implement iterator pattern&lt;/li&gt;
&lt;li&gt;Generate sequence and iterator&lt;/li&gt;
&lt;li&gt;Yield statement and generator&lt;/li&gt;
&lt;li&gt;Iterator and generator in other languages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation-7&quot;&gt;Deferred execution, lazy evaluation and eager Evaluation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deferred execution vs. immediate execution
&lt;ul&gt;
&lt;li&gt;Cold IEnumerable&amp;lt;T&amp;gt; vs. hot IEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-query-methods-implementation-7&quot;&gt;LINQ to Objects internals: Standard queries implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Argument check and deferred execution&lt;/li&gt;
&lt;li&gt;Return a new collection
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return a new IEnumerable&amp;lt;T&amp;gt; sequence
&lt;ul&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join: SelectMany, Join, GroupJoin&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return a single value
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-interactive-extensions-ix-7&quot;&gt;Microsoft Interactive Extensions (Ix): More powerful queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Returns a new IEnumerable&amp;lt;T&amp;gt; sequence
&lt;ul&gt;
&lt;li&gt;Generation: Defer, Create, Return, Repeat&lt;/li&gt;
&lt;li&gt;Filtering: IgnoreElements, DistinctUntilChanged&lt;/li&gt;
&lt;li&gt;Mapping: SelectMany, Scan, Expand&lt;/li&gt;
&lt;li&gt;Concatenation: Concat, StartWith&lt;/li&gt;
&lt;li&gt;Set: Distinct&lt;/li&gt;
&lt;li&gt;Partitioning: TakeLast, SkipLast&lt;/li&gt;
&lt;li&gt;Conversion: Hide&lt;/li&gt;
&lt;li&gt;Buffering: Buffer, Share, Publish, Memoize&lt;/li&gt;
&lt;li&gt;Exception: Throw, Catch, Finally, OnErrorResumeNext, Retry&lt;/li&gt;
&lt;li&gt;Imperative: If, Case, Using, While, DoWhile, Generate, For&lt;/li&gt;
&lt;li&gt;Iteration: Do&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns void
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns a single value
&lt;ul&gt;
&lt;li&gt;Aggregation: Min, Max, MinBy, MaxBy&lt;/li&gt;
&lt;li&gt;Quantifiers: isEmpty&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-objects-custom-query-methods-7&quot;&gt;Building custom queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Returns a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution)
&lt;ul&gt;
&lt;li&gt;Generation: Create, RandomInt32, RandomDouble, FromValue, FromValues, EmptyIfNull&lt;/li&gt;
&lt;li&gt;Filtering: Timeout&lt;/li&gt;
&lt;li&gt;Concatenation: Join, Append, Prepend, AppendTo, PrependTo&lt;/li&gt;
&lt;li&gt;Partitioning: Subsequence&lt;/li&gt;
&lt;li&gt;Exception: Catch, Retry&lt;/li&gt;
&lt;li&gt;Comparison: OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;List: Insert, Remove, RemoveAll, RemoveAt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns a new collection
&lt;ul&gt;
&lt;li&gt;Comparison: ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns a single value
&lt;ul&gt;
&lt;li&gt;List: IndexOf, LastIndexOf&lt;/li&gt;
&lt;li&gt;Aggregation: PercentileExclusive, PercentileInclusive, Percentile&lt;/li&gt;
&lt;li&gt;Quantifiers: IsNullOrEmpty, IsNotNullOrEmpty&lt;/li&gt;
&lt;li&gt;Comparison: Contains, SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns void
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;LINQ to XML: Querying XML&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-1-modeling-xml-7&quot;&gt;Modeling XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Imperative vs. declarative paradigm&lt;/li&gt;
&lt;li&gt;Types, conversions and operators&lt;/li&gt;
&lt;li&gt;Read and deserialize XML&lt;/li&gt;
&lt;li&gt;Serialize and write XML&lt;/li&gt;
&lt;li&gt;Deferred construction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-2-query-methods-7&quot;&gt;LINQ to XML standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;li&gt;Comparison&lt;/li&gt;
&lt;li&gt;More useful queries&lt;/li&gt;
&lt;li&gt;XPath&lt;/li&gt;
&lt;li&gt;Generate XPath expression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/linq-to-xml-3-manipulating-xml-7&quot;&gt;Manipulating XML&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Clone&lt;/li&gt;
&lt;li&gt;Add, replace, delete, update, and events&lt;/li&gt;
&lt;li&gt;Annotation&lt;/li&gt;
&lt;li&gt;Validate with XSD&lt;/li&gt;
&lt;li&gt;Transform&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Parallel LINQ: Querying objects in parallel&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-1-local-parallel-query-and-visualization-7&quot;&gt;Parallel LINQ query and visualization&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Parallel LINQ classes and methods&lt;/li&gt;
&lt;li&gt;Parallel query vs. sequential query&lt;/li&gt;
&lt;li&gt;Execute parallel query&lt;/li&gt;
&lt;li&gt;Visualize parallel query execution
&lt;ul&gt;
&lt;li&gt;Install and configure Concurrency Visualizer&lt;/li&gt;
&lt;li&gt;Visualize sequential and parallel LINQ queries&lt;/li&gt;
&lt;li&gt;Visualize chaining query methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-2-partitioning-7&quot;&gt;Parallel LINQ internals: data partitioning&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Partitioning algorithms and load balancing
&lt;ul&gt;
&lt;li&gt;Range partitioning&lt;/li&gt;
&lt;li&gt;Stripped partitioning&lt;/li&gt;
&lt;li&gt;Hash partitioning&lt;/li&gt;
&lt;li&gt;Chunk partitioning&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implement custom partitioner
&lt;ul&gt;
&lt;li&gt;Static partitioner&lt;/li&gt;
&lt;li&gt;Dynamic partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-3-query-methods-7&quot;&gt;Parallel LINQ standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Query settings
&lt;ul&gt;
&lt;li&gt;Cancellation&lt;/li&gt;
&lt;li&gt;Degree of parallelism&lt;/li&gt;
&lt;li&gt;Execution mode&lt;/li&gt;
&lt;li&gt;Merge the values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ordering
&lt;ul&gt;
&lt;li&gt;Control the order&lt;/li&gt;
&lt;li&gt;Order and correctness&lt;/li&gt;
&lt;li&gt;Orderable partitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregation
&lt;ul&gt;
&lt;li&gt;Commutativity, associativity and correctness&lt;/li&gt;
&lt;li&gt;Partition and merge&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/parallel-linq-4-performance-7&quot;&gt;Parallel query performance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sequential vs. parallel&lt;/li&gt;
&lt;li&gt;CPU bound vs. IO bound&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Entity Framework/Core and LINQ to Entities: Querying relational data&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-1-remote-query-7&quot;&gt;Remote LINQ query&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Entity Framework and Entity Framework Core&lt;/li&gt;
&lt;li&gt;SQL database&lt;/li&gt;
&lt;li&gt;Remote query vs. local query&lt;/li&gt;
&lt;li&gt;Function vs. expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping-7&quot;&gt;Modeling database: Object-Relational Mapping&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data types&lt;/li&gt;
&lt;li&gt;Database
&lt;ul&gt;
&lt;li&gt;Connection resiliency and execution strategy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Relationships
&lt;ul&gt;
&lt;li&gt;One-to-one&lt;/li&gt;
&lt;li&gt;One-to-many&lt;/li&gt;
&lt;li&gt;Many-to-many&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Views&lt;/li&gt;
&lt;li&gt;Stored procedures and functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries-7&quot;&gt;Logging and tracing LINQ to Entities queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Application side logging&lt;/li&gt;
&lt;li&gt;Database side tracing with Extended Events&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-4-query-methods-7&quot;&gt;LINQ to Entities standard queries&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Return a new IQueryable&amp;lt;T&amp;gt; source
&lt;ul&gt;
&lt;li&gt;Generation: DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join
&lt;ul&gt;
&lt;li&gt;Inner join: Join, SelectMany, GroupJoin, Select&lt;/li&gt;
&lt;li&gt;Outer join: GroupJoin, Select, SelectMany&lt;/li&gt;
&lt;li&gt;Cross join and self join: SelectMany, Join&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsQueryable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return a single value
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation-7&quot;&gt;LINQ to Entities internals: Query translation implementation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Code to LINQ expression tree
&lt;ul&gt;
&lt;li&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/li&gt;
&lt;li&gt;Queryable methods&lt;/li&gt;
&lt;li&gt;Build LINQ to Entities abstract syntax tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;.NET expression tree to database expression tree
&lt;ul&gt;
&lt;li&gt;Database query abstract syntax tree&lt;/li&gt;
&lt;li&gt;Compile LINQ expressions to database expressions&lt;/li&gt;
&lt;li&gt;Compile LINQ query method calls&lt;/li&gt;
&lt;li&gt;Compile .NET API calls&lt;/li&gt;
&lt;li&gt;Remote API call vs. local API call&lt;/li&gt;
&lt;li&gt;Compile database function call&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Database expression tree to SQL
&lt;ul&gt;
&lt;li&gt;SQL generator and SQL command&lt;/li&gt;
&lt;li&gt;Generate SQL from database expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading-7&quot;&gt;Loading query data&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deferred execution
&lt;ul&gt;
&lt;li&gt;Iterator pattern&lt;/li&gt;
&lt;li&gt;Lazy evaluation vs. eager evaluation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Explicit loading&lt;/li&gt;
&lt;li&gt;Eager loading&lt;/li&gt;
&lt;li&gt;Lazy loading
&lt;ul&gt;
&lt;li&gt;The N + 1 problem&lt;/li&gt;
&lt;li&gt;Disable lazy loading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions-7&quot;&gt;Manipulating relational data: Data change and transaction&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repository pattern and unit of work pattern&lt;/li&gt;
&lt;li&gt;Track entities and changes
&lt;ul&gt;
&lt;li&gt;Track entities&lt;/li&gt;
&lt;li&gt;Track entity changes and property changes&lt;/li&gt;
&lt;li&gt;Track relationship changes&lt;/li&gt;
&lt;li&gt;Enable and disable tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Change data
&lt;ul&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Delete&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Transaction
&lt;ul&gt;
&lt;li&gt;Transaction with connection resiliency and execution strategy&lt;/li&gt;
&lt;li&gt;EF/Core transaction&lt;/li&gt;
&lt;li&gt;ADO.NET transaction&lt;/li&gt;
&lt;li&gt;Transaction scope&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency-7&quot;&gt;Resolving optimistic concurrency&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Detect concurrent conflicts&lt;/li&gt;
&lt;li&gt;Resolve concurrent conflicts
&lt;ul&gt;
&lt;li&gt;Retain database values (database wins)&lt;/li&gt;
&lt;li&gt;Overwrite database values (client wins)&lt;/li&gt;
&lt;li&gt;Merge with database values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Save changes with concurrent conflict handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-9-performance-7&quot;&gt;Performance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Initialization
&lt;ul&gt;
&lt;li&gt;Provider initialization&lt;/li&gt;
&lt;li&gt;Database initialization&lt;/li&gt;
&lt;li&gt;Mapping views initialization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cache
&lt;ul&gt;
&lt;li&gt;Entity cache&lt;/li&gt;
&lt;li&gt;LINQ query translation cache&lt;/li&gt;
&lt;li&gt;SQL query plan cache&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Asynchrony
&lt;ul&gt;
&lt;li&gt;Asynchronous data queries and data changes&lt;/li&gt;
&lt;li&gt;Transactions and connection resiliency with asynchronous operations&lt;/li&gt;
&lt;li&gt;Asynchronous concurrent conflicts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Lambda Calculus via C#: The foundation of all functional programming&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;Fundamentals - Closure, Currying and Partial Application&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;About lambda calculus (λ-calculus)&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;li&gt;Currying and partial application&lt;/li&gt;
&lt;li&gt;Uncurry&lt;/li&gt;
&lt;li&gt;=&amp;gt; associativity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-2-fundamentals-lambda-expression-variables-reductions&quot;&gt;Fundamentals - Lambda Expression, Variables, Reductions&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lambda expression&lt;/li&gt;
&lt;li&gt;Bound and free variables&lt;/li&gt;
&lt;li&gt;Reductions
&lt;ul&gt;
&lt;li&gt;α-conversion / alpha-conversion&lt;/li&gt;
&lt;li&gt;β-reduction / beta-reduction&lt;/li&gt;
&lt;li&gt;η-conversion / eta-conversion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-3-fundamentals-function-composition&quot;&gt;Fundamentals - Function composition&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Function composition
&lt;ul&gt;
&lt;li&gt;Built-in operator in other languages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Properties
&lt;ul&gt;
&lt;li&gt;Associativity&lt;/li&gt;
&lt;li&gt;Unit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Encoding Church Booleans&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church encoding&lt;/li&gt;
&lt;li&gt;Church Booleans - True and False&lt;/li&gt;
&lt;li&gt;Unit test&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;Boolean Logic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;And&lt;/li&gt;
&lt;li&gt;Or&lt;/li&gt;
&lt;li&gt;Not&lt;/li&gt;
&lt;li&gt;Xor&lt;/li&gt;
&lt;li&gt;Conversion between Church Boolean and System.Boolean&lt;/li&gt;
&lt;li&gt;Unit Tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies&quot;&gt;If Logic, And Reduction Strategies&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The first If&lt;/li&gt;
&lt;li&gt;Reduction strategies
&lt;ul&gt;
&lt;li&gt;Normal order&lt;/li&gt;
&lt;li&gt;Applicative order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make If lazy&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals&quot;&gt;Encoding Church Numerals&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church numerals&lt;/li&gt;
&lt;li&gt;C# Implementation - starting from 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-8-church-numeral-arithmetic&quot;&gt;Church Numeral Arithmetic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Increase&lt;/li&gt;
&lt;li&gt;Add&lt;/li&gt;
&lt;li&gt;Decrease and subtract&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;Wrapping Church Numerals And Arithmetic&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Non-generic wrapper for Numeral&amp;lt;T&amp;gt;, and Increase&lt;/li&gt;
&lt;li&gt;Add&lt;/li&gt;
&lt;li&gt;Decrease and Subtract&lt;/li&gt;
&lt;li&gt;Multiply and Pow&lt;/li&gt;
&lt;li&gt;Divide?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-10-church-numeral-arithmetic-operators&quot;&gt;Church Numeral Arithmetic Operators&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operators&lt;/li&gt;
&lt;li&gt;Conversion between Church numeral (now _Numeral) and System.UInt32&lt;/li&gt;
&lt;li&gt;Compare _Numeral and System.UInt32&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;Predicates, And Divide&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Predicates&lt;/li&gt;
&lt;li&gt;Divide&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-12-church-numeral-comparison-operators&quot;&gt;Church Numeral Comparison Operators&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church Numeral Comparison Operators
&lt;ul&gt;
&lt;li&gt;C# object equality&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Encoding Church Pairs (2-Tuples) and Generic Church Booleans&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church pair (2-tuple)&lt;/li&gt;
&lt;li&gt;Generic Church Booleans
&lt;ul&gt;
&lt;li&gt;Back to Church Boolean - why not using generic Church Booleans from the beginning?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Currying and type inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-14-church-pair-2-tuple-and-church-numeral-decrease&quot;&gt;Church Pair (2-Tuple) and Church Numeral Decrease&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Shift a Church Pair (2-Tuple)&lt;/li&gt;
&lt;li&gt;Decrease a Church numeral&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-15-encoding-church-list-with-church-pair-and-null&quot;&gt;Encoding Church List with Church Pair, And Null&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Church pair as a Church list node&lt;/li&gt;
&lt;li&gt;Encoding Null, and IsNull predicate&lt;/li&gt;
&lt;li&gt;Church Boolean as Null&lt;/li&gt;
&lt;li&gt;The improved Next&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-16-encoding-church-list-with-2-church-pairs-as-a-node&quot;&gt;Encoding Church List with 2 Church Pairs as a Node&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IsNull and Null&lt;/li&gt;
&lt;li&gt;Create, Value, and Next&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-17-encoding-church-list-with-fold-aggregate-function&quot;&gt;Encoding Church List with Fold (Aggregate) Function&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ListNode and wrapper&lt;/li&gt;
&lt;li&gt;IsNull&lt;/li&gt;
&lt;li&gt;Create, value and Next&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number&quot;&gt;Encoding Signed Number&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create Signed number from Church numeral&lt;/li&gt;
&lt;li&gt;Format with 0&lt;/li&gt;
&lt;li&gt;Arithmetic&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-19-church-encoding-and-more&quot;&gt;Church Encoding, And More&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Summary of church encoding
&lt;ul&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;li&gt;Numeral&lt;/li&gt;
&lt;li&gt;Predicate&lt;/li&gt;
&lt;li&gt;Pair (2-tuple)&lt;/li&gt;
&lt;li&gt;List&lt;/li&gt;
&lt;li&gt;Signed number&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Encode, encode, and encode&amp;lt;
&lt;ul&gt;
&lt;li&gt;From signed number to complex integer and rational number&lt;/li&gt;
&lt;li&gt;From rational number to real number and complex number&lt;/li&gt;
&lt;li&gt;And much more/li&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-20-combinators&quot;&gt;Combinators&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I Combinator&lt;/li&gt;
&lt;li&gt;BCKW combinators&lt;/li&gt;
&lt;li&gt;ω combinator&lt;/li&gt;
&lt;li&gt;SKI combinators
&lt;ul&gt;
&lt;li&gt;Boolean in SKI, and type issue&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-21-ski-combinator-calculus&quot;&gt;SKI Combinator Calculus&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I Combinator&lt;/li&gt;
&lt;li&gt;BCKW combinators&lt;/li&gt;
&lt;li&gt;ω combinator&lt;/li&gt;
&lt;li&gt;Function composition&lt;/li&gt;
&lt;li&gt;Booleans&lt;/li&gt;
&lt;li&gt;Numerals&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-22-iota-combinator&quot;&gt;Iota Combinator and Jot Combinators&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Language with 1 element&lt;/li&gt;
&lt;li&gt;Completeness&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide&quot;&gt;Y Combinator, And Divide&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fix point&lt;/li&gt;
&lt;li&gt;Fixed point combinator&lt;/li&gt;
&lt;li&gt;Recursion
&lt;ul&gt;
&lt;li&gt;Example – Fibonacci&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DivideBy&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Category Theory via C#: The essentials and design of LINQ&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-1-fundamentals-category-object-and-morphism&quot;&gt;Fundamentals - Category, Object And Morphism&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Category and category laws&lt;/li&gt;
&lt;li&gt;The .NET category and morphism&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-2-monoid&quot;&gt;Monoid&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoid and monoid laws&lt;/li&gt;
&lt;li&gt;C#/.NET monoids
&lt;ul&gt;
&lt;li&gt;Void and Unit monoids&lt;/li&gt;
&lt;li&gt;More examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nullable&amp;lt;T&amp;gt; monoid&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-3-monoid-as-category&quot;&gt;Monoid as Category&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One monoid, one category&lt;/li&gt;
&lt;li&gt;Category laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-4-functor-and-ienumerable&quot;&gt;Functor And IEnumerable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functor and functor laws&lt;/li&gt;
&lt;li&gt;C#/.NET functors
&lt;ul&gt;
&lt;li&gt;Endofunctor&lt;/li&gt;
&lt;li&gt;Kind issue of C# language/CLR&lt;/li&gt;
&lt;li&gt;The built-in IEnumerable&amp;lt;&amp;gt; functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Functor pattern of LINQ&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt;, functor laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-5-more-functors-lazy-func-and-nullable&quot;&gt;More Functors: Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt; And Nullable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lazy&amp;lt;&amp;gt; functor&lt;/li&gt;
&lt;li&gt;Func&amp;lt;&amp;gt; functor
&lt;ul&gt;
&lt;li&gt;Fun&amp;lt; , &amp;gt; functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nullable&amp;lt;&amp;gt; functor&lt;/li&gt;
&lt;li&gt;Functor laws, laziness, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-6-functor-like-tuple-task-and-iqueryable&quot;&gt;Functor-like Tuple&amp;lt;&amp;gt;, Task&amp;lt;&amp;gt; And IQueryable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tuple&amp;lt;&amp;gt; is like a functor
&lt;ul&gt;
&lt;li&gt;Tuple&amp;lt; , &amp;gt; is also like a functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Laziness vs. eagerness&lt;/li&gt;
&lt;li&gt;Task&amp;lt;T&amp;gt; is like a functor too&lt;/li&gt;
&lt;li&gt;Purity vs. impurity
&lt;ul&gt;
&lt;li&gt;Purity and category theory&lt;/li&gt;
&lt;li&gt;Purity and .NET&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Purity, laziness and LINQ
&lt;ul&gt;
&lt;li&gt;Functor vs. functor-like&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IQueryable&amp;lt;&amp;gt; is also like a functor&lt;/li&gt;
&lt;li&gt;Hot task vs. cold task, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-7-natural-transformation&quot;&gt;Natural Transformation&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Natural transformation&lt;/li&gt;
&lt;li&gt;Natural transformations for LINQ&lt;/li&gt;
&lt;li&gt;More LINQ to Monads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-8-functor-category&quot;&gt;Functor Category&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functor Category&lt;/li&gt;
&lt;li&gt;Endofunctor category&lt;/li&gt;
&lt;li&gt;Monoid laws for endofunctor category, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-9-bifunctor&quot;&gt;Bifunctor&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bifunctor&lt;/li&gt;
&lt;li&gt;C#/.NET bifunctor&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-10-monoidal-category&quot;&gt;Monoidal Category&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoidal category&lt;/li&gt;
&lt;li&gt;DotNet category is monoidal category&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-11-monoidal-functor-and-ienumerable&quot;&gt;Monoidal Functor And IEnumerable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monoidal functor&lt;/li&gt;
&lt;li&gt;C#/.NET lax monoidal endofunctors&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; monoidal functor
&lt;ul&gt;
&lt;li&gt;N-arity selector for functor&lt;/li&gt;
&lt;li&gt;Binary vs. Apply&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monoidal functor and LINQ&lt;/li&gt;
&lt;li&gt;Applicative functor&lt;/li&gt;
&lt;li&gt;Applicative laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-12-more-monoidal-functors-lazy-func-and-nullable&quot;&gt;More Monoidal Functors: Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt; And Nullable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lazy&amp;lt;&amp;gt; monoidal functor&lt;/li&gt;
&lt;li&gt;Func&amp;lt;&amp;gt; monoidal functor&lt;/li&gt;
&lt;li&gt;Nullable&amp;lt;&amp;gt; monoidal functor&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-13-monoidal-functor-like-tuple-and-task&quot;&gt;Monoidal Functor-like Tuple&amp;lt;&amp;gt; And Task&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tuple&amp;lt;&amp;gt;: lack of laziness&lt;/li&gt;
&lt;li&gt;Task&amp;lt;&amp;gt;: lack of purity&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-14-monad-and-ienumerable&quot;&gt;Monad And IEnumerable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monad and monad laws&lt;/li&gt;
&lt;li&gt;C#/.NET monads&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; monad and SelectMany
&lt;ul&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is monoid&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is monoidal functor&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is functor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monad pattern of LINQ&lt;/li&gt;
&lt;li&gt;Monad laws, and unit test&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-15-ienumerable-monad-and-linq-selectmany-for-all&quot;&gt;IEnumerable&amp;lt;&amp;gt; Monad And LINQ: SelectMany For All&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Query methods implemented by SelectMany&lt;/li&gt;
&lt;li&gt;Query methods in LINQ syntax&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-16-more-monads-lazy-func-nullable-parallelquery-and-iobservale&quot;&gt;More Monads: Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt;, ParallelQuery&amp;lt;&amp;gt; And IObservale&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lazy&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Func&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Nullable&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;ParallelQuery&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;IObservable&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-17-monad-like-tuple-task-iqueryable-and-iqbservable&quot;&gt;Monad-like Tuple&amp;lt;&amp;gt;, Task&amp;lt;&amp;gt;, IQueryable&amp;lt;&amp;gt; And IQbservable&amp;lt;&amp;gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tuple&amp;lt;&amp;gt;: lack of laziness&lt;/li&gt;
&lt;li&gt;Task&amp;lt;&amp;gt;: lack of purity
&lt;ul&gt;
&lt;li&gt;Task&amp;lt;&amp;gt; and LINQ&lt;/li&gt;
&lt;li&gt;Non-generic Task&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IQueryable&amp;lt;&amp;gt; is like a monad&lt;/li&gt;
&lt;li&gt;IQbservable&amp;lt;&amp;gt; is also like a monad&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-18-more-monad-io-monad&quot;&gt;More Monad: IO&amp;lt;&amp;gt; Monad&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IO&amp;lt;T&amp;gt; and impurity&lt;/li&gt;
&lt;li&gt;IO&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Monad laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-19-more-monad-state-monad&quot;&gt;More Monad: State&amp;lt; , &amp;gt; Monad&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C#/.NET state machines&lt;/li&gt;
&lt;li&gt;State pattern in object-oriented programming&lt;/li&gt;
&lt;li&gt;State&amp;lt;&amp;gt; monad&lt;/li&gt;
&lt;li&gt;Monad laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-20-more-monad-reader-monad&quot;&gt;More Monad: Reader&amp;lt; , &amp;gt; Monad&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reader&amp;lt; , &amp;gt; Monad&lt;/li&gt;
&lt;li&gt;Monad laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-21-more-monad-writer-monad&quot;&gt;More Monad: Writer&amp;lt; , &amp;gt; Monad&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Writer&amp;lt; , &amp;gt; monad&lt;/li&gt;
&lt;li&gt;Monad laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-22-more-monad-continuation-monad&quot;&gt;More Monad: Continuation Monad&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Continuation and continuation-passing style&lt;/li&gt;
&lt;li&gt;Continuation monad&lt;/li&gt;
&lt;li&gt;Monad laws, and unit tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/category-theory-via-c-sharp-23-knowing-the-cost&quot;&gt;Performance&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functional and purely functional&lt;/li&gt;
&lt;li&gt;Cost of functional and monad&lt;/li&gt;
&lt;li&gt;Cost of lambda&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Linq.IndexRange: The package to enable C# 8.0 index and range featues for LINQ and IEnumerable&lt;T&gt; types</title><link>https://dixin.github.io/posts/linq-indexrange-the-package-to-enable-c-8-0-index-and-range-featues-for-linq-and-ienumerable-t-types/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-indexrange-the-package-to-enable-c-8-0-index-and-range-featues-for-linq-and-ienumerable-t-types/</guid><description>LINQ operators to enable C# 8.0 index and range new features working with LINQ queries and any type that implements `IEnumerable&lt;T&gt;`.</description><pubDate>Sun, 03 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;LINQ operators to enable C# 8.0 index and range new features working with LINQ queries and any type that implements &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;dotnet add package Linq.IndexRange&lt;/p&gt;
&lt;p&gt;var element = source1.ElementAt(index: `5);
var elements = source2.ElementsIn(range: 10..^10); // or Slice(10..^10)
var query1 = Enumerable.Range(10..20).Select().Where();
var query2 = (10..20).AsEnumerable().Select().Where();&lt;/p&gt;
&lt;p&gt;Proposed these APIs to .NET Core &lt;a href=&quot;https://github.com/dotnet/corefx/issues/35552&quot;&gt;dotnet/corefx/#35552&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;Index/range are &lt;strong&gt;language level&lt;/strong&gt; features. However, currently (v3.0.0-preview2/SDK 3.0.100-preview-010184), they&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;only work with array, not other types like &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;are compiled to array copy, apparently no deferred execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Rationale and usage&lt;/h4&gt;
&lt;p&gt;The goals of these LINQ APIs are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use index to locate an element in sequence.&lt;/li&gt;
&lt;li&gt;Use range to slice a sequence. The usage should be consistent with array, but with deferred execution.&lt;/li&gt;
&lt;li&gt;Use range to start fluent LINQ query.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This enables index and range &lt;strong&gt;langaguge features&lt;/strong&gt; to work with any type that implements &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;LINQ already has &lt;code&gt;ElementAt(int index)&lt;/code&gt; and &lt;code&gt;ElementAtOrDefault(int index)&lt;/code&gt; query operator. It would be natural to have a overload for &lt;code&gt;System.Index&lt;/code&gt;: &lt;code&gt;ElementAt(Index index)&lt;/code&gt; and &lt;code&gt;ElementAtOrDefault(Index index)&lt;/code&gt;, and a new method &lt;code&gt;ElementsIn(Range range)&lt;/code&gt; (or &lt;code&gt;Slice(Range)&lt;/code&gt;), so that LINQ can seamlessly work with C# 8.0:&lt;/p&gt;
&lt;p&gt;Index index = ...;
var element1 = source1.ElementAt(index);
var element2 = source2.ElementAtOrDefault(^5);
Range range = ...;
var slice1 = source3.ElementsIn(range); // or Slice(range)
var slice2 = source4.ElementsIn(2..^2) // or Slice(2..^2)
var slice2 = source5.ElementsIn(^10..); // or Slice(^10..)&lt;/p&gt;
&lt;p&gt;The following &lt;code&gt;Range&lt;/code&gt; overload and &lt;code&gt;AsEnumerable&lt;/code&gt; overload for &lt;code&gt;System.Range&lt;/code&gt; convert it to a sequence, so that LINQ query can be started fluently from c# range:&lt;/p&gt;
&lt;p&gt;var query1 = Enumerable.Range(10..).Select(...);
Range range = ...;
var query1 = range.AsEnumerable().Select(...);
var query2 = (10..20).AsEnumerable().Where(...);&lt;/p&gt;
&lt;h2&gt;APIs&lt;/h2&gt;
&lt;p&gt;For LINQ to Objects:&lt;/p&gt;
&lt;p&gt;namespace System.Linq
{
public static partial class EnumerableExtensions
{
public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

    public static IEnumerable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Range range) { throw null; }

    public static IEnumerable&amp;lt;TSource&amp;gt; Range&amp;lt;TSource&amp;gt;(Range range) { throw null; }

    public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this Range source) { throw null; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;For remote LINQ:&lt;/p&gt;
&lt;p&gt;namespace System.Linq
{
public static partial class QueryableExtensions
{
public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Index index) { throw null; }

    public static IQueryable&amp;lt;TSource&amp;gt; ElementsIn&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Range range) { throw null; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h4&gt;Implementation details (and pull request)&lt;/h4&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md&quot;&gt;API review process&lt;/a&gt; says PR should not be submitted before the API proposal is approved. So currently I implemented these APIs separately &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange&quot;&gt;https://github.com/Dixin/Linq.IndexRange&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Enumerable&lt;/code&gt;: &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/ElementAt.cs&quot;&gt;&lt;code&gt;ElementAt(Index)&lt;/code&gt;, &lt;code&gt;ElementAtOrDefault(Index)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Enumerable&lt;/code&gt;: &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/ElementsIn.cs&quot;&gt;&lt;code&gt;ElementsIn(Range)&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/Slice.cs&quot;&gt;&lt;code&gt;Slice(Range)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Enumerable&lt;/code&gt;: &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/Range.cs&quot;&gt;&lt;code&gt;Range(Range)&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/AsEnumerable.cs&quot;&gt;&lt;code&gt;AsEnumerable(Range)&lt;/code&gt;&lt;/a&gt;. They are the same conversion.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Queryable&lt;/code&gt;: &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange/QueryableExtensions.cs&quot;&gt;&lt;code&gt;ElementAt(Index)&lt;/code&gt;, &lt;code&gt;ElementAtOrDefault(Index)&lt;/code&gt;, &lt;code&gt;ElementsIn(Range)&lt;/code&gt;, &lt;code&gt;Slice(Range)&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So that anyone can start to use these APIs by adding a NuGet package:&lt;/p&gt;
&lt;p&gt;dotnet add package Linq.IndexRange&lt;/p&gt;
&lt;p&gt;If this proposal is doable, I can submit a PR quickly.&lt;/p&gt;
&lt;p&gt;The implementation of &lt;code&gt;ElementAt(Index)&lt;/code&gt;, &lt;code&gt;ElementAtOrDefault(Index)&lt;/code&gt; and &lt;code&gt;ElementsIn(Range)&lt;/code&gt; for &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt; is straightforward. They just create an expression tree. &lt;code&gt;ElementAt(Index)&lt;/code&gt; and &lt;code&gt;ElementAtOrDefault(Index)&lt;/code&gt; for &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;are straightforward as well.&lt;/p&gt;
&lt;h2&gt;Open questions&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;ElementsIn(Range)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Should it be called &lt;code&gt;Slice&lt;/code&gt;? Currently I implement it as &lt;code&gt;ElementsIn(Range range)&lt;/code&gt; to maintain the consistency with original &lt;code&gt;ElementAt(int index)&lt;/code&gt;, which could be natural for existing LINQ users.&lt;/p&gt;
&lt;p&gt;What should we do when the range&apos;s start index and/or end index go off the boundaries of source sequence? There are 2 options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow the behavior of range with array, and throw &lt;code&gt;OverflowException&lt;/code&gt;/&lt;code&gt;ArgumentEception&lt;/code&gt;/&lt;code&gt;ArgumentOutOfRangeException&lt;/code&gt;accordingly.&lt;/li&gt;
&lt;li&gt;Follow the behavior of current partitioning LINQ operators like &lt;code&gt;Skip&lt;/code&gt;/&lt;code&gt;Take&lt;/code&gt;/&lt;code&gt;SkipLast&lt;/code&gt;/&lt;code&gt;TakeLast&lt;/code&gt;, do not throw exception.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I implemented &lt;code&gt;ElementsIn(Range)&lt;/code&gt; following the array behavior. See &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange.Tests/ElementsInTests.cs&quot;&gt;unit tests of &lt;code&gt;ElementsIn&lt;/code&gt;&lt;/a&gt;. And I implemented &lt;code&gt;Slice&lt;/code&gt;following the LINQ behavior. See &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange.Tests/SliceTests.cs&quot;&gt;unit test of &lt;code&gt;Slice&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;ElementAt(Index)&lt;/code&gt; and &lt;code&gt;Queryable&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;As @bartdesmet mentioned in the comments, LINQ providers may have issues when they see &lt;code&gt;ElementAt&lt;/code&gt; having an &lt;code&gt;Index&lt;/code&gt;argument, etc. Should we have a new name for the operator instead of overload? For example, &lt;code&gt;At(Index)&lt;/code&gt; and &lt;code&gt;Slice(Range)&lt;/code&gt;?&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;Range&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;For &lt;code&gt;Range(Range)&lt;/code&gt; and &lt;code&gt;AsEnumerable(Range)&lt;/code&gt;, the question is: what does range&apos;s start index and end index mean, when the index is from the end? For example, &lt;code&gt;10..20&lt;/code&gt; can be easily converted to a sequence of 10, 11,12, ... 19, but how about &lt;code&gt;^20...^10&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;The easiest way is to disallow, and throw exception.&lt;/p&gt;
&lt;p&gt;My current implementation attempts to make it flexible. Regarding &lt;code&gt;Index&lt;/code&gt;&apos;s &lt;code&gt;Value&lt;/code&gt; can be from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;int.MaxValue&lt;/code&gt;, I assume a virtual &quot;full range&quot; &lt;code&gt;0..2147483648&lt;/code&gt;, and any &lt;code&gt;Range&lt;/code&gt; instance is a slice of that &quot;full range&quot;. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ranges &lt;code&gt;..&lt;/code&gt; and &lt;code&gt;0..&lt;/code&gt; and &lt;code&gt;..^0&lt;/code&gt; and &lt;code&gt;0..^0&lt;/code&gt; are converted to &quot;full sequence&quot; 0, 1, .. 2147483647&lt;/li&gt;
&lt;li&gt;Range &lt;code&gt;100..^47&lt;/code&gt; is converted to sequence 100, 101, .. 2147483600&lt;/li&gt;
&lt;li&gt;Range &lt;code&gt;^48..^40&lt;/code&gt; is converted to sequence 2147483600, 2147483601 .. 2147483607&lt;/li&gt;
&lt;li&gt;Range &lt;code&gt;10..10&lt;/code&gt; is converted to empty sequence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. See &lt;a href=&quot;https://github.com/Dixin/Linq.IndexRange/blob/master/Linq.IndexRange.Tests/RangeTests.cs&quot;&gt;unit tests of &lt;code&gt;Range(Range)&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;AsEnumerable&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Should this be provided to bridge range to LINQ? For me, at least &lt;code&gt;(10..20).AsEnumerable().Select().Where()&lt;/code&gt; is intuitive and natural.&lt;/p&gt;
</content:encoded></item><item><title>Upload any file to FTP server via C#</title><link>https://dixin.github.io/posts/upload-any-file-to-ftp-server-via-c/</link><guid isPermaLink="true">https://dixin.github.io/posts/upload-any-file-to-ftp-server-via-c/</guid><description>Microsoft has a C# example of uploading file to FTP server in MSDN .aspx</description><pubDate>Thu, 31 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Microsoft has a C# example of uploading file to FTP server in MSDN &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms229715(v=vs.100).aspx&quot;&gt;https://msdn.microsoft.com/en-us/library/ms229715(v=vs.100).aspx&lt;/a&gt; and Microsoft docs &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp&quot;&gt;https://docs.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Copy the contents of the file to the request stream.  
StreamReader sourceStream = new StreamReader(&quot;testfile.txt&quot;);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;

Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It uses StreamReader to read a string from a text file, then encode the string to bytes and upload.&lt;/p&gt;
&lt;p&gt;This document’s title has a general title “Upload Files with FTP&quot;. However, this approach with StreamReader only works with text file. If the above code is used to upload a binary file, like a picture, the uploaded file on FTP server becomes corrupted. The general options are:&lt;/p&gt;
&lt;p&gt;1. Call File.ReadAllBytes to read the bytes, and write to request stream:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;byte[] fileContents = File.ReadAllBytes(filePath);
using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(fileContents, 0, fileContents.Length);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2. Use FileStream to read the file, and copy the file stream to request stream:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;FtpStatusCode&amp;gt; FtpUploadAsync(string uri, string userName, string password, string filePath)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.Credentials = new NetworkCredential(userName, password);
    // request.UsePassive is true by default.

    using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    using (Stream requestStream = request.GetRequestStream())
    {
        await fileStream.CopyToAsync(requestStream);
    }

    using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
    {
        return response.StatusCode;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3. Use WebClient, which wraps all the above work flow:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task FtpUploadAsync(string uri, string userName, string password, string filePath)
{
    using (WebClient webClient = new WebClient())
    {
        webClient.Credentials = new NetworkCredential(userName, password);
        await webClient.UploadFileTaskAsync(uri, WebRequestMethods.Ftp.UploadFile, filePath);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Setup passive FTP server in Azure virtual machine</title><link>https://dixin.github.io/posts/setup-passive-ftp-server-in-azure-virtual-machine/</link><guid isPermaLink="true">https://dixin.github.io/posts/setup-passive-ftp-server-in-azure-virtual-machine/</guid><description>This article demonstrates how to setup a passive FTP server in a Azure virtual machine running Windows.</description><pubDate>Tue, 29 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This article demonstrates how to setup a passive FTP server in a Azure virtual machine running Windows.&lt;/p&gt;
&lt;h2&gt;Create virtual machine on Azure&lt;/h2&gt;
&lt;p&gt;Use Azure account to log on to the Azure portal: &lt;a href=&quot;https://portal.azure.com&quot;&gt;https://portal.azure.com&lt;/a&gt;. A free Azure account and be created from &lt;a href=&quot;https://azure.microsoft.com/en-us/free/&quot;&gt;https://azure.microsoft.com/en-us/free/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the Azure portal, click ”Create a resource” to create a “Windows Server 2016 VM”:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Follow the “Create virtual machine”wizard to specify the information, including location, size, auto-shutdown, etc. Review the price, if it is ok, click “Create”.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When it is done, a bunch of resources will be created, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a virtual machine and a diagnostics extension&lt;/li&gt;
&lt;li&gt;a storage account and a disk,&lt;/li&gt;
&lt;li&gt;a network interface, a network security group, a public IP address, and a virtual network&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup FTP server in virtual machine&lt;/h2&gt;
&lt;p&gt;Go to the virtual machine’s blade, click “Connect” to log on to the virtual machine through remote desktop. Then install a FTP server, like IIS, or FileZilla Server from &lt;a href=&quot;https://filezilla-project.org/download.php?type=server&quot;&gt;https://filezilla-project.org/download.php?type=server&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To make passive mode work, the external IP address should be specified for the FTP server. In Azure portal, the external IP address can be copied from the virtual machine’s blade, or the public IP address’ blade. Also manually specify the port range for passive mode:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup firewall and virtual network&lt;/h2&gt;
&lt;p&gt;In Windows, go to “Windows firewall with advanced security” console, create a inbound rule to allow TCP on port 21, and a inbound rule to allow the above port range:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to portal, open the network security group’s blade, add the same inbound rukes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup_19D9/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If a custom domain should be used for this FTP server, add a A record to the domain, with the victual machine’s external IP address.&lt;/p&gt;
&lt;h2&gt;Verify with a FTP client&lt;/h2&gt;
&lt;p&gt;Now use a FTP client, like FileZilla client, to connect with the external IP address or custom domain:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Status: Resolving address of dixineastasia.eastasia.cloudapp.azure.com Status: Connecting to 52.175.15.132:21... Status: Connection established, waiting for welcome message... Status: Insecure server, it does not support FTP over TLS. Status: Logged in Status: Retrieving directory listing... Status: Directory listing of &quot;/&quot; successful Status: Resolving address of dixineastasia.eastasia.cloudapp.azure.com Status: Connecting to 52.175.15.132:21... Status: Connection established, waiting for welcome message... Status: Insecure server, it does not support FTP over TLS. Status: Logged in Status: Retrieving directory listing... Status: Directory listing of &quot;/&quot; successful Status: Connection closed by server&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Build custom Windows 10 PE</title><link>https://dixin.github.io/posts/build-custom-windows-10-pe/</link><guid isPermaLink="true">https://dixin.github.io/posts/build-custom-windows-10-pe/</guid><description>Windows PE (WinPE) is a small version of Windows, which can be used to boot up computers from CD or USB disk drive. It is very useful to deploy or repair the desktop or server edition of Windows. For</description><pubDate>Mon, 14 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Windows PE (WinPE) is a small version of Windows, which can be used to boot up computers from CD or USB disk drive. It is very useful to deploy or repair the desktop or server edition of Windows. For many years I have tried many options to build a WinPE image and create a bootable media, including &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/winpe-intro&quot;&gt;the Microsoft official approach&lt;/a&gt;. The easiest way I found, is to use a third party tool called “&lt;a href=&quot;http://win10se.cwcodes.net/&quot;&gt;Win10PE SE project&lt;/a&gt;”. I am sharing this tool with a post, because it is not easy to be found when searching WinPE related keywords.&lt;/p&gt;
&lt;p&gt;Win10PE SE can be downloaded from: &lt;a href=&quot;http://win10se.cwcodes.net/Compressed/index.php&quot;&gt;http://win10se.cwcodes.net/Compressed/index.php&lt;/a&gt;. It is a zip package, so just unzip and run. It can load Windows installer files from your &lt;a href=&quot;https://www.microsoft.com/en-us/software-download/windows10&quot;&gt;latest genuine Windows 10 ISO&lt;/a&gt;, and build a Windows PE ISO file, with tons of customization options:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It can also add Chinese support and Chinese ISO to WinPE, which is extremely helpful for me:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It can add third party free tools to WinPE, like Total Commander, Firefox, etc.:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Build-custom-Windows-10-PE_10F27/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you are done with customization (or just use the default), click “Play” button, it will build a WinPE.iso file in the specified directory. Then you can use tools like &lt;a href=&quot;https://rufus.akeo.ie/&quot;&gt;Rufus&lt;/a&gt; to make a bootable USB disk drive. Have fun!&lt;/p&gt;
</content:encoded></item><item><title>Run Hyper-V and VMware virtual machines on Windows 10</title><link>https://dixin.github.io/posts/run-hyper-v-and-vmware-virtual-machines-on-windows-10/</link><guid isPermaLink="true">https://dixin.github.io/posts/run-hyper-v-and-vmware-virtual-machines-on-windows-10/</guid><description>I use Windows’ Hyper-V to run virtual machines for long time. Recently I need to run a VMware virtual machine to test something. I installed VMware Player, which is free for non-commercial usage. Howe</description><pubDate>Mon, 14 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I use Windows’ Hyper-V to run virtual machines for long time. Recently I need to run a VMware virtual machine to test something. I installed VMware Player, which is free for non-commercial usage. However, the virtual machine cannot started, with an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;VMware Player and Device/Credential Guard are not compatible. VMware Player can be run after disabling Device/Credential Guard. Please visit &lt;a href=&quot;http://www.wmware.com/go/turnoff_CG_DG&quot;&gt;http://www.wmware.com/go/turnoff_CG_DG&lt;/a&gt; for more details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The link will redirect you to a document with many steps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Disable the group policy setting that was used to enable Credential Guard.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the host operating system, click S&lt;strong&gt;tart&lt;/strong&gt; &amp;gt; &lt;strong&gt;Run&lt;/strong&gt;, type gpedit.msc, and click &lt;strong&gt;Ok.&lt;/strong&gt; The Local group Policy Editor opens.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Local Computer Policy&lt;/strong&gt; &amp;gt; &lt;strong&gt;Computer Configuration&lt;/strong&gt; &amp;gt; &lt;strong&gt;Administrative Templates &amp;gt; System&lt;/strong&gt; &amp;gt; &lt;strong&gt;Device Guard&lt;/strong&gt; &amp;gt; &lt;strong&gt;Turn on Virtualization Based Security&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Disabled&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;strong&gt;Control Panel&lt;/strong&gt; &amp;gt; &lt;strong&gt;Uninstall a Program&lt;/strong&gt; &amp;gt; &lt;strong&gt;Turn Windows features on or off to turn off Hyper-V&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &lt;strong&gt;Do not restart&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete the related EFI variables by launching a command prompt on the host machine using an Administrator account and run these commands: mountvol X: /s copy %WINDIR%\System32\SecConfig.efi X:\EFI\Microsoft\Boot\SecConfig.efi /Y bcdedit /create {0cb3b571-2f2e-4343-a879-d86a476d7215} /d &quot;DebugTool&quot; /application osloader bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} path &quot;\EFI\Microsoft\Boot\SecConfig.efi&quot; bcdedit /set {bootmgr} bootsequence {0cb3b571-2f2e-4343-a879-d86a476d7215} bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} loadoptions DISABLE-LSA-ISO,DISABLE-VBS bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} device partition=X: mountvol X: /d &lt;strong&gt;Note&lt;/strong&gt;: Ensure X is an unused drive, else change to another drive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restart the host.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Accept the prompt on the boot screen to disable Device Guard or Credential Guard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Actually, this is a conflict that can be simply resolved by temporarily disabling Hyper-V hypervisor:&lt;/p&gt;
&lt;p&gt;bcdedit /set hypervisorlaunchtype off&lt;/p&gt;
&lt;p&gt;Restart is required. Apparently, the side effect is that Hyper-V virtual machines cannot be started after this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And so is Docker:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/fe3eba9eac73_13F83/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To get Hyper-V back, just turn its hypervisor back on:&lt;/p&gt;
&lt;p&gt;bcdedit /set hypervisorlaunchtype auto&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (23) Performance</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-23-knowing-the-cost/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-23-knowing-the-cost/</guid><description>In functional programming, there are many powerful tools and patterns, like lambda expression, purity, deferred execution, immutability, fluent LINQ query composition, … But everything has a cost. As</description><pubDate>Mon, 24 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;In functional programming, there are many powerful tools and patterns, like lambda expression, purity, deferred execution, immutability, fluent LINQ query composition, … But everything has a cost. As &lt;a href=&quot;http://en.wikiquote.org/wiki/Alan_Perlis&quot;&gt;Alan Perlis&lt;/a&gt; &lt;a href=&quot;http://en.wikiquote.org/wiki/Alan_Perlis&quot;&gt;said&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LISP programmers know the value of everything and the cost of nothing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For C#/.NET, the major cost of functional programming paradigm is performance. A very simple example is immutable typing. If a Product entity with many properties are designed to be an immutable type, then updating a ListPrice property requires constructing a new Product entity and copying all the other properties, which is a performance overhead.&lt;/p&gt;
&lt;h2&gt;Functional and purely functional&lt;/h2&gt;
&lt;h3&gt;Sort array&lt;/h3&gt;
&lt;p&gt;The built-in LINQ query methods for IEnumerable&amp;lt;T&amp;gt;, are implemented in imperative algorithms for a lower performance cost. Take the sorting method as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
{
    [Pure]
    public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;
        (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, this API itself is functional, fluent, deferred, and higher-order so that lambda expression can be used for great convenience, and most important, it is pure. Calling OrderBy has no side effect. When when pulling the returned IOrderedEnumerable&amp;lt;TSource&amp;gt;, this is what happens internally:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The source, an IEnumerable&amp;lt;TSource&amp;gt;, is converted to a Buffer&amp;lt;TSource&amp;gt;, which is just a wrapper of TSource[] array.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Quicksort&quot;&gt;Quick sort&lt;/a&gt; algorithm is applied to that wrapped TSource[] array.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the core implementation of OrderBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    internal abstract class EnumerableSorter&amp;lt;TElement&amp;gt;
    {
        internal abstract void ComputeKeys(TElement[] elements, int count);

        internal abstract int CompareKeys(int index1, int index2);

        internal int[] Sort(TElement[] elements, int count)
        {
            this.ComputeKeys(elements, count);
            int[] map = new int[count];
            for (int i = 0; i &amp;lt; count; i++)
            {
                map[i] = i;
            }

            this.QuickSort(map, 0, count - 1);
            return map;
        }

        private void QuickSort(int[] map, int left, int right)
        {
            do
            {
                int i = left;
                int j = right;
                int x = map[i + ((j - i) &amp;gt;&amp;gt; 1)];
                do
                {
                    while (i &amp;lt; map.Length &amp;amp;&amp;amp; this.CompareKeys(x, map[i]) &amp;gt; 0)
                    {
                        i++;
                    }

                    while (j &amp;gt;= 0 &amp;amp;&amp;amp; this.CompareKeys(x, map[j]) &amp;lt; 0)
                    {
                        j--;
                    }

                    if (i &amp;gt; j)
                    {
                        break;
                    }

                    if (i &amp;lt; j)
                    {
                        int temp = map[i];
                        map[i] = map[j];
                        map[j] = temp;
                    }

                    i++;
                    j--;
                } while (i &amp;lt;= j);

                if (j - left &amp;lt;= right - i)
                {
                    if (left &amp;lt; j)
                    {
                        this.QuickSort(map, left, j);
                    }

                    left = i;
                }
                else
                {
                    if (i &amp;lt; right)
                    {
                        this.QuickSort(map, i, right);
                    }

                    right = j;
                }
            } while (left &amp;lt; right);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OrderBy, OrderByDescending, ThenBy all calls above QuickSort, which is completely imperative, for the lowest performance overhead.&lt;/p&gt;
&lt;p&gt;If above quick sort is implemented in purely functional manner, it will be like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;T&amp;gt; QuickSort&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source, Comparer&amp;lt;T&amp;gt; comparer = null)
    {
        if (!source.Any())
        {
            return source; // End of recursion.
        }

        comparer = comparer ?? Comparer&amp;lt;T&amp;gt;.Default;
        T head = source.First();
        IEnumerable&amp;lt;T&amp;gt; tail = source.Skip(1);
        IEnumerable&amp;lt;T&amp;gt; smallerThanHead = (from value in tail
                                            where comparer.Compare(value, head) &amp;lt;= 0
                                            select value).QuickSort();
        IEnumerable&amp;lt;T&amp;gt; greaterThanHead = (from value in tail
                                            where comparer.Compare(value, head) &amp;gt; 0
                                            select value).QuickSort();
        return smallerThanHead.Concat(head.Enumerable()).Concat(greaterThanHead);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET, there are other built-in sorting functions, like Array.Sort. The following code roughly demonstrates its implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Array
{
    public static void Sort&amp;lt;T&amp;gt;(T[] array, int index, int length, IComparer&amp;lt;T&amp;gt; comparer)
    {
        if (length &amp;lt;= 1)
        {
            return;
        }

        if (comparer == null || comparer == Comparer&amp;lt;T&amp;gt;.Default)
        {
            if (TrySZSort(array, null, index, index + length - 1))
            {
                return;
            }

            if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
            {
                GenericArraySortHelper&amp;lt;T&amp;gt;.IntrospectiveSort(array, index, length);
            }
            else
            {
                GenericArraySortHelper&amp;lt;T&amp;gt;.DepthLimitedQuickSort(array, index, length + index - 1, 32);
            }
        }
        else
        {
            if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
            {
                ArraySortHelper&amp;lt;T&amp;gt;.IntrospectiveSort(array, index, length, comparer);
            }
            else
            {
                ArraySortHelper&amp;lt;T&amp;gt;.DepthLimitedQuickSort(array, index, length + index - 1, comparer, 32);
            }
        }
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern bool TrySZSort(Array keys, Array items, int left, int right);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, the LINQ to Objects chapter has implemented an OrderBy query method with an OrderedSequence class, which is just for demonstration purpose. Now, the above 4 C# functions’ performance of sorting array will be compared.&lt;/p&gt;
&lt;h3&gt;Prepare to test&lt;/h3&gt;
&lt;p&gt;First some help functions are needed. The following ForEach is from the EnumerableX class in the LINQ to Objects chapter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableX
{
    public static void ForEach&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source)
    {
        foreach (T value in source)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following Stopwatch helper methods will be used to call methods repeatedly to measure the performance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static class StopwatchHelper
{
    public const int DefaultCount = 100;

    private static readonly Stopwatch DefaultStopwatch = new Stopwatch();

    public static long Run(this Action action, int count = DefaultCount, Stopwatch stopwatch = null)
    {
        stopwatch = stopwatch ?? DefaultStopwatch;
        stopwatch.Reset();
        action(); // Warm up.
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        stopwatch.Start();

        for (int index = 0; index &amp;lt; count; index++)
        {
            action();
        }

        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }

    public static long RunEach&amp;lt;T&amp;gt;
        (this IEnumerable&amp;lt;T&amp;gt; args, Func&amp;lt;T, T&amp;gt; action, int count = DefaultCount, Stopwatch stopwatch = null) =&amp;gt;
            Run(() =&amp;gt; args.ForEach(arg =&amp;gt; action(arg)), count);

    public static long RunEach&amp;lt;T1, T2&amp;gt;
        (this IEnumerable&amp;lt;IEnumerable&amp;lt;T1&amp;gt;&amp;gt; args1,
        Func&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, Func&amp;lt;T1, T2&amp;gt;, IEnumerable&amp;lt;T1&amp;gt;&amp;gt; action,
        Func&amp;lt;T1, T2&amp;gt; arg2,
        int count = DefaultCount,
        Stopwatch stopwatch = null)
            =&amp;gt; Run(() =&amp;gt; args1.ForEach(arg1 =&amp;gt; action(arg1, arg2).ForEach()), count);

    public static long Run&amp;lt;T&amp;gt;(this T arg, Func&amp;lt;T, T&amp;gt; action, int count = DefaultCount, Stopwatch stopwatch = null) =&amp;gt;
        Run(() =&amp;gt; action(arg), count);

    public static long Run&amp;lt;T1, T2&amp;gt;
        (this IEnumerable&amp;lt;T1&amp;gt; arg1,
        Func&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, Func&amp;lt;T1, T2&amp;gt;, IEnumerable&amp;lt;T1&amp;gt;&amp;gt; action,
        Func&amp;lt;T1, T2&amp;gt; arg2,
        int count = DefaultCount,
        Stopwatch stopwatch = null)
            =&amp;gt; Run(() =&amp;gt; action(arg1, arg2).ForEach(), count);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The performance tests will be done by sorting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Int32 (primitive value type) array&lt;/li&gt;
&lt;li&gt;String, (primitive reference type) array (To get random strings, Guid can be used.)&lt;/li&gt;
&lt;li&gt;Struct (custom value type) array&lt;/li&gt;
&lt;li&gt;Class (custom reference type) array&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So these functions are created to generate random arrays:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class ArrayHelper
{
    public static int[][] RandomArrays(int minValue, int maxValue, int minLength, int maxLength, int count)
        =&amp;gt; Enumerable
            .Range(0, count)
            .Select(_ =&amp;gt; RandomArray(minValue, maxValue, minLength, maxLength))
            .ToArray();

    public static int[] RandomArray(int minValue, int maxValue, int minLength, int maxLength)
    {
        Random random = new Random();
        return EnumerableX
            .RandomInt32(minValue, maxValue, random).Take(random.Next(minLength, maxLength))
            .ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EnumerableX.Random is defined in the LINQ to Objects chapter to generate a sequence of random int values.&lt;/p&gt;
&lt;p&gt;A struct and a class has to be created too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PersonReferenceType : IComparable&amp;lt;PersonReferenceType&amp;gt;
{
    public string Name { [Pure] get; private set; }

    public int Age { [Pure] get; private set; }

    public string Description { [Pure] get; private set; }

    [Pure]
    public int CompareTo(PersonReferenceType other)
    {
        int nameCompare = string.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
        return nameCompare != 0 ? nameCompare : this.Age.CompareTo(other.Age);
    }

    private static readonly string longString =
        Enumerable.Range(0, 10000).Select(_ =&amp;gt; Guid.NewGuid().ToString()).Aggregate(string.Concat);

    private static readonly Random random = new Random();

    [Pure]
    public static IEnumerable&amp;lt;PersonReferenceType&amp;gt; Random
        (int count) =&amp;gt; 
            Enumerable.Range(1, count).Select(_ =&amp;gt; new PersonReferenceType()
                {
                    Name = Guid.NewGuid().ToString(),
                    Age = random.Next(0, 100),
                    Description = longString
                });
}

public struct PersonValueType : IComparable&amp;lt;PersonValueType&amp;gt;
{
    public string Name { [Pure] get; private set; }

    public int Age { [Pure] get; private set; }
         
    public string Description { [Pure] get; private set; }

    [Pure]
    public int CompareTo(PersonValueType other)
    {
        int nameCompare = string.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
        return nameCompare != 0 ? nameCompare : this.Age.CompareTo(other.Age);
    }

    private static readonly string longString =
        Enumerable.Range(0, 10000).Select(_ =&amp;gt; Guid.NewGuid().ToString()).Aggregate(string.Concat);

    private static readonly Random random = new Random();

    [Pure]
    public static IEnumerable&amp;lt;PersonValueType&amp;gt; Random
        (int count) =&amp;gt;
            Enumerable.Range(1, count).Select(_ =&amp;gt; new PersonValueType()
            {
                Name = Guid.NewGuid().ToString(),
                Age = random.Next(0, 100),
                Description = longString
            });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Performance tests&lt;/h3&gt;
&lt;p&gt;Above 4 kinds of sorting will be compared:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Array.Sort: Imperative API with imperative implementation&lt;/li&gt;
&lt;li&gt;Enumerable.OrderBy: Functional API with imperative implementation and imperative optimization&lt;/li&gt;
&lt;li&gt;EnumerableExtensions.OrderBy: Functional API with imperative implementation without optimization&lt;/li&gt;
&lt;li&gt;EnumerableExtensions.QuickSort: Functional API with functional implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;using CustomLinq = Dixin.Linq.LinqToObjects.EnumerableExtensions;
    
// Impure.
internal static partial class Sort
{
    internal static T[] ArraySort&amp;lt;T&amp;gt;(T[] array)
    {
        Array.Sort(array);
        return array;
    }

    internal static T[] LinqOrderBy&amp;lt;T&amp;gt;(T[] array) =&amp;gt; array.OrderBy(value =&amp;gt; value).ToArray();

    internal static T[] CustomLinqOrderBy&amp;lt;T&amp;gt;(T[] array) =&amp;gt; CustomLinq.OrderBy(array, value =&amp;gt; value).ToArray();

    internal static T[] FunctionalQuickSort&amp;lt;T&amp;gt;(T[] array) =&amp;gt; array.QuickSort().ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
internal static partial class Sort
{
    internal static void Int32Array()
    {
        int[][] arrays1 = ArrayHelper.RandomArrays(int.MinValue, int.MaxValue, 0, 100, 100);
        int[][] arrays2 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        int[][] arrays3 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        int[][] arrays4 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        Trace.WriteLine($&quot;{nameof(ArraySort)}: {arrays1.RunEach(ArraySort)}&quot;);
        Trace.WriteLine($&quot;{nameof(LinqOrderBy)}: {arrays2.RunEach(LinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(CustomLinqOrderBy)}: {arrays4.RunEach(CustomLinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(FunctionalQuickSort)}: {arrays3.RunEach(FunctionalQuickSort)}&quot;);
    }

    internal static void StringArray()
    {
        string[] array1 = Enumerable.Range(0, 100).Select(_ =&amp;gt; Guid.NewGuid().ToString()).ToArray();
        string[] array2 = array1.ToArray(); // Copy.
        string[] array3 = array1.ToArray(); // Copy.
        string[] array4 = array1.ToArray(); // Copy.
        Trace.WriteLine($&quot;{nameof(ArraySort)}: {array1.Run(ArraySort)}&quot;);
        Trace.WriteLine($&quot;{nameof(LinqOrderBy)}: {array2.Run(LinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(CustomLinqOrderBy)}: {array4.Run(CustomLinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(FunctionalQuickSort)}: {array3.Run(FunctionalQuickSort)}&quot;);
    }

    internal static void ValueTypeArray()
    {
        PersonValueType[] array1 = PersonValueType.Random(100).ToArray();
        PersonValueType[] array2 = array1.ToArray(); // Copy.
        PersonValueType[] array3 = array1.ToArray(); // Copy.
        PersonValueType[] array4 = array1.ToArray(); // Copy.
        Trace.WriteLine($&quot;{nameof(ArraySort)}: {array1.Run(ArraySort)}&quot;);
        Trace.WriteLine($&quot;{nameof(LinqOrderBy)}: {array2.Run(LinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(CustomLinqOrderBy)}: {array4.Run(CustomLinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(FunctionalQuickSort)}: {array3.Run(FunctionalQuickSort)}&quot;);
    }

    internal static void ReferenceTypeArray()
    {
        PersonReferenceType[] array1 = PersonReferenceType.Random(100).ToArray();
        PersonReferenceType[] array2 = array1.ToArray(); // Copy.
        PersonReferenceType[] array3 = array1.ToArray(); // Copy.
        PersonReferenceType[] array4 = array1.ToArray(); // Copy.
        Trace.WriteLine($&quot;{nameof(ArraySort)}: {array1.Run(ArraySort)}&quot;);
        Trace.WriteLine($&quot;{nameof(LinqOrderBy)}: {array2.Run(LinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(CustomLinqOrderBy)}: {array4.Run(CustomLinqOrderBy)}&quot;);
        Trace.WriteLine($&quot;{nameof(FunctionalQuickSort)}: {array3.Run(FunctionalQuickSort)}&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying these 4 functions (Release build, optimize code, x64) gives following numbers on a PC:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;790&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;234&quot;&amp;gt;(Millisecond, the smaller the better)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;ArraySort&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;LinqOrderBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;171&quot;&amp;gt;CustomLinqOrderBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;161&quot;&amp;gt;FunctionalQuickSort&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;234&quot;&amp;gt;Sort.Int32Array&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;44&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;171&quot;&amp;gt;214&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;161&quot;&amp;gt;6195&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;234&quot;&amp;gt;Sort.StringArray&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;7&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;11&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;171&quot;&amp;gt;14&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;161&quot;&amp;gt;891&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;234&quot;&amp;gt;Sort.ValueTypeArray&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;6&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;171&quot;&amp;gt;8&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;161&quot;&amp;gt;664&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;234&quot;&amp;gt;Sort.ReferenceTypeArray&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;112&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;120&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;171&quot;&amp;gt;6&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;161&quot;&amp;gt;424&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;FunctionalQuickSort function demonstrates the significant performance cost of functional paradigm for sorting array in C#/.NET.&lt;/p&gt;
&lt;h2&gt;Cost of functional and monad&lt;/h2&gt;
&lt;h3&gt;Filter IEnumerable&amp;lt;T&amp;gt;&lt;/h3&gt;
&lt;p&gt;Filtering an IEnumerable&amp;lt;T&amp;gt; can be done in several different ways:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
internal static partial class Filter
{
    [Pure]
    internal static T[] EagerForEach&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; source, Func&amp;lt;T, bool&amp;gt; predicate)
    {
        T[] result = new T[4];
        int count = 0;
        foreach (T value in source)
        {
            if (predicate(value))
            {
                if (result.Length == count)
                {
                    T[] newValues = new T[checked(count * 2)];
                    Array.Copy(result, 0, newValues, 0, count);
                    result = newValues;
                }

                result[count] = value;
                count++;
            }
        }

        return result;
    }

    [Pure]
    internal static IEnumerable&amp;lt;T&amp;gt; LazyForEach&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; source, Func&amp;lt;T, bool&amp;gt; predicate)
    {
        foreach (T value in source)
        {
            if (predicate(value))
            {
                yield return value;
            }
        }
    }

    [Pure]
    internal static IEnumerable&amp;lt;T&amp;gt; Linq&amp;lt;T&amp;gt;
        (IEnumerable&amp;lt;T&amp;gt; source, Func&amp;lt;T, bool&amp;gt; predicate)
            =&amp;gt; from value in source
                where predicate(value)
                select value;

    [Pure]
    internal static IEnumerable&amp;lt;T&amp;gt; Monad&amp;lt;T&amp;gt;
        (IEnumerable&amp;lt;T&amp;gt; source, Func&amp;lt;T, bool&amp;gt; predicate)
            =&amp;gt; from value in source
                from result in predicate(value) ? Enumerable.Empty&amp;lt;T&amp;gt;() : value.Enumerable()
                select result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first EagerForEach function uses the same algorithm as System.Linq. Buffer&amp;lt;TElement&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Performance tests&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
internal static partial class Filter
{
    internal static void Int32Sequence()
    {
        IEnumerable&amp;lt;int&amp;gt;[] arrays1 = ArrayHelper.RandomArrays(int.MinValue, int.MaxValue, 0, 100, 100);
        IEnumerable&amp;lt;int&amp;gt;[] arrays2 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        IEnumerable&amp;lt;int&amp;gt;[] arrays3 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        IEnumerable&amp;lt;int&amp;gt;[] arrays4 = arrays1.Select(array =&amp;gt; array.ToArray()).ToArray(); // Copy.
        Func&amp;lt;int, bool&amp;gt; predicate = value =&amp;gt; value &amp;gt; 0;
        Trace.WriteLine($&quot;{nameof(Linq)}: {arrays1.RunEach(Linq, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(EagerForEach)}: {arrays2.RunEach(EagerForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(LazyForEach)}: {arrays3.RunEach(LazyForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(Monad)}: {arrays4.RunEach(Monad, predicate)}&quot;);
    }

    internal static void StringSequence()
    {
        IEnumerable&amp;lt;string&amp;gt; array1 = Enumerable.Range(0, 1000).Select(_ =&amp;gt; Guid.NewGuid().ToString()).ToArray();
        IEnumerable&amp;lt;string&amp;gt; array2 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;string&amp;gt; array3 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;string&amp;gt; array4 = array1.ToArray(); // Copy.
        Func&amp;lt;string, bool&amp;gt; predicate = value =&amp;gt; string.Compare(value, &quot;x&quot;, StringComparison.OrdinalIgnoreCase) &amp;gt; 0;
        Trace.WriteLine($&quot;{nameof(Linq)}: {array1.Run(Linq, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(EagerForEach)}: {array2.Run(EagerForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(LazyForEach)}: {array3.Run(LazyForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(Monad)}: {array4.Run(Monad, predicate)}&quot;);
    }

    internal static void ValueTypeSequence()
    {
        IEnumerable&amp;lt;PersonValueType&amp;gt; array1 = PersonValueType.Random(1000).ToArray();
        IEnumerable&amp;lt;PersonValueType&amp;gt; array2 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;PersonValueType&amp;gt; array3 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;PersonValueType&amp;gt; array4 = array1.ToArray(); // Copy.
        Func&amp;lt;PersonValueType, bool&amp;gt; predicate = value =&amp;gt; value.Age &amp;gt; 18;
        Trace.WriteLine($&quot;{nameof(Linq)}: {array1.Run(Linq, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(EagerForEach)}: {array2.Run(EagerForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(LazyForEach)}: {array3.Run(LazyForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(Monad)}: {array4.Run(Monad, predicate)}&quot;);
    }

    internal static void ReferenceTypeSequence()
    {
        IEnumerable&amp;lt;PersonReferenceType&amp;gt; array1 = PersonReferenceType.Random(1000).ToArray();
        IEnumerable&amp;lt;PersonReferenceType&amp;gt; array2 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;PersonReferenceType&amp;gt; array3 = array1.ToArray(); // Copy.
        IEnumerable&amp;lt;PersonReferenceType&amp;gt; array4 = array1.ToArray(); // Copy.
        Func&amp;lt;PersonReferenceType, bool&amp;gt; predicate = value =&amp;gt; value.Age &amp;gt; 18;
        Trace.WriteLine($&quot;{nameof(Linq)}: {array1.Run(Linq, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(EagerForEach)}: {array2.Run(EagerForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(LazyForEach)}: {array3.Run(LazyForEach, predicate)}&quot;);
        Trace.WriteLine($&quot;{nameof(Monad)}: {array4.Run(Monad, predicate)}&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying these 4 functions (Release build, optimize code, x64) gives following numbers:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;677&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;266&quot;&amp;gt;(Milliseconds, the smaller the better)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;134&quot;&amp;gt;EagerForEach&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;LazyForEach&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Linq&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;91&quot;&amp;gt;Monad&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;266&quot;&amp;gt;Filter.Int32Sequence&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;134&quot;&amp;gt;4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;7&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;7&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;91&quot;&amp;gt;82&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;266&quot;&amp;gt;Filter.StringSequence&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;134&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;91&quot;&amp;gt;36&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;266&quot;&amp;gt;Filter.ValueTypeSequence&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;134&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;91&quot;&amp;gt;20&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;266&quot;&amp;gt;Filter.ReferenceTypeSequence&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;134&quot;&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;91&quot;&amp;gt;20&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Monad implementation runs slower in all cases.&lt;/p&gt;
&lt;h2&gt;Cost of lambda&lt;/h2&gt;
&lt;h3&gt;Filter array&lt;/h3&gt;
&lt;p&gt;Filtering an array can be done imperatively without any lambda expression, and functionally with lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
internal static partial class Filter
{
    internal static PersonReferenceType[] WithoutLambda(
        this PersonReferenceType[] source,
        int minAge1, int maxAge1, int minAge2, int maxAge2,
        string minName1, string maxName1, string minName2, string maxName2)
    {
        PersonReferenceType[] result = new PersonReferenceType[source.Length];
        int resultIndex = 0;
        foreach (PersonReferenceType person in source)
        {
            if ((person.Age &amp;gt;= minAge1 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2
                    || person.Age &amp;gt;= minAge2 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2)
                &amp;amp;&amp;amp; (string.Compare(person.Name, minName1, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                        &amp;amp;&amp;amp; string.Compare(person.Name, maxName1, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0
                    || string.Compare(person.Name, minName2, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                        &amp;amp;&amp;amp; string.Compare(person.Name, maxName2, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0))
            {
                result[resultIndex++] = person;
            }
        }

        Array.Resize(ref result, resultIndex);
        return result;
    }

    internal static PersonReferenceType[] WithLambda(
        this PersonReferenceType[] source,
        int minAge1, int maxAge1, int minAge2, int maxAge2,
        string minName1, string maxName1, string minName2, string maxName2)
            =&amp;gt; source
                .Where(person =&amp;gt;
                    (person.Age &amp;gt;= minAge1 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2
                        || person.Age &amp;gt;= minAge2 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2)
                    &amp;amp;&amp;amp; (string.Compare(person.Name, minName1, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                            &amp;amp;&amp;amp; string.Compare(person.Name, maxName1, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0
                        || string.Compare(person.Name, minName2, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                            &amp;amp;&amp;amp; string.Compare(person.Name, maxName2, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0))
                .ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Performance tests&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Filter
{
    internal static PersonReferenceType[] WithoutLambda(
        this PersonReferenceType[] source,
        int minAge1, int maxAge1, int minAge2, int maxAge2,
        string minName1, string maxName1, string minName2, string maxName2)
    {
        PersonReferenceType[] result = new PersonReferenceType[source.Length];
        int resultIndex = 0;
        foreach (PersonReferenceType person in source)
        {
            if ((person.Age &amp;gt;= minAge1 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2 || person.Age &amp;gt;= minAge2 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2)
                &amp;amp;&amp;amp; (string.Compare(person.Name, minName1, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                    &amp;amp;&amp;amp; string.Compare(person.Name, maxName1, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0
                    || string.Compare(person.Name, minName2, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                    &amp;amp;&amp;amp; string.Compare(person.Name, maxName2, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0))
            {
                result[resultIndex++] = person;
            }
        }

        Array.Resize(ref result, resultIndex);
        return result;
    }

    internal static PersonReferenceType[] WithLambda(
        this PersonReferenceType[] source,
        int minAge1, int maxAge1, int minAge2, int maxAge2,
        string minName1, string maxName1, string minName2, string maxName2)
        =&amp;gt; source.Where(person =&amp;gt;
            (person.Age &amp;gt;= minAge1 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2 || person.Age &amp;gt;= minAge2 &amp;amp;&amp;amp; person.Age &amp;lt;= maxAge2)
            &amp;amp;&amp;amp; (string.Compare(person.Name, minName1, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                &amp;amp;&amp;amp; string.Compare(person.Name, maxName1, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0
                || string.Compare(person.Name, minName2, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                &amp;amp;&amp;amp; string.Compare(person.Name, maxName2, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0)).ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying this function (Release build, optimize code, x64) gives following numbers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
internal static partial class Filter
{
    internal static void ByPredicate()
    {
        PersonReferenceType[] array1 = PersonReferenceType.Random(10000).ToArray();
        PersonReferenceType[] array2 = array1.ToArray(); // Copy.
        string minName1 = Guid.NewGuid().ToString();
        string maxName1 = Guid.NewGuid().ToString();
        string minName2 = Guid.NewGuid().ToString();
        string maxName2 = Guid.NewGuid().ToString();
        Trace.WriteLine(
            $@&quot;{nameof(WithoutLambda)}: {array1.Run(values =&amp;gt;
                WithoutLambda(values, 10, 20, 30, 40, minName1, maxName1, minName2, maxName2))}&quot;);
        Trace.WriteLine(
            $@&quot;{nameof(WithLambda)}: {array2.Run(values =&amp;gt;
                WithLambda(values, 10, 20, 30, 40, minName1, maxName1, minName2, maxName2))}&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;595&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;321&quot;&amp;gt;(Milliseconds, the smaller the better)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;148&quot;&amp;gt;WithoutLambda&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Lambda&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;321&quot;&amp;gt;Filter.ByPredicate&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;148&quot;&amp;gt;183&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;830&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Here lambda expression causes performance overhead because of closure. In above Lambda function, the lambda expression is compiled to a class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Filter
{
    [CompilerGenerated]
    private sealed class Predicate
    {
        public int minAge1; public int minAge2; public int maxAge1; public int maxAge2;

        public string minName1; public string maxName1; public string minName2; public string maxName2;

        public bool WithLambda(PersonReferenceType person)
            =&amp;gt; ((person.Age &amp;gt;= this.minAge1 &amp;amp;&amp;amp; person.Age &amp;lt;= this.maxAge1)
                    || (person.Age &amp;gt;= this.minAge2 &amp;amp;&amp;amp; person.Age &amp;lt;= this.maxAge2))
                &amp;amp;&amp;amp; ((string.Compare(person.Name, this.minName1, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                        &amp;amp;&amp;amp; string.Compare(person.Name, this.maxName1, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0)
                    || (string.Compare(person.Name, this.minName2, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0
                        &amp;amp;&amp;amp; string.Compare(person.Name, this.maxName2, StringComparison.OrdinalIgnoreCase) &amp;lt;= 0));
    }

    internal static PersonReferenceType[] CompiledWithLambda(
        this PersonReferenceType[] source,
        int minAge1, int maxAge1, int minAge2, int maxAge2,
        string minName1, string maxName1, string minName2, string maxName2)
            =&amp;gt; source.Where(new Predicate
                {
                    minAge1 = minAge1, minAge2 = minAge2, maxAge1 = maxAge1, maxAge2 = maxAge2,
                    minName1 = minName1, maxName1 = maxName1, minName2 = minName2, maxName2 = maxName2
                }.WithLambda).ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each reference to non-local variable becomes a field of the generated class, and the lambda expression (anonymous function) becomes a instance method. So every time Lambda function is applied, a Predicate class will be instantiated.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;After understanding aspects and powerful features of category theory and purely/impurely functional programming in C# and LINQ, it is also important to understand the cost of the value. Not all programs should be written in functional paradigm or in LINQ query style. These tests above demonstrated that some certain algorithm implemented in functional paradigm could run significantly slower than in imperative paradigm. Laziness, LINQ query, lambda with closure in LINQ can all cause performance overhead. In real world programming, knowing these cost helps making the right decision for each case.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (22) More Monad: Continuation Monad</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-22-more-monad-continuation-monad/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-22-more-monad-continuation-monad/</guid><description>In C#, callback is frequently used. For example, a very simple Add function, without asynchrony:</description><pubDate>Sun, 23 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-8-more-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Continuation and continuation-passing style&lt;/h2&gt;
&lt;p&gt;In C#, callback is frequently used. For example, a very simple Add function, without asynchrony:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class Cps
{
    // Add = (x, y) =&amp;gt; x + y
    public static int Add
        (int x, int y) =&amp;gt; x + y;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With a callback, it becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// AddWithCallback = (x, y, callback) =&amp;gt; callback(x + y)
public static TCallback AddWithCallback&amp;lt;TCallback&amp;gt;
    (int x, int y, Func&amp;lt;int, TCallback&amp;gt; callback) =&amp;gt; callback(x + y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In functional programming, a continuation is like a callback. &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuation-passing_style&quot;&gt;Continuation-passing style (CPS)&lt;/a&gt; is a style of programming to pass the control to a &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuation&quot;&gt;continuation&lt;/a&gt;, just like in above example, (x + y) is calculated then passed to the callback.&lt;/p&gt;
&lt;p&gt;For convenience, AddWithCallback can be curried a little bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// AddWithCallback = (x, y) =&amp;gt; callback =&amp;gt; callback(x + y)
public static Func&amp;lt;Func&amp;lt;int, TCallback&amp;gt;, TCallback&amp;gt; AddWithCallback&amp;lt;TCallback&amp;gt;
    (int x, int y) =&amp;gt; callback =&amp;gt; callback(x + y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that all the apperances of TCallback are in the return type Func&amp;lt;Func&amp;lt;int, TCallback&amp;gt;, TCallback&amp;gt;, then an alias Cps can be defined to make the code shorter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cps&amp;lt;T, TContinuation&amp;gt; is alias of Func&amp;lt;Func&amp;lt;T, TContinuation&amp;gt;, TContinuation&amp;gt;
public delegate TContinuation Cps&amp;lt;out T, TContinuation&amp;gt;(Func&amp;lt;T, TContinuation&amp;gt; continuation);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now a continuation-passing style function AddCps can be defined, which is exactly the same as above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// AddCps = (x, y) =&amp;gt; continuation =&amp;gt; continuation(x + y)
public static Cps&amp;lt;int, TContinuation&amp;gt; AddCps&amp;lt;TContinuation&amp;gt;
    (int x, int y) =&amp;gt; continuation =&amp;gt; continuation(x + y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other examples are the SquareCps and SumOfSquareCps functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SquareCps = x =&amp;gt; continuation =&amp;gt; continuation(x * x)
public static Cps&amp;lt;int, TContinuation&amp;gt; SquareCps&amp;lt;TContinuation&amp;gt;
    (int x) =&amp;gt; continuation =&amp;gt; continuation(x * x);

// SumOfSquaresCps = (x, y) =&amp;gt; continuation =&amp;gt; SquareCps(x)(xx =&amp;gt; SquareCps(y)(yy =&amp;gt; AddCps(xx)(yy)(continuation)));
public static Cps&amp;lt;int, TContinuation&amp;gt; SumOfSquaresCps&amp;lt;TContinuation&amp;gt;
    (int x, int y) =&amp;gt; continuation =&amp;gt;
        SquareCps&amp;lt;TContinuation&amp;gt;(x)(xx =&amp;gt;
            SquareCps&amp;lt;TContinuation&amp;gt;(y)(yy =&amp;gt;
                AddCps&amp;lt;TContinuation&amp;gt;(xx, yy)(continuation)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, CPS makes code and algorithms harder to understand and maintain.&lt;/p&gt;
&lt;h2&gt;Continuation monad&lt;/h2&gt;
&lt;p&gt;SelectMany can be implemented for Cps&amp;lt;T, TContinuation&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class CpsExtensions
{
    // Required by LINQ.
    public static Cps&amp;lt;TResult, TContinuation&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult, TContinuation&amp;gt;
        (this Cps&amp;lt;TSource, TContinuation&amp;gt; source,
         Func&amp;lt;TSource, Cps&amp;lt;TSelector, TContinuation&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            continuation =&amp;gt; source(sourceArg =&amp;gt;
                selector(sourceArg)(selectorArg =&amp;gt; 
                    continuation(resultSelector(sourceArg, selectorArg))));

    // Not required, just for convenience.
    public static Cps&amp;lt;TResult, TContinuation&amp;gt; SelectMany&amp;lt;TSource, TResult, TContinuation&amp;gt;
        (this Cps&amp;lt;TSource, TContinuation&amp;gt; source, Func&amp;lt;TSource, Cps&amp;lt;TResult, TContinuation&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class CpsExtensions
{
    // η: T -&amp;gt; Cps&amp;lt;T, TContinuation&amp;gt;
    public static Cps&amp;lt;T, TContinuation&amp;gt; Cps&amp;lt;T, TContinuation&amp;gt;
        (this T arg) =&amp;gt; continuation =&amp;gt; continuation(arg);

    // φ: Lazy&amp;lt;Cps&amp;lt;T1, TContinuation&amp;gt;, Cps&amp;lt;T2, TContinuation&amp;gt;&amp;gt; =&amp;gt; Cps&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, TContinuation&amp;gt;
    public static Cps&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, TContinuation&amp;gt; Binary&amp;lt;T1, T2, TContinuation&amp;gt;
        (this Lazy&amp;lt;Cps&amp;lt;T1, TContinuation&amp;gt;, Cps&amp;lt;T2, TContinuation&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Cps&amp;lt;TUnit, TContinuation&amp;gt;
    public static Cps&amp;lt;Unit, TContinuation&amp;gt; Unit&amp;lt;TContinuation&amp;gt;
        (Unit unit) =&amp;gt; unit.Cps&amp;lt;Unit, TContinuation&amp;gt;();

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Cps&amp;lt;TSource, TContinuation&amp;gt; -&amp;gt; Cps&amp;lt;TResult, TContinuation&amp;gt;)
    public static Cps&amp;lt;TResult, TContinuation&amp;gt; Select&amp;lt;TSource, TResult, TContinuation&amp;gt;
        (this Cps&amp;lt;TSource, TContinuation&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            // continuation =&amp;gt; source(sourceArg =&amp;gt; continuation(selector(sourceArg)));
            // continuation =&amp;gt; source(continuation.o(selector));
            source.SelectMany(value =&amp;gt; selector(value).Cps&amp;lt;TResult, TContinuation&amp;gt;());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cps&amp;lt; , &amp;gt; is a monad, monoidal functor, and functor.&lt;/p&gt;
&lt;h2&gt;Monad laws, and unit tests&lt;/h2&gt;
&lt;p&gt;2 helper functions can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class CpsExtensions
{
    public static Func&amp;lt;T, TContinuation&amp;gt; NoCps&amp;lt;T, TContinuation&amp;gt;
        (this Func&amp;lt;T, Cps&amp;lt;TContinuation, TContinuation&amp;gt;&amp;gt; cps) =&amp;gt; arg =&amp;gt; cps(arg)(Functions.Id);

    public static T Invoke&amp;lt;T&amp;gt;
        (this Cps&amp;lt;T, T&amp;gt; cps) =&amp;gt; cps(Functions.Id);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the unit test becomes easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void ContinuationTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;string, string&amp;gt;&amp;gt;&amp;gt; f = x =&amp;gt; y =&amp;gt; z =&amp;gt;
            {
                isExecuted1 = true;
                return (x + y + z.Length).ToString(CultureInfo.InstalledUICulture);
            };
        Cps&amp;lt;string, int&amp;gt; query = from x in 1.Cps&amp;lt;int, int&amp;gt;()
                                    from y in 2.Cps&amp;lt;int, int&amp;gt;()
                                    from z in &quot;abc&quot;.Cps&amp;lt;string, int&amp;gt;()
                                    select f(x)(y)(z);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.AreEqual((1 + 2 + &quot;abc&quot;.Length).ToString(CultureInfo.InstalledUICulture).Length, query(x =&amp;gt; x.Length)); // Execution.
        Assert.IsTrue(isExecuted1);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Cps&amp;lt;int, int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Cps&amp;lt;int, int&amp;gt;();
        Cps&amp;lt;int, int&amp;gt; left = 1.Cps&amp;lt;int, int&amp;gt;().SelectMany(addOne);
        Cps&amp;lt;int, int&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Invoke(), right.Invoke());
        // Monad law 2: M.SelectMany(Monad) == M
        Cps&amp;lt;int, int&amp;gt; M = 1.Cps&amp;lt;int, int&amp;gt;();
        left = M.SelectMany(CpsExtensions.Cps&amp;lt;int, int&amp;gt;);
        right = M;
        Assert.AreEqual(left.Invoke(), right.Invoke());
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Cps&amp;lt;int, int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Cps&amp;lt;int, int&amp;gt;();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Invoke(), right.Invoke());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And following is unit test for continuation functor, which also demonstrate the CPS version of &lt;a href=&quot;http://en.wikipedia.org/wiki/Factorial&quot;&gt;factorial&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class FunctorTests
{
    [TestMethod()]
    public void ContinuationTest()
    {
        Func&amp;lt;int, Cps&amp;lt;int, int&amp;gt;&amp;gt; factorialCps = null; // Must have.
        factorialCps = x =&amp;gt; x == 0
            ? 1.Cps&amp;lt;int, int&amp;gt;()
            : (from y in factorialCps(x - 1)
               select x * y);
        Func&amp;lt;int, int&amp;gt; factorial = factorialCps.NoCps();
        Assert.AreEqual(3 * 2 * 1, factorial(3));

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(factorialCps(3).Select(Functions.Id).Invoke(), Functions.Id(factorialCps(3)).Invoke());
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; x + 1;
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Cps&amp;lt;int, int&amp;gt; cps1 = factorialCps(3).Select(addTwo.o(addOne));
        Cps&amp;lt;int, int&amp;gt; cps2 = factorialCps(3).Select(addOne).Select(addTwo);
        Assert.AreEqual(cps1.Invoke(), cps2.Invoke());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (21) More Monad: Writer&lt; , &gt; Monad</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-21-more-monad-writer-monad/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-21-more-monad-writer-monad/</guid><description>Unlike the Reader&lt; , &gt; monad, the Writer&lt; , &gt; monad output contents with a sequence of functions:</description><pubDate>Sat, 22 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-8-more-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Writer&amp;lt; , &amp;gt; monad&lt;/h2&gt;
&lt;p&gt;Unlike the Reader&amp;lt; , &amp;gt; monad, the Writer&amp;lt; , &amp;gt; monad output contents with a sequence of functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Writer&amp;lt;T, TContent&amp;gt;
{
    private readonly Lazy&amp;lt;Tuple&amp;lt;T, TContent&amp;gt;&amp;gt; lazy;

    public Writer(Func&amp;lt;Tuple&amp;lt;T, TContent&amp;gt;&amp;gt; factory, IMonoid&amp;lt;TContent&amp;gt; monoid)
    {
        this.lazy = new Lazy&amp;lt;Tuple&amp;lt;T, TContent&amp;gt;&amp;gt;(factory);
        this.Monoid = monoid;
    }

    public T Value
    {
        [Pure]get { return this.lazy.Value.Item1; }
    }
public TContent Content
    {
        [Pure]get { return this.lazy.Value.Item2; }
    }

    public IMonoid&amp;lt;TContent&amp;gt; Monoid {[Pure] get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A Writer&amp;lt; , &amp;gt; is more complex than Reader&amp;lt; , &amp;gt;. It is a pair of value and output content, plus a monoid. A monoid is needed because its Binary operator is used to combine multiple output contents into one.&lt;/p&gt;
&lt;p&gt;This is the SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class WriterExtensions
{
    // Required by LINQ.
    public static Writer&amp;lt;TResult, TContent&amp;gt; SelectMany&amp;lt;TSource, TContent, TSelector, TResult&amp;gt;
        (this Writer&amp;lt;TSource, TContent&amp;gt; source,
         Func&amp;lt;TSource, Writer&amp;lt;TSelector, TContent&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            new Writer&amp;lt;TResult, TContent&amp;gt;(() =&amp;gt;
                {
                    Writer&amp;lt;TSelector, TContent&amp;gt; selectorResult = selector(source.Value);
                    return Tuple.Create(
                        resultSelector(source.Value, selectorResult.Value),
                        source.Monoid.Binary(source.Content, selectorResult.Content));
                }, source.Monoid);

    // Not required, just for convenience.
    public static Writer&amp;lt;TResult, TContent&amp;gt; SelectMany&amp;lt;TSource, TContent, TResult&amp;gt;
        (this Writer&amp;lt;TSource, TContent&amp;gt; source,
            Func&amp;lt;TSource, Writer&amp;lt;TResult, TContent&amp;gt;&amp;gt; selector) =&amp;gt; source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class WriterExtensions
{
    // μ: Writer&amp;lt;Writer&amp;lt;T, TContent&amp;gt;&amp;gt; =&amp;gt; Writer&amp;lt;T, TContent&amp;gt;
    public static Writer&amp;lt;TResult, TContent&amp;gt; Flatten&amp;lt;TResult, TContent&amp;gt;
        (Writer&amp;lt;Writer&amp;lt;TResult, TContent&amp;gt;, TContent&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Writer&amp;lt;T, TContent&amp;gt;
    public static Writer&amp;lt;T, TContent&amp;gt; Writer&amp;lt;T, TContent&amp;gt;
        (this T value, TContent content, IMonoid&amp;lt;TContent&amp;gt; monoid) =&amp;gt; 
            new Writer&amp;lt;T, TContent&amp;gt;(() =&amp;gt; Tuple.Create(value, content), monoid);

    // φ: Lazy&amp;lt;Writer&amp;lt;T1, TContent&amp;gt;, Writer&amp;lt;T2, TContent&amp;gt;&amp;gt; =&amp;gt; Writer&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, TContent&amp;gt;
    public static Writer&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, TContent&amp;gt; Binary&amp;lt;T1, T2, TContent&amp;gt;
        (this Lazy&amp;lt;Writer&amp;lt;T1, TContent&amp;gt;, Writer&amp;lt;T2, TContent&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Writer&amp;lt;TUnit, TContent&amp;gt;
    public static Writer&amp;lt;Unit, TContent&amp;gt; Unit&amp;lt;TContent&amp;gt;
        (Unit unit, TContent content, IMonoid&amp;lt;TContent&amp;gt; monoid) =&amp;gt; unit.Writer(content, monoid);

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Writer&amp;lt;TSource, TContent&amp;gt; -&amp;gt; Writer&amp;lt;TResult, TContent&amp;gt;)
    public static Writer&amp;lt;TResult, TContent&amp;gt; Select&amp;lt;TSource, TResult, TContent&amp;gt;
        (this Writer&amp;lt;TSource, TContent&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Writer(source.Content, source.Monoid));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A typical usage is to output string logs when applying a sequence of functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class WriterExtensions
{
    public static Writer&amp;lt;TSource, IEnumerable&amp;lt;string&amp;gt;&amp;gt; WithLog&amp;lt;TSource&amp;gt;(this TSource value, string log) =&amp;gt;
        value.Writer(
            $&quot;{DateTime.Now.ToString(&quot;o&quot;, CultureInfo.InvariantCulture)} - {log}&quot;.Enumerable(),
            Enumerable.Empty&amp;lt;string&amp;gt;().Monoid((a, b) =&amp;gt; a.Concat(b)));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take previous IEnumerable stack as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void Stack()
{
    IEnumerable&amp;lt;int&amp;gt; stack = Enumerable.Empty&amp;lt;int&amp;gt;();
    Writer&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;string&amp;gt;&amp;gt; writer =
        from lazy1 in stack.Push(1).WithLog(&quot;Push 1 to stack.&quot;)
        from lazy2 in lazy1.Value2.Push(2).WithLog(&quot;Push 2 to stack.&quot;)
        from lazy3 in lazy2.Value2.Pop().WithLog(&quot;Pop 2 from stack.&quot;)
        from stack1 in Enumerable.Range(0, 3).WithLog(&quot;Reset stack to 0, 1, 2.&quot;)
        from lazy4 in stack1.Push(4).WithLog(&quot;Push 4 to stack.&quot;)
        from lazy5 in lazy4.Value2.Pop().WithLog(&quot;Pop 4 from stack.&quot;)
        from stack2 in lazy5.Value2.WithLog(&quot;Get current stack.&quot;)
        select stack2;

    IEnumerable&amp;lt;int&amp;gt; resultStack = writer.Value;
    IEnumerable&amp;lt;string&amp;gt; logs = writer.Content;
    logs.ForEach(log =&amp;gt; Trace.WriteLine(log));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The logs will be like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2015-05-25T10:18:50.1769264-07:00 - Push 1 to stack. 2015-05-25T10:18:50.1769264-07:00 - Push 2 to stack. 2015-05-25T10:18:50.2082128-07:00 - Pop 2 from stack. 2015-05-25T10:18:50.2082128-07:00 - Reset stack to 0, 1, 2. 2015-05-25T10:18:50.2082128-07:00 - Push 4 to stack. 2015-05-25T10:18:50.2082128-07:00 - Pop 4 from stack. 2015-05-25T10:18:50.2082128-07:00 - Get current stack.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Monad laws, and unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void WriterTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int&amp;gt; f1 = () =&amp;gt; 1;
        Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;string, int&amp;gt;&amp;gt;&amp;gt; f2 = x =&amp;gt; y =&amp;gt; z =&amp;gt;
            { isExecuted1 = true; return x + y + z.Length; };
        Writer&amp;lt;int, IEnumerable&amp;lt;string&amp;gt;&amp;gt; query = from x in f1().WithLog(&quot;a&quot;)
                                                    from y in 2.WithLog(&quot;b&quot;)
                                                    from z in &quot;xyz&quot;.WithLog(&quot;c&quot;)
                                                    select f2(x)(y)(z);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.AreEqual(1 + 2 + &quot;xyz&quot;.Length, query.Value); // Execution.
        string[] logs = query.Content.ToArray();
        Assert.IsTrue(logs.Length==3);
        Assert.IsTrue(logs[0].EndsWith(&quot; - a&quot;));
        Assert.IsTrue(logs[1].EndsWith(&quot; - b&quot;));
        Assert.IsTrue(logs[2].EndsWith(&quot; - c&quot;));
        Assert.IsTrue(isExecuted1);

        IMonoid&amp;lt;string&amp;gt; monoid = string.Empty.Monoid((a, b) =&amp;gt; string.Concat(a, b));
        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Writer&amp;lt;int, string&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Writer(&quot;a&quot;, monoid);
        Writer&amp;lt;int, string&amp;gt; left = 1.Writer(&quot;b&quot;, monoid).SelectMany(addOne);
        Writer&amp;lt;int, string&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Value, right.Value);
        Assert.AreEqual(&quot;ba&quot;, left.Content);
        Assert.AreEqual(&quot;a&quot;, right.Content);
        // Monad law 2: M.SelectMany(Monad) == M
        Func&amp;lt;int, Writer&amp;lt;int, string&amp;gt;&amp;gt; Resturn = x =&amp;gt; x.Writer(&quot;abc&quot;, monoid);
        Writer&amp;lt;int, string&amp;gt; M = Resturn(1);
        left = M.SelectMany(Resturn);
        right = M;
        Assert.AreEqual(left.Value, right.Value);
        Assert.AreEqual(&quot;abcabc&quot;, left.Content);
        Assert.AreEqual(&quot;abc&quot;, right.Content);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Writer&amp;lt;int, string&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Writer(&quot;b&quot;, monoid);
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Value, right.Value);
        Assert.AreEqual(&quot;abcab&quot;, left.Content);
        Assert.AreEqual(&quot;abcab&quot;, right.Content);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (20) More Monad: Reader&lt; , &gt; Monad</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-20-more-monad-reader-monad/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-20-more-monad-reader-monad/</guid><description>Sometimes there are functions work with a shared environment. Typical examples are:</description><pubDate>Fri, 21 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-8-more-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Reader&amp;lt; , &amp;gt; Monad&lt;/h2&gt;
&lt;p&gt;Sometimes there are functions work with a shared environment. Typical examples are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;li&gt;Application’s settings stored in App.config&lt;/li&gt;
&lt;li&gt;web application’s configurations stored in Web.config&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Reader&amp;lt; , &amp;gt; monad is a specialized State&amp;lt; , &amp;gt; monad. It threads an environment parameter through a sequence of functions.&lt;/p&gt;
&lt;p&gt;The definition is simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Reader&amp;lt;TEnvironment, T&amp;gt; is alias of Func&amp;lt;TEnvironment, T&amp;gt;
public delegate T Reader&amp;lt;in TEnvironment, out T&amp;gt;(TEnvironment environment);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is nothing but a Func&amp;lt; , &amp;gt;. This is its SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class ReaderExtensions
{
    // Required by LINQ.
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; SelectMany&amp;lt;TEnvironment, TSource, TSelector, TResult&amp;gt;
        (this Reader&amp;lt;TEnvironment, TSource&amp;gt; source,
         Func&amp;lt;TSource, Reader&amp;lt;TEnvironment, TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            environment =&amp;gt;
                {
                    TSource sourceResult = source(environment);
                    return resultSelector(sourceResult, selector(sourceResult)(environment));
                };

    // Not required, just for convenience.
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; SelectMany&amp;lt;TEnvironment, TSource, TResult&amp;gt;
        (this Reader&amp;lt;TEnvironment, TSource&amp;gt; source,
            Func&amp;lt;TSource, Reader&amp;lt;TEnvironment, TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class ReaderExtensions
{
    // μ: Reader&amp;lt;TEnvironment, Reader&amp;lt;TEnvironment, T&amp;gt;&amp;gt; =&amp;gt; Reader&amp;lt;TEnvironment, T&amp;gt;
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; Flatten&amp;lt;TEnvironment, TResult&amp;gt;
        (Reader&amp;lt;TEnvironment, Reader&amp;lt;TEnvironment, TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Reader&amp;lt;TEnvironment, T&amp;gt;
    public static Reader&amp;lt;TEnvironment, T&amp;gt; Reader&amp;lt;TEnvironment, T&amp;gt;
        (this T value) =&amp;gt; environment =&amp;gt; value;

    // φ: Lazy&amp;lt;Reader&amp;lt;TEnvironment, T1&amp;gt;, Reader&amp;lt;TEnvironment, T2&amp;gt;&amp;gt; =&amp;gt; Reader&amp;lt;TEnvironment, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Reader&amp;lt;TEnvironment, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;TEnvironment, T1, T2&amp;gt;
        (this Lazy&amp;lt;Reader&amp;lt;TEnvironment, T1&amp;gt;, Reader&amp;lt;TEnvironment, T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Reader&amp;lt;TEnvironment, TUnit&amp;gt;
    public static Reader&amp;lt;TEnvironment, Unit&amp;gt; Unit&amp;lt;TEnvironment&amp;gt;
        (Unit unit) =&amp;gt; unit.Reader&amp;lt;TEnvironment, Unit&amp;gt;();

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Reader&amp;lt;TEnvironment, TSource&amp;gt; -&amp;gt; Reader&amp;lt;TEnvironment, TResult&amp;gt;)
    public static Reader&amp;lt;TEnvironment, TResult&amp;gt; Select&amp;lt;TEnvironment, TSource, TResult&amp;gt;
        (this Reader&amp;lt;TEnvironment, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Reader&amp;lt;TEnvironment, TResult&amp;gt;());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is an example of the usage in a .NET application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Reader&amp;lt;Settings, string&amp;gt; query =
    // 1. Use settings.
    from html in new Reader&amp;lt;Settings, string&amp;gt;(settings =&amp;gt; DownloadString(settings.BlogUrl))
    // 2. Use settings.
    from _ in new Reader&amp;lt;Settings, Unit&amp;gt;(settings =&amp;gt; SaveToDatabase(settings.ConnectionString, html))
    // 3. Update settings.
    from __ in new Reader&amp;lt;Settings, Settings&amp;gt;(settings =&amp;gt; UpdateSettings(settings))
    // 4. Use settings. Here settings are updated.
    from ___ in new Reader&amp;lt;Settings, Unit&amp;gt;(settings =&amp;gt; ListenToPort(settings.Port))
    select html;
string result = query(Settings.Default);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monad laws, and unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void ReaderTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        bool isExecuted3 = false;
        bool isExecuted4 = false;
        Reader&amp;lt;int, int&amp;gt; f1 = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Reader&amp;lt;int, string&amp;gt; f2 = x =&amp;gt;
            { isExecuted2 = true; return x.ToString(CultureInfo.InvariantCulture); };
        Func&amp;lt;string, Reader&amp;lt;int, int&amp;gt;&amp;gt; f3 = x =&amp;gt; y =&amp;gt; { isExecuted3 = true; return x.Length + y; };
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; f4 = x =&amp;gt; y =&amp;gt; { isExecuted4 = true; return x + y; };
        Reader&amp;lt;int, int&amp;gt; query1 = from x in f1
                                    from y in f2
                                    from z in f3(y)
                                    from _ in f1
                                    let f4x = f4(x)
                                    select f4x(z);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.IsFalse(isExecuted4); // Laziness.
        Assert.AreEqual(1 + 1 + 1 + 1, query1(1)); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted3);
        Assert.IsTrue(isExecuted4);

        Tuple&amp;lt;bool, string&amp;gt; config = Tuple.Create(true, &quot;abc&quot;);
        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt;&amp;gt; addOne = x =&amp;gt; c =&amp;gt; x + 1;
        Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt; left = 1.Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt;().SelectMany(addOne);
        Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt; right = addOne(1);
        Assert.AreEqual(left(config), right(config));
        // Monad law 2: M.SelectMany(Monad) == M
        Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt; M = c =&amp;gt; 1 + c.Item2.Length;
        left = M.SelectMany(ReaderExtensions.Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt;);
        right = M;
        Assert.AreEqual(left(config), right(config));
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Reader&amp;lt;Tuple&amp;lt;bool, string&amp;gt;, int&amp;gt;&amp;gt; addLength = x =&amp;gt; c =&amp;gt; x + c.Item2.Length;
        left = M.SelectMany(addOne).SelectMany(addLength);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addLength));
        Assert.AreEqual(left(config), right(config));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (19) More Monad: State&lt; , &gt; Monad</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-19-more-monad-state-monad/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-19-more-monad-state-monad/</guid><description>represents a abstract machine with one state or a number of state. C# use state machine a lot. For example:</description><pubDate>Thu, 20 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-8-more-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;C#/.NET state machines&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;State machine (or finite state machine)&lt;/a&gt; represents a abstract machine with one state or a number of state. C# use state machine a lot. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C# yield keyword &lt;a href=&quot;/posts/understanding-linq-to-objects-5-implementing-iterator&quot;&gt;compiles to a state machine that implements IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# await keyword &lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;compiles to a state machine that implements IAsyncStateMachine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;.NET has a lot of built-in state machines too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.activities.statements.statemachine.aspx&quot;&gt;System.Activities.Statements.StateMachine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh414263.aspx&quot;&gt;System.Web.Razor.StateMachine&amp;lt;TReturn&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;System.Xml.Xsl.XsltOld.StateMachine&lt;/li&gt;
&lt;li&gt;Microsoft.Transactions.Bridge.Dtc.StateMachine, and its 6 derived classes&lt;/li&gt;
&lt;li&gt;Microsoft.Transactions.Wsat.StateMachines.StateMachine, and its 9 derived classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;h2&gt;State pattern in object-oriented programming&lt;/h2&gt;
&lt;p&gt;State pattern is a typical way to implement state machine. The following picture is stolen from Wikipedia:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/dixin/category-theory-via-c-sharp-19-more-monad-state-monad/images/400px-State_Design_Pattern_UML_Class_Diagram.svg.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Traffic light state machine&lt;/h3&gt;
&lt;p&gt;A very simple example of (finite) state machine is traffic light. Assume a traffic light state machine has 3 state:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It starts with green state, and stays green for 3 seconds&lt;/li&gt;
&lt;li&gt;Then it mutates to yellow state for 1 second&lt;/li&gt;
&lt;li&gt;Then it mutates to red state, for 2 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code will just follow above diagram. Here are the states’ definitions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ITrafficLightState // State
{
    Task Handle(TrafficLightStateMachine light);
}

public class GreenState : ITrafficLightState // ConcreteStateA
{
    public async Task Handle(TrafficLightStateMachine light)
    {
        TraceHelper.TypeName(typeof(GreenState));
        await Task.Delay(3000);
        await light.MoveNext(new YellowState());
    }
}

public class YellowState : ITrafficLightState // ConcreteStateB
{
    public async Task Handle(TrafficLightStateMachine light)
    {
        TraceHelper.TypeName(typeof(YellowState));
        await Task.Delay(1000);
        await light.MoveNext(new RedState());
    }
}

public class RedState : ITrafficLightState // ConcreteStateC
{
    public async Task Handle(TrafficLightStateMachine light)
    {
        TraceHelper.TypeName(typeof(RedState));
        await Task.Delay(2000);
        // await light.MoveNext(new GreenState());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where TraceHelper.TypeName is just:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TraceHelper
{
    public static Unit TypeName(Type type)
    {
        Trace.WriteLine($&quot;{DateTime.Now.ToString(&quot;o&quot;, CultureInfo.InvariantCulture)}: {type.Name}&quot;);
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice Trace.TypeName and all Handle method implementations have side effects (write trace messages). And, in typical C# programming and OOP, side effect is not specially managed.&lt;/p&gt;
&lt;p&gt;The state machine will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TrafficLightStateMachine
{
    public ITrafficLightState State { get; private set; }

    public async Task MoveNext(ITrafficLightState state = null)
    {
        this.State = state ?? new GreenState();
        await this.State.Handle(this);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the state machine is mutable. The underlined code updates the state of the state machine.&lt;/p&gt;
&lt;p&gt;Running the state machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new TrafficLightStateMachine().MoveNext().Wait();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can result the following trace message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2015-05-24T16:19:08.2431705-07:00 - GreenState 2015-05-24T16:19:11.2530920-07:00 - YellowState 2015-05-24T16:19:12.2549302-07:00 - RedState&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;State&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;In purely functional programming, objects are immutable, state cannot just be updated when changing. State monad can be used to thread a state parameter through a sequence of functions to represent the state updating.&lt;/p&gt;
&lt;p&gt;This is the definition of state monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// State&amp;lt;T, TState&amp;gt; is alias of Func&amp;lt;TState, Lazy&amp;lt;T, TState&amp;gt;&amp;gt;
public delegate Lazy&amp;lt;T, TState&amp;gt; State&amp;lt;T, TState&amp;gt;(TState state);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As usual, its SelectMany will be defined firstly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class StateExtensions
{
    // Required by LINQ.
    public static State&amp;lt;TResult, TState&amp;gt; SelectMany&amp;lt;TSource, TState, TSelector, TResult&amp;gt;
        (this State&amp;lt;TSource, TState&amp;gt; source,
         Func&amp;lt;TSource, State&amp;lt;TSelector, TState&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            state =&amp;gt; new Lazy&amp;lt;TResult, TState&amp;gt;(() =&amp;gt;
                {
                    Lazy&amp;lt;TSource, TState&amp;gt; sourceResult = source(state);
                    Lazy&amp;lt;TSelector, TState&amp;gt; selectorResult = selector(sourceResult.Value1)(sourceResult.Value2);
                    return Tuple.Create(
                        resultSelector(sourceResult.Value1, selectorResult.Value1),
                        selectorResult.Value2);
                });

    // Not required, just for convenience.
    public static State&amp;lt;TResult, TState&amp;gt; SelectMany&amp;lt;TSource, TState, TResult&amp;gt;
        (this State&amp;lt;TSource, TState&amp;gt; source, Func&amp;lt;TSource, State&amp;lt;TResult, TState&amp;gt;&amp;gt; selector) =&amp;gt;
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class StateExtensions
{
    // η: T -&amp;gt; State&amp;lt;T, TState&amp;gt;
    public static State&amp;lt;T, TState&amp;gt; State&amp;lt;T, TState&amp;gt;
        (this T value) =&amp;gt; state =&amp;gt; new Lazy&amp;lt;T, TState&amp;gt;(value, state);

    // η: T -&amp;gt; State&amp;lt;T, TState&amp;gt;
    public static State&amp;lt;T, TState&amp;gt; State&amp;lt;T, TState&amp;gt;
        (this T value, Func&amp;lt;TState, TState&amp;gt; newState) =&amp;gt;
            oldState =&amp;gt; new Lazy&amp;lt;T, TState&amp;gt;(value, newState(oldState));

    // φ: Lazy&amp;lt;State&amp;lt;T1, TState&amp;gt;, State&amp;lt;T2, TState&amp;gt;&amp;gt; =&amp;gt; State&amp;lt;Defer&amp;lt;T1, T2&amp;gt;, TState&amp;gt;
    public static State&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, TState&amp;gt; Binary&amp;lt;T1, T2, TState&amp;gt;
        (this Lazy&amp;lt;State&amp;lt;T1, TState&amp;gt;, State&amp;lt;T2, TState&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; State&amp;lt;TUnit, TState&amp;gt;
    public static State&amp;lt;Unit, TState&amp;gt; Unit&amp;lt;TState&amp;gt;
        (Unit unit) =&amp;gt; unit.State&amp;lt;Unit, TState&amp;gt;();

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (State&amp;lt;TSource, TState&amp;gt; -&amp;gt; State&amp;lt;TResult, TState&amp;gt;)
    public static State&amp;lt;TResult, TState&amp;gt; Select&amp;lt;TSource, TResult, TState&amp;gt;
        (this State&amp;lt;TSource, TState&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(value =&amp;gt; selector(value).State&amp;lt;TResult, TState&amp;gt;());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;State&amp;lt;&amp;gt; is monad, monoidal functor, and functor.&lt;/p&gt;
&lt;p&gt;Also a few other helper functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class StateExtensions
{
    public static TSource Value&amp;lt;TSource, TState&amp;gt;
        (this State&amp;lt;TSource, TState&amp;gt; source, TState state) =&amp;gt; source(state).Value1;

    public static TState State&amp;lt;T, TState&amp;gt;
        (this State&amp;lt;T, TState&amp;gt; source, TState state) =&amp;gt; source(state).Value2;
}

[Pure]
public static class State
{
    public static State&amp;lt;TState, TState&amp;gt; Get&amp;lt;TState&amp;gt;
        () =&amp;gt; state =&amp;gt; new Lazy&amp;lt;TState, TState&amp;gt;(state, state);

    public static State&amp;lt;TState, TState&amp;gt; Set&amp;lt;TState&amp;gt;
        (TState newState) =&amp;gt; oldState =&amp;gt; new Lazy&amp;lt;TState, TState&amp;gt;(oldState, newState);

    public static State&amp;lt;TState, TState&amp;gt; Set&amp;lt;TState&amp;gt;
        (Func&amp;lt;TState, TState&amp;gt; newState) =&amp;gt; oldState =&amp;gt; new Lazy&amp;lt;TState, TState&amp;gt;(oldState, newState(oldState));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Traffic light state machine with State&amp;lt;&amp;gt; monad and LINQ&lt;/h3&gt;
&lt;p&gt;Now everything becomes functions. This is the definition of the traffic light state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; TrafficLightState();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not interface any more.&lt;/p&gt;
&lt;p&gt;And each state is a pure function of above type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class StateQuery
{
    [Pure]
    public static IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; GreenState
        () =&amp;gt;
            from _ in TraceHelper.Log(nameof(GreenState))
            select (from __ in Task.Delay(TimeSpan.FromSeconds(3))
                    select new TrafficLightState(YellowState));

    [Pure]
    public static IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; YellowState
        () =&amp;gt;
            from _ in TraceHelper.Log(nameof(YellowState))
            select (from __ in Task.Delay(TimeSpan.FromSeconds(1))
                    select new TrafficLightState(RedState));

    [Pure]
    public static IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; RedState
        () =&amp;gt;
            from _ in TraceHelper.Log(nameof(RedState))
            select (from __ in Task.Delay(TimeSpan.FromSeconds(2))
                    select default(TrafficLightState));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where Trace.Log is a pure function too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class TraceHelper
{
    public static IO&amp;lt;Unit&amp;gt; Log
        (string log) =&amp;gt;
            () =&amp;gt;
                {
                    Trace.WriteLine($&quot;{DateTime.Now.ToString(&quot;o&quot;, CultureInfo.InvariantCulture)} - {log}&quot;);
                    return null;
                };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please also notice Task.Delay returns a Task (not Task&amp;lt;&amp;gt;). As mentioned in an earlier part, Task can be viewed as Task&amp;lt;Unit&amp;gt;, a special case of Task&amp;lt;&amp;gt;. So the LINQ syntax works for Task.&lt;/p&gt;
&lt;p&gt;The state machine is also pure function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class StateQuery
{
    [Pure]
    public static State&amp;lt;Unit, IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt;&amp;gt; MoveNext
        () =&amp;gt;
            ((Unit)null).State&amp;lt;Unit, IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt;&amp;gt;(state =&amp;gt; async () =&amp;gt;
                {
                    TrafficLightState next = await (state ?? GreenState())();
                    return next == null ? null : await next()();
                });

    [Pure]
    public static IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; TrafficLight(IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt; state = null)
    {
        State&amp;lt;Unit, IO&amp;lt;Task&amp;lt;TrafficLightState&amp;gt;&amp;gt;&amp;gt; query =
            from green in MoveNext()
            from yellow in MoveNext()
            from red in MoveNext()
            select (Unit)null; // Deferred and lazy.
        return query.State(state); // Final state.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running this state machine with State&amp;lt;&amp;gt; monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class StateQuery
{
    public static async void ExecuteTrafficLight() =&amp;gt; await TrafficLight()();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will result similar trace message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;04/02/2015 20:44:30 - GreenState 04/02/2015 20:44:33 - YellowState 04/02/2015 20:44:34 - RedState&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Immutable IEnumerable&amp;lt;T&amp;gt; stack&lt;/h3&gt;
&lt;p&gt;An easier example could be using a immutable IEnumerable&amp;lt;T&amp;gt; to simulate a mutable stack. Firstly, a Pop and a Push function can be implemented:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static Lazy&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; Pop&amp;lt;T&amp;gt;
        (this IEnumerable&amp;lt;T&amp;gt; source) =&amp;gt;
            // The execution of First is deferred, so that Pop is still pure.
            new Lazy&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt;(source.First, () =&amp;gt; source.Skip(1));

    public static Lazy&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; Push&amp;lt;T&amp;gt;
        (this IEnumerable&amp;lt;T&amp;gt; source, T value) =&amp;gt;
            new Lazy&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt;(value, source.Concat(value.Enumerable()));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a stateful stack can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class StateQuery
{
    [Pure]
    public static State&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; Pop&amp;lt;T&amp;gt;
        () =&amp;gt; source =&amp;gt; source.Pop();

    [Pure]
    public static State&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; Push&amp;lt;T&amp;gt;
        (T value) =&amp;gt; source =&amp;gt; source.Push(value);

    [Pure]
    public static IEnumerable&amp;lt;int&amp;gt; Stack(IEnumerable&amp;lt;int&amp;gt; state = null)
    {
        state = state ?? Enumerable.Empty&amp;lt;int&amp;gt;();
        State&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; query =
            from value1 in Push(1)
            from value2 in Push(2)
            from value3 in Pop&amp;lt;int&amp;gt;()
            from stack1 in State.Set(Enumerable.Range(0, 3))
            from value4 in Push(4)
            from value5 in Pop&amp;lt;int&amp;gt;()
            from stack2 in State.Get&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt;()
            select stack2;
        return query.Value(state);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above functions are all pure functions, and IEnumerable&amp;lt;int&amp;gt; is immutable. They clearly demonstrated how State&amp;lt;&amp;gt; monad simulates the state updating - after each call of Push, Pop, or Set, a new IEnumerable&amp;lt;T&amp;gt; is created to pass to the next function in the sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class StackTests
{
    [TestMethod]
    public void StateMachineTest()
    {
        IEnumerable&amp;lt;int&amp;gt; expected = Enumerable.Range(0, 3).Push(4).Value2.Pop().Value2;
        IEnumerable&amp;lt;int&amp;gt; actual = StateQuery.Stack();
        EnumerableAssert.AreEqual(expected, actual);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Monad laws, and unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod]
    public void StateTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;State&amp;lt;int, string&amp;gt;&amp;gt; f1 = () =&amp;gt; 1.State&amp;lt;int, string&amp;gt;(
            state =&amp;gt; { isExecuted1 = true; return state + &quot;a&quot;; });
        Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;string, int&amp;gt;&amp;gt;&amp;gt; f2 =
            x =&amp;gt; y =&amp;gt; z =&amp;gt; { isExecuted2 = true; return x + y + z.Length; };
        State&amp;lt;int, string&amp;gt; query1 = from x in f1()
                                    from _ in State.Set(x.ToString(CultureInfo.InvariantCulture))
                                    from y in 2.State&amp;lt;int, string&amp;gt;(state =&amp;gt; &quot;b&quot; + state)
                                    from z in State.Get&amp;lt;string&amp;gt;()
                                    select f2(x)(y)(z);
        Assert.IsFalse(isExecuted1); // Deferred and lazy.
        Assert.IsFalse(isExecuted2); // Deferred and lazy.
        Lazy&amp;lt;int, string&amp;gt; result1 = query1(&quot;state&quot;); // Execution.
        Assert.AreEqual(1 + 2 + (&quot;b&quot; + &quot;1&quot;).Length, result1.Value1);
        Assert.AreEqual(&quot;b&quot; + &quot;1&quot;, result1.Value2);
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, State&amp;lt;int, string&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).State&amp;lt;int, string&amp;gt;();
        State&amp;lt;int, string&amp;gt; left = 1.State&amp;lt;int, string&amp;gt;().SelectMany(addOne);
        State&amp;lt;int, string&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Value(&quot;a&quot;), right.Value(&quot;a&quot;));
        Assert.AreEqual(left.State(&quot;a&quot;), right.State(&quot;a&quot;));
        // Monad law 2: M.SelectMany(Monad) == M
        State&amp;lt;int, string&amp;gt; M = 1.State&amp;lt;int, string&amp;gt;();
        left = M.SelectMany(StateExtensions.State&amp;lt;int, string&amp;gt;);
        right = M;
        Assert.AreEqual(left.Value(&quot;a&quot;), right.Value(&quot;a&quot;));
        Assert.AreEqual(left.State(&quot;a&quot;), right.State(&quot;a&quot;));
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, State&amp;lt;int, string&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).State&amp;lt;int, string&amp;gt;();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Value(&quot;a&quot;), right.Value(&quot;a&quot;));
        Assert.AreEqual(left.State(&quot;a&quot;), right.State(&quot;a&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (18) More Monad: IO&lt;&gt; Monad</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-18-more-monad-io-monad/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-18-more-monad-io-monad/</guid><description>As mentioned in a previous part, in purely functional programming, functions cannot have side effects. For example, when defining LINQ queries, laziness and purity are expected. So, how should the imp</description><pubDate>Wed, 19 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-8-more-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-8-more-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As mentioned in a previous part, in purely functional programming, functions cannot have side effects. For example, when defining LINQ queries, laziness and purity are expected. So, how should the impure actions be managed in purely functional programming or LINQ? For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read from/write to console&lt;/li&gt;
&lt;li&gt;Read from/write to file system&lt;/li&gt;
&lt;li&gt;Download from/upload to Internet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Monad_(functional_programming)#The_I.2FO_monad&quot;&gt;IO&amp;lt;&amp;gt; monad&lt;/a&gt; is an approach.&lt;/p&gt;
&lt;h2&gt;IO&amp;lt;T&amp;gt; and impurity&lt;/h2&gt;
&lt;p&gt;The definition of IO&amp;lt;&amp;gt; is simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate T IO&amp;lt;out T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Syntactically it is just Func&amp;lt;T&amp;gt;. However, it is used to represent a different semantic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Here in category theory and functional programming, Func&amp;lt;T&amp;gt; is used to represent a pure function. When a Func&amp;lt;T&amp;gt; value is executed, it returns a T value without side effects&lt;/li&gt;
&lt;li&gt;IO&amp;lt;T&amp;gt; is used to represent a impure function. When a IO&amp;lt;T&amp;gt; function is applied, it returns a T value, with side effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So above examples can be represented with IO&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read a line from console: Console.ReadLine: () → string
&lt;ul&gt;
&lt;li&gt;Syntactically it is a Func&amp;lt;string&amp;gt;.&lt;/li&gt;
&lt;li&gt;Now with IO&amp;lt;T&amp;gt;, semantically it can be represented as IO&amp;lt;string&amp;gt;, meaning when applied it returns a string value with side effect&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write a line to console: Console.WriteLIne: string → Void
&lt;ul&gt;
&lt;li&gt;Syntactically it is an Action&amp;lt;string&amp;gt; or Func&amp;lt;string, Void&amp;gt;, since it takes a string parameter and returns nothing (Void)&lt;/li&gt;
&lt;li&gt;Now semantically it can be a Func&amp;lt;string, IO&amp;lt;Void&amp;gt;&amp;gt;, meaning it is will eventually return nothing (a Void value) with side effect
&lt;ul&gt;
&lt;li&gt;Because C# does not allow using Void in that way, Console.WriteLIne will be represented by Func&amp;lt;string, IO&amp;lt;Unit&amp;gt;&amp;gt;, by borrowing &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee370443.aspx&quot;&gt;Unit from F#&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Actually, in F# Console.WriteLine is of type string -&amp;gt; Unit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read text from a file: File.ReadAllText: string → string
&lt;ul&gt;
&lt;li&gt;Syntactically it is a Func&amp;lt;string, string&amp;gt;, since it takes a file path parameter and returns the text in that file&lt;/li&gt;
&lt;li&gt;Now semantically it should be a Func&amp;lt;string, IO&amp;lt;string&amp;gt;&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write text to a file: File.WriteAllText: (string, string) → Void
&lt;ul&gt;
&lt;li&gt;Syntactically it is an Action&amp;lt;string, string&amp;gt; or Func&amp;lt;string, string, Void&amp;gt;, since it takes a file path parameter and a text parameter, and returns nothing (Void)&lt;/li&gt;
&lt;li&gt;Now semantically it should be a Func&amp;lt;string, string, IO&amp;lt;Unit&amp;gt;&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. The following extension methods convert Func&amp;lt;T&amp;gt; to IO&amp;lt;T&amp;gt;, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class IOExtensions
{
    public static IO&amp;lt;Unit&amp;gt; AsIO
        (this Action action) =&amp;gt; 
            () =&amp;gt;
                {
                    action();
                    return null;
                };

    public static Func&amp;lt;T, IO&amp;lt;Unit&amp;gt;&amp;gt; AsIO&amp;lt;T&amp;gt;
        (this Action&amp;lt;T&amp;gt; action) =&amp;gt; arg =&amp;gt; 
            () =&amp;gt;
                {
                    action(arg);
                    return null;
                };

    public static Func&amp;lt;T1, T2, IO&amp;lt;Unit&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2&amp;gt;
        (this Action&amp;lt;T1, T2&amp;gt; action) =&amp;gt; (arg1, arg2) =&amp;gt; 
            () =&amp;gt;
                {
                    action(arg1, arg2);
                    return null;
                };

    public static Func&amp;lt;T1, T2, T3, IO&amp;lt;Unit&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2, T3&amp;gt;
        (this Action&amp;lt;T1, T2, T3&amp;gt; action) =&amp;gt; (arg1, arg2, arg3) =&amp;gt; 
            () =&amp;gt;
                {
                    action(arg1, arg2, arg3);
                    return null;
                };

    public static Func&amp;lt;T1, T2, T3, T4, IO&amp;lt;Unit&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2, T3, T4&amp;gt;
        (this Action&amp;lt;T1, T2, T3, T4&amp;gt; action) =&amp;gt; (arg1, arg2, arg3, arg4) =&amp;gt; 
            () =&amp;gt;
                {
                    action(arg1, arg2, arg3, arg4);
                    return null;
                };

    // ...

    public static IO&amp;lt;TResult&amp;gt; AsIO&amp;lt;TResult&amp;gt;
        (this Func&amp;lt;TResult&amp;gt; function) =&amp;gt; 
            () =&amp;gt; function();

    public static Func&amp;lt;T, IO&amp;lt;TResult&amp;gt;&amp;gt; AsIO&amp;lt;T, TResult&amp;gt;
        (this Func&amp;lt;T, TResult&amp;gt; function) =&amp;gt; arg =&amp;gt; 
            () =&amp;gt; function(arg);

    public static Func&amp;lt;T1, T2, IO&amp;lt;TResult&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, TResult&amp;gt; function) =&amp;gt; (arg1, arg2) =&amp;gt; 
            () =&amp;gt; function(arg1, arg2);

    public static Func&amp;lt;T1, T2, T3, IO&amp;lt;TResult&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2, T3, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function) =&amp;gt; (arg1, arg2, arg3) =&amp;gt; 
            () =&amp;gt; function(arg1, arg2, arg3);

    public static Func&amp;lt;T1, T2, T3, T4, IO&amp;lt;TResult&amp;gt;&amp;gt; AsIO&amp;lt;T1, T2, T3, T4, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function) =&amp;gt; (arg1, arg2, arg3, arg4) =&amp;gt; 
            () =&amp;gt; function(arg1, arg2, arg3, arg4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IO&amp;lt;string&amp;gt; consoleReadLine = new Func&amp;lt;string&amp;gt;(Console.ReadLine).AsIO();
Func&amp;lt;string, IO&amp;lt;Unit&amp;gt;&amp;gt; consoleWriteLine = new Action&amp;lt;string&amp;gt;(Console.WriteLine).AsIO();

Func&amp;lt;string, IO&amp;lt;string&amp;gt;&amp;gt; fileReadAllText = new Func&amp;lt;string, string&amp;gt;(File.ReadAllText).AsIO();
Func&amp;lt;string, string, IO&amp;lt;Unit&amp;gt;&amp;gt; fileWriteAllText = new Action&amp;lt;string, string&amp;gt;(File.WriteAllText).AsIO();

Func&amp;lt;string, IO&amp;lt;bool&amp;gt;&amp;gt; fileExists = new Func&amp;lt;string, bool&amp;gt;(File.Exists).AsIO();
// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A lot of type information as usual. Some other functions can be created to make the code shorter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class IO
{
    public static IO&amp;lt;Unit&amp;gt; Action
        (Action action) =&amp;gt; action.AsIO();

    public static Func&amp;lt;T, IO&amp;lt;Unit&amp;gt;&amp;gt; Action&amp;lt;T&amp;gt;
        (this Action&amp;lt;T&amp;gt; action) =&amp;gt; action.AsIO();

    public static Func&amp;lt;T1, T2, IO&amp;lt;Unit&amp;gt;&amp;gt; Action&amp;lt;T1, T2&amp;gt;
        (this Action&amp;lt;T1, T2&amp;gt; action) =&amp;gt; action.AsIO();

    public static Func&amp;lt;T1, T2, T3, IO&amp;lt;Unit&amp;gt;&amp;gt; Action&amp;lt;T1, T2, T3&amp;gt;
        (this Action&amp;lt;T1, T2, T3&amp;gt; action) =&amp;gt; action.AsIO();

    public static Func&amp;lt;T1, T2, T3, T4, IO&amp;lt;Unit&amp;gt;&amp;gt; Action&amp;lt;T1, T2, T3, T4&amp;gt;
        (this Action&amp;lt;T1, T2, T3, T4&amp;gt; action) =&amp;gt; action.AsIO();

    // ...

    public static IO&amp;lt;T&amp;gt; Func&amp;lt;T&amp;gt;
        (this Func&amp;lt;T&amp;gt; function) =&amp;gt; function.AsIO();

    public static Func&amp;lt;T, IO&amp;lt;TResult&amp;gt;&amp;gt; Func&amp;lt;T, TResult&amp;gt;
        (this Func&amp;lt;T, TResult&amp;gt; function) =&amp;gt; function.AsIO();

    public static Func&amp;lt;T1, T2, IO&amp;lt;TResult&amp;gt;&amp;gt; Func&amp;lt;T1, T2, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, TResult&amp;gt; function) =&amp;gt; function.AsIO();

    public static Func&amp;lt;T1, T2, T3, IO&amp;lt;TResult&amp;gt;&amp;gt; Func&amp;lt;T1, T2, T3, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function) =&amp;gt; function.AsIO();

    public static Func&amp;lt;T1, T2, T3, T4, IO&amp;lt;TResult&amp;gt;&amp;gt; Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function) =&amp;gt; function.AsIO();

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IO&amp;lt;string&amp;gt; consoleReadLine = IO.Func(Console.ReadLine);
Func&amp;lt;string, IO&amp;lt;Unit&amp;gt;&amp;gt; consoleWriteLine = IO.Action&amp;lt;string&amp;gt;(Console.WriteLine);

Func&amp;lt;string, IO&amp;lt;string&amp;gt;&amp;gt; fileReadAllText = IO.Func&amp;lt;string, string&amp;gt;(File.ReadAllText);
Func&amp;lt;string, string, IO&amp;lt;Unit&amp;gt;&amp;gt; fileWriteAllText = IO.Action&amp;lt;string, string&amp;gt;(File.WriteAllText);

Func&amp;lt;string, IO&amp;lt;bool&amp;gt;&amp;gt; fileExists = IO.Func&amp;lt;string, bool&amp;gt;(File.Exists);
// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some type parameters are still needed for IO.Action/IO.Func to locate the specific overload.&lt;/p&gt;
&lt;h2&gt;IO&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;Again, for C# compiler, IO&amp;lt;&amp;gt; is exactly the same as Func&amp;lt;&amp;gt;, so IO&amp;lt;&amp;gt; must be a monad. The following SelectMany is copied from previous part of Func&amp;lt;&amp;gt; monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class IOExtensions
{
    // Required by LINQ.
    public static IO&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this IO&amp;lt;TSource&amp;gt; source, 
         Func&amp;lt;TSource, IO&amp;lt;TSelector&amp;gt;&amp;gt; selector, 
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            () =&amp;gt;
                {
                    TSource sourceItem = source();
                    return resultSelector(sourceItem, selector(sourceItem)());
                };

    // Not required, just for convenience.
    public static IO&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this IO&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IO&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation for μ, φ, and ι are skipped since they are all the same as Func&amp;lt;&amp;gt;. Here is only Select implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class IOExtensions
{
    // η: T -&amp;gt; IO&amp;lt;T&amp;gt;
    public static IO&amp;lt;T&amp;gt; IO&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; () =&amp;gt; value;

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (IO&amp;lt;TSource&amp;gt; -&amp;gt; IO&amp;lt;TResult&amp;gt;)
    public static IO&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this IO&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(item =&amp;gt; selector(item).IO());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Select has to be implemented so that &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb383976.aspx&quot;&gt;let clause&lt;/a&gt; can be used in LINQ query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 1. Read file name from console.
IO&amp;lt;Tuple&amp;lt;bool, string&amp;gt;&amp;gt; query1 = from fileName in IO.Func(Console.ReadLine)
                                 // 2. Write confirmation message to console.
                                 let message = string.Format(
                                                 CultureInfo.InstalledUICulture, &quot;{0}? y/n&quot;, fileName)
                                 from _ in IO.Action&amp;lt;string&amp;gt;(Console.WriteLine)(message)
                                 // 3. Read confirmation from console.
                                 from confirmation in IO.Func(Console.ReadLine)
                                 // 4. If confirmed, read the file.
                                 let isConfirmed = string.Equals(
                                                 confirmation, &quot;y&quot;, StringComparison.OrdinalIgnoreCase)
                                 from text in isConfirmed
                                                 ? IO.Func&amp;lt;string, string&amp;gt;(File.ReadAllText)(fileName)
                                                 : string.Empty.IO()
                                 // 5. Write text to console.
                                 from __ in IO.Action&amp;lt;string&amp;gt;(Console.WriteLine)(text)
                                 // 6. Returns text as query result.
                                 select new Tuple&amp;lt;bool, string&amp;gt;(isConfirmed, text); // Laziness.
Tuple&amp;lt;bool, string&amp;gt; result = query1(); // Execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 1. Read URL from console.
IO&amp;lt;Unit&amp;gt; query2 = from url in IO.Func(Console.ReadLine)
                  // 2. Download string from Internet.
                  from text in IO.Func(() =&amp;gt; new WebClient().DownloadString(url))
                  // 3. Write string to console.
                  let length = 1000
                  let message = text.Length &amp;lt;= length 
                          ? text
                          : string.Format(CultureInfo.InstalledUICulture, &quot;{0}...&quot;, text.Substring(0, length))
                  from unit in IO.Action&amp;lt;string&amp;gt;(Console.WriteLine)(message)
                  select (Unit)null; // Laziness.
query2(); // Execution...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both examples demonstrated the purity and laziness of IO&amp;lt;&amp;gt; monad. When defining the LINQ query, those involved impure functions are not applied at all. They are applied only when the query is executed. Again, IO&amp;lt;&amp;gt; is exactly the same as Func&amp;lt;&amp;gt; at compile time and run time. It is just artificially assigned a different semantic from Func&amp;lt;&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Monad laws, and unit tests&lt;/h2&gt;
&lt;p&gt;The following unit test demonstrates how IO&amp;lt;&amp;gt; monad satisfies the monad laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void IOTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        bool isExecuted3 = false;
        bool isExecuted4 = false;
        IO&amp;lt;int&amp;gt; one = () =&amp;gt; { isExecuted1 = true; return 1; };
        IO&amp;lt;int&amp;gt; two = () =&amp;gt; { isExecuted2 = true; return 2; };
        Func&amp;lt;int, IO&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; { isExecuted3 = true; return (x + 1).IO(); };
        Func&amp;lt;int, Func&amp;lt;int, IO&amp;lt;int&amp;gt;&amp;gt;&amp;gt; add = x =&amp;gt; y =&amp;gt; { isExecuted4 = true; return (x + y).IO(); };
        IO&amp;lt;IO&amp;lt;int&amp;gt;&amp;gt; query1 = from x in one
                                from y in two
                                from z in addOne.Partial(y)()
                                from _ in &quot;abc&quot;.IO()
                                let addOne2 = add(x)
                                select addOne2(z);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.IsFalse(isExecuted4); // Laziness.
        Assert.AreEqual(1 + 2 + 1, query1()()); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted3);
        Assert.IsTrue(isExecuted4);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, IO&amp;lt;int&amp;gt;&amp;gt; addOne3 = x =&amp;gt; (x + 1).IO();
        IO&amp;lt;int&amp;gt; left = 1.IO().SelectMany(addOne3);
        IO&amp;lt;int&amp;gt; right = addOne3(1);
        Assert.AreEqual(left(), right());
        // Monad law 2: M.SelectMany(Monad) == M
        IO&amp;lt;int&amp;gt; M = 1.IO();
        left = M.SelectMany(m =&amp;gt; m.IO());
        right = M;
        Assert.AreEqual(left(), right());
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, IO&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).IO();
        left = M.SelectMany(addOne3).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne3(x).SelectMany(addTwo));
        Assert.AreEqual(left(), right());

        bool isExecuted5 = false;
        bool isExecuted6 = false;
        bool isExecuted7 = false;
        Func&amp;lt;int, IO&amp;lt;int&amp;gt;&amp;gt; addOne4 = x =&amp;gt; { isExecuted5 = true; return (x + 1).IO(); };
        Func&amp;lt;string, IO&amp;lt;int&amp;gt;&amp;gt; length = x =&amp;gt; { isExecuted6 = true; return (x.Length).IO(); };
        Func&amp;lt;int, Func&amp;lt;int, IO&amp;lt;string&amp;gt;&amp;gt;&amp;gt; f7 = x =&amp;gt; y =&amp;gt;
            { isExecuted7 = true; return (new string(&apos;a&apos;, x + y)).IO(); };
        Func&amp;lt;int, Func&amp;lt;string, IO&amp;lt;string&amp;gt;&amp;gt;&amp;gt; query2 = a =&amp;gt; b =&amp;gt; (from x in addOne4(a).IO()
                                                                from y in length(b).IO()
                                                                from z in 0.IO()
                                                                select f7(x())(y()))();
        Assert.IsFalse(isExecuted5); // Laziness.
        Assert.IsFalse(isExecuted6); // Laziness.
        Assert.IsFalse(isExecuted7); // Laziness.
        Assert.AreEqual(new string(&apos;a&apos;, 1 + 1 + &quot;abc&quot;.Length), query2(1)(&quot;abc&quot;)()); // Execution.
        Assert.IsTrue(isExecuted5);
        Assert.IsTrue(isExecuted6);
        Assert.IsTrue(isExecuted7);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (17) Monad-like Tuple&lt;&gt;, Task&lt;&gt;, IQueryable&lt;&gt; And IQbservable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-17-monad-like-tuple-task-iqueryable-and-iqbservable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-17-monad-like-tuple-task-iqueryable-and-iqbservable/</guid><description>Theoretically, Tuple&lt;&gt; should be counted as the Id&lt;&gt; monad. However, it is lack of laziness. In the context of C# and LINQ, it is only monad-like.</description><pubDate>Tue, 18 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-7-monad-and-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Tuple&amp;lt;&amp;gt;: lack of laziness&lt;/h2&gt;
&lt;p&gt;Theoretically, Tuple&amp;lt;&amp;gt; should be counted as the Id&amp;lt;&amp;gt; monad. However, it is lack of laziness. In the context of C# and LINQ, it is only monad-like.&lt;/p&gt;
&lt;p&gt;This is its SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class TupleExtensions
{
    // Required by LINQ.
    public static Tuple&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this Tuple&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, Tuple&amp;lt;TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            new Tuple&amp;lt;TResult&amp;gt;(resultSelector(source.Item1, selector(source.Item1).Item1));

    // Not required, just for convenience.
    public static Tuple&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this Tuple&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, Tuple&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which can implement μ, η, φ, ι, Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class TupleExtensions
{
    // μ: Tuple&amp;lt;Tuple&amp;lt;T&amp;gt; =&amp;gt; Tuple&amp;lt;T&amp;gt;
    public static Tuple&amp;lt;TResult&amp;gt; Flatten&amp;lt;TResult&amp;gt;
        (this Tuple&amp;lt;Tuple&amp;lt;TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Tuple&amp;lt;T&amp;gt; is already implemented previously as TupleExtensions.Tuple.

    // φ: Lazy&amp;lt;Tuple&amp;lt;T1&amp;gt;, Tuple&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Tuple&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Tuple&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary2&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Tuple&amp;lt;T1&amp;gt;, Tuple&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Tuple&amp;lt;TUnit&amp;gt; is already implemented previously with η: T -&amp;gt; Tuple&amp;lt;T&amp;gt;.

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Tuple&amp;lt;TSource&amp;gt; -&amp;gt; Tuple&amp;lt;TResult&amp;gt;)
    public static Tuple&amp;lt;TResult&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;
        (this Tuple&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Tuple());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tuple&amp;lt;&amp;gt; is most close to the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/Data-Functor-Identity.html#line-89&quot;&gt;Haskell Id Monad&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Task&amp;lt;&amp;gt;: lack of purity&lt;/h2&gt;
&lt;p&gt;Task&amp;lt;&amp;gt; also seems monadic, but is lack of purity. This is the SelectMany for Task&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    // Required by LINQ.
    public static async Task&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this Task&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, Task&amp;lt;TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            resultSelector(await source, await selector(await source));

    // Not required, just for convenience.
    public static Task&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this Task&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, Task&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which can implement μ, η, φ, ι, Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    // μ: Task&amp;lt;Task&amp;lt;T&amp;gt; =&amp;gt; Task&amp;lt;T&amp;gt;
    public static Task&amp;lt;TResult&amp;gt; Flatten&amp;lt;TResult&amp;gt;
        (this Task&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Task&amp;lt;T&amp;gt; is already implemented previously as TaskExtensions.Task.

    // φ: Lazy&amp;lt;Task&amp;lt;T1&amp;gt;, Task&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Task&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Task&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary2&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Task&amp;lt;T1&amp;gt;, Task&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Task&amp;lt;TUnit&amp;gt; is already implemented previously with η: T -&amp;gt; Task&amp;lt;T&amp;gt;.

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Task&amp;lt;TSource&amp;gt; -&amp;gt; Task&amp;lt;TResult&amp;gt;)
    public static Task&amp;lt;TResult&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;
        (this Task&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Task());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Task&amp;lt;&amp;gt; and LINQ&lt;/h3&gt;
&lt;p&gt;With above SelectMany, Task&amp;lt;&amp;gt; can be used in LINQ syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;string, Task&amp;lt;string&amp;gt;&amp;gt; query = url =&amp;gt;
    from httpResponseMessage in new HttpClient().GetAsync(url) // Returns Task&amp;lt;HttpResponseMessage&amp;gt;
    from html in httpResponseMessage.Content.ReadAsStringAsync() // Returns Task&amp;lt;string&amp;gt;
    select html;
string result = await query(&quot;https://weblogs.asp.net/dixin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Non-generic Task&lt;/h3&gt;
&lt;p&gt;Task&amp;lt;T&amp;gt; is a wrapper of Func&amp;lt;T&amp;gt; and Task is a wrapper of Action. Actually Action can be viewed as Func&amp;lt;Void&amp;gt;, so that Task can be viewed as Task&amp;lt;Void&amp;gt;. Since C# compiler does not allow Void to be used in this way, Task can be just viewed as Task&amp;lt;Unit&amp;gt;. In this way, Task become like monad too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    // Required by LINQ.
    public static async Task&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        this Task source,
        Func&amp;lt;Unit, Task&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;Unit, TSelector, TResult&amp;gt; resultSelector)
    {
        await source;
        return resultSelector(null, await selector(null));
    }

    // Not required, just for convenience.
    public static Task&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TResult&amp;gt;
        (this Task source, Func&amp;lt;Unit, Task&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    // η: Unit -&amp;gt; Task.
    public static Task Task(Unit unit) =&amp;gt; System.Threading.Tasks.Task.Run(() =&amp;gt; { });

    // ι: TUnit -&amp;gt; Task is already implemented previously with η: Unit -&amp;gt; Task.

    // Select: (Unit -&amp;gt; TResult) -&amp;gt; (Task -&amp;gt; Task&amp;lt;TResult&amp;gt;)
    public static Task&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;
        (this Task source, Func&amp;lt;Unit, TResult&amp;gt; selector) =&amp;gt; source.SelectMany(value =&amp;gt; selector(value).Task());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IQueryable&amp;lt;&amp;gt; is like a monad&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-linq-to-sql-2-iqueryable-lt-t-gt&quot;&gt;IQueryable&amp;lt;&amp;gt;&lt;/a&gt; has been discussed a lot in &lt;a href=&quot;/archive/?tag=LINQ%20to%20SQL&quot;&gt;previous posts&lt;/a&gt;. It looks like monad, with laziness and purity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    var query = from category in database.Categories
                from product in category.Products
                select new { category.CategoryName, product.ProductName }; // Laziness

    query.ForEach(value =&amp;gt; { }); // Execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or equivalently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    var query = database.Categories.SelectMany(
        category =&amp;gt; category.Products, 
        (category, product) =&amp;gt; new { category.CategoryName, product.ProductName }); // Laziness

    query.ForEach(value =&amp;gt; { }); // Execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this is its SelectMany implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class QueryableExtensions
{
    public static IQueryable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;
        (this IQueryable&amp;lt;TSource&amp;gt; source,
         Expression&amp;lt;Func&amp;lt;TSource, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt;&amp;gt; collectionSelector,
         Expression&amp;lt;Func&amp;lt;TSource, TCollection, TResult&amp;gt;&amp;gt; resultSelector) =&amp;gt; 
            source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(Expression.Call(
                null, 
                ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
                    new Type[] { typeof(TSource), typeof(TCollection), typeof(TResult) }),
                new Expression[]
                    {
                        source.Expression,
                        Expression.Quote(collectionSelector),
                        Expression.Quote(resultSelector)
                    }));

    public static IQueryable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this IQueryable&amp;lt;TSource&amp;gt; source,
         Expression&amp;lt;Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(Expression.Call(
                null, 
                ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
                    new Type[] { typeof(TSource), typeof(TResult) }),
                new Expression[] { source.Expression, Expression.Quote(selector) }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;discussed before&lt;/a&gt;, when working with IQueryable&amp;lt;T&amp;gt;, the lambda expressions are not functions but &lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;data structure - an abstract syntax tree&lt;/a&gt;. So that a lambda-like expression trees in the query can be compiled to something else - here a T-SQL query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[CategoryName], [t1].[ProductName]
FROM [dbo].[Categories] AS [t0], [dbo].[Products] AS [t1]
WHERE [t1].[CategoryID] = [t0].[CategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very powerful feature of C# language and LINQ.&lt;/p&gt;
&lt;h2&gt;IQbservable&amp;lt;&amp;gt; is also like a monad&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.reactive.linq.iqbservable.aspx&quot;&gt;IQbservable&amp;lt;&amp;gt;&lt;/a&gt; is provided by &lt;a href=&quot;http://www.nuget.org/packages/Rx-Interfaces/&quot;&gt;System.Reactive.Interfaces&lt;/a&gt;, a part of &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/gg577609.aspx&quot;&gt;Rx (Reactive Extensions)&lt;/a&gt;. It is the queryable version of &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd990377.aspx&quot;&gt;IObservable&amp;lt;&amp;gt;&lt;/a&gt;, works similarly with expression lambda-like expression trees.&lt;/p&gt;
&lt;p&gt;Here are 2 samples of Qbservable providers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://social.msdn.microsoft.com/Forums/en-US/d459291a-4245-45ba-8888-35e07f7cf5b2/rx-sample-of-qbservable-provider-for-wmi-events-linq-to-wql?forum=rx&quot;&gt;Qbservable provider for WMI events (LINQ to WQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rxx.codeplex.com/wikipage?title=TCP%20Qbservable%20Provider&quot;&gt;Qbservable provider for TCP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;Following unit tests demonstrate the usage of monadic Tuple&amp;lt;&amp;gt; and Task&amp;lt;&amp;gt;. Notice Tuple is lack of laziness, and Task&amp;lt;&amp;gt;’s SelectMany extension method work for both cold tasks and hot tasks.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void TupleTest()
    {
        bool isExecuted = false;
        Tuple&amp;lt;int&amp;gt; one = new Tuple&amp;lt;int&amp;gt;(1);
        Tuple&amp;lt;int&amp;gt; two = new Tuple&amp;lt;int&amp;gt;(2);
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; add = x =&amp;gt; y =&amp;gt; { isExecuted = true; return x + y; };
        Tuple&amp;lt;int&amp;gt; query = from x in one
                            from y in two
                            from _ in one
                            select add(x)(y);
        Assert.IsTrue(isExecuted); // No laziness.
        Assert.AreEqual(1 + 2, query.Item1); // Execution.

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Tuple&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Tuple();
        Tuple&amp;lt;int&amp;gt; left = 1.Tuple().SelectMany(addOne);
        Tuple&amp;lt;int&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Item1, right.Item1);
        // Monad law 2: M.SelectMany(Monad) == M
        Tuple&amp;lt;int&amp;gt; M = 1.Tuple();
        left = M.SelectMany(TupleExtensions.Tuple);
        right = M;
        Assert.AreEqual(left.Item1, right.Item1);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Tuple&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Tuple();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Item1, right.Item1);
    }

    [TestMethod()]
    public void HotTaskTest()
    {
        Task&amp;lt;string&amp;gt; a = Task.Run(() =&amp;gt; &quot;a&quot;);
        Task&amp;lt;string&amp;gt; b = Task.Run(() =&amp;gt; &quot;b&quot;);
        Func&amp;lt;string, Func&amp;lt;string, string&amp;gt;&amp;gt; concat = x =&amp;gt; y =&amp;gt; x + y;
        Task&amp;lt;string&amp;gt; query1 = from x in a
                                from y in b
                                from _ in a
                                select concat(x)(y);
        Assert.AreEqual(&quot;a&quot; + &quot;b&quot;, query1.Result);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Task&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Task();
        Task&amp;lt;int&amp;gt; left = 1.Task().SelectMany(addOne);
        Task&amp;lt;int&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Result, right.Result);
        // Monad law 2: M.SelectMany(Monad) == M
        Task&amp;lt;int&amp;gt; M = 1.Task();
        left = M.SelectMany(TaskExtensions.Task);
        right = M;
        Assert.AreEqual(left.Result, right.Result);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        M = 1.Task();
        Func&amp;lt;int, Task&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Task();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Result, right.Result);
    }

    [TestMethod()]
    public void ColdTaskTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        bool isExecuted3 = false;
        Task&amp;lt;string&amp;gt; a = new Task&amp;lt;string&amp;gt;(() =&amp;gt; { isExecuted1 = true; return &quot;a&quot;; });
        Task&amp;lt;string&amp;gt; b = new Task&amp;lt;string&amp;gt;(() =&amp;gt; { isExecuted2 = true; return &quot;b&quot;; });
        Func&amp;lt;string, Func&amp;lt;string, string&amp;gt;&amp;gt; concat = x =&amp;gt; y =&amp;gt; { isExecuted3 = true; return x + y; };
        Task&amp;lt;string&amp;gt; query = from x in a
                                from y in b
                                from _ in a
                                select concat(x)(y);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(isExecuted3); // Laziness.
        a.Start(); // Execution.
        b.Start(); // Execution.
        Assert.AreEqual(&quot;a&quot; + &quot;b&quot;, query.Result);
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted3);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt; addOneTasks = new List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt;();
        Func&amp;lt;int, Task&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt;
        {
            Task&amp;lt;int&amp;gt; task = (x + 1).Task(true);
            addOneTasks.Add(task);
            return task;
        };
        Task&amp;lt;int&amp;gt; one = 1.Task(true);
        Task&amp;lt;int&amp;gt; left = one.SelectMany(addOne);
        Task&amp;lt;int&amp;gt; right = addOne(1);
        one.Start();
        while (addOneTasks.Count &amp;lt; 2) { }
        addOneTasks.ForEach(task =&amp;gt; task.Start());
        Assert.AreEqual(left.Result, right.Result);
        // Monad law 2: M.SelectMany(Monad) == M
        Task&amp;lt;int&amp;gt; M = 1.Task(true);
        left = M.SelectMany(TaskExtensions.Task);
        right = M;
        M.Start();
        Assert.AreEqual(left.Result, right.Result);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        addOneTasks.Clear();
        List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt; addTwoTasks = new List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt;();
        M = 1.Task(true);
        Func&amp;lt;int, Task&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt;
        {
            Task&amp;lt;int&amp;gt; task = (x + 1).Task(true);
            addTwoTasks.Add(task);
            return task;
        };
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        M.Start();
        while (addOneTasks.Count &amp;lt; 2) { }
        addOneTasks.ForEach(task =&amp;gt; task.Start());
        while (addTwoTasks.Count &amp;lt; 2) { }
        addTwoTasks.ForEach(task =&amp;gt; task.Start());
        Assert.AreEqual(left.Result, right.Result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (16) More Monads: Lazy&lt;&gt;, Func&lt;&gt;, Nullable&lt;&gt;, ParallelQuery&lt;&gt; And IObservale&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-16-more-monads-lazy-func-nullable-parallelquery-and-iobservale/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-16-more-monads-lazy-func-nullable-parallelquery-and-iobservale/</guid><description>Again, Lazy&lt;&gt; is the simplest monad, it is just the lazy version of Tuple&lt;&gt;, and should be considered as the Id&lt;&gt; monad. This is the implementation of its SelectMany:</description><pubDate>Mon, 17 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-7-monad-and-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Lazy&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;Again, Lazy&amp;lt;&amp;gt; is the simplest monad, it is just the lazy version of Tuple&amp;lt;&amp;gt;, and should be considered as the Id&amp;lt;&amp;gt; monad. This is the implementation of its SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    // Required by LINQ.
    public static Lazy&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this Lazy&amp;lt;TSource&amp;gt; source, 
         Func&amp;lt;TSource, Lazy&amp;lt;TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; resultSelector(source.Value, selector(source.Value).Value));

    // Not required, just for convenience.
    public static Lazy&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this Lazy&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, Lazy&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that Lazy&amp;lt;&amp;gt; is a monad, a monoidal functor, and a functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    // μ: Lazy&amp;lt;Lazy&amp;lt;T&amp;gt; =&amp;gt; Lazy&amp;lt;T&amp;gt;
    public static Lazy&amp;lt;TResult&amp;gt; Flatten&amp;lt;TResult&amp;gt;
        (this Lazy&amp;lt;Lazy&amp;lt;TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Lazy&amp;lt;T&amp;gt; is already implemented previously as LazyExtensions.Lazy.

    // φ: Lazy&amp;lt;Lazy&amp;lt;T1&amp;gt;, Lazy&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Lazy&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Lazy&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary2&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Lazy&amp;lt;T1&amp;gt;, Lazy&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Lazy&amp;lt;TUnit&amp;gt; is already implemented previously with η: T -&amp;gt; Lazy&amp;lt;T&amp;gt;.

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Lazy&amp;lt;TSource&amp;gt; -&amp;gt; Lazy&amp;lt;TResult&amp;gt;)
    public static Lazy&amp;lt;TResult&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;
        (this Lazy&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Lazy());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lazy&amp;lt;&amp;gt; is similar to the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/Data-Functor-Identity.html#line-89&quot;&gt;Haskell Id Monad&lt;/a&gt;. The usage will be demonstrated in unit tests later.&lt;/p&gt;
&lt;h2&gt;Func&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;SelectMany can be implemented for Func&amp;lt;&amp;gt; too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class FuncExtensions
{
    // Required by LINQ.
    public static Func&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this Func&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, Func&amp;lt;TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            () =&amp;gt;
                {
                    TSource sourceValue = source();
                    return resultSelector(sourceValue, selector(sourceValue)());
                };

    // Not required, just for convenience.
    public static Func&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this Func&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, Func&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that Func&amp;lt;&amp;gt; is a monad, a monoidal functor, and a functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class FuncExtensions
{
    // μ: Func&amp;lt;Func&amp;lt;T&amp;gt; =&amp;gt; Func&amp;lt;T&amp;gt;
    public static Func&amp;lt;TResult&amp;gt; Flatten&amp;lt;TResult&amp;gt;
        (this Func&amp;lt;Func&amp;lt;TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Func&amp;lt;T&amp;gt; is already implemented previously as FuncExtensions.Func.

    // φ: Lazy&amp;lt;Func&amp;lt;T1&amp;gt;, Func&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Func&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Func&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary2&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Func&amp;lt;T1&amp;gt;, Func&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Func&amp;lt;TUnit&amp;gt; is already implemented previously with η: T -&amp;gt; Func&amp;lt;T&amp;gt;.

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Func&amp;lt;TSource&amp;gt; -&amp;gt; Func&amp;lt;TResult&amp;gt;)
    public static Func&amp;lt;TResult&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;
        (this Func&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Func());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Nullable&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;And this is the SelectMany for Nullable&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class NullableExtensions
{
    // Required by LINQ.
    public static Nullable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
        (this Nullable&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, Nullable&amp;lt;TSelector&amp;gt;&amp;gt; selector,
         Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt; 
            new Nullable&amp;lt;TResult&amp;gt;(() =&amp;gt;
                {
                    if (source.HasValue)
                    {
                        Nullable&amp;lt;TSelector&amp;gt; selectorResult = selector(source.Value);
                        if (selectorResult.HasValue)
                        {
                            return Tuple.Create(true, resultSelector(source.Value, selectorResult.Value));
                        }
                    }

                    return Tuple.Create(false, default(TResult));
                });

    // Not required, just for convenience.
    public static Nullable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
        (this Nullable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, Nullable&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.SelectMany(selector, Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that Nullable&amp;lt;&amp;gt; is a monad, a monoidal functor, and a functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class NullableExtensions
{
    // μ: Nullable&amp;lt;Nullable&amp;lt;T&amp;gt; =&amp;gt; Nullable&amp;lt;T&amp;gt;
    public static Nullable&amp;lt;TResult&amp;gt; Flatten&amp;lt;TResult&amp;gt;
        (this Nullable&amp;lt;Nullable&amp;lt;TResult&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);

    // η: T -&amp;gt; Nullable&amp;lt;T&amp;gt; is already implemented previously as NullableExtensions.Nullable.

    // φ: Lazy&amp;lt;Nullable&amp;lt;T1&amp;gt;, Nullable&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Nullable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Nullable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary2&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Nullable&amp;lt;T1&amp;gt;, Nullable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: TUnit -&amp;gt; Nullable&amp;lt;TUnit&amp;gt; is already implemented previously with η: T -&amp;gt; Nullable&amp;lt;T&amp;gt;.

    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (Nullable&amp;lt;TSource&amp;gt; -&amp;gt; Nullable&amp;lt;TResult&amp;gt;)
    public static Nullable&amp;lt;TResult&amp;gt; Select2&amp;lt;TSource, TResult&amp;gt;
        (this Nullable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(value =&amp;gt; selector(value).Nullable());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ParallelQuery&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;Parallel LINQ provides ParallelQuery&amp;lt;&amp;gt; monad. This is its SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class ParallelEnumerable
{
    public static ParallelQuery&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;
        (this ParallelQuery&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
         Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector) =&amp;gt;
            new SelectManyQueryOperator&amp;lt;TSource, TCollection, TResult&amp;gt;(
                source, collectionSelector, null, resultSelector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation of System.Linq.Parallel.SelectManyQueryOperator&amp;lt;TLeftInput, TRightInput, TOutput&amp;gt; class is a big parallel computing topic and will be skipped in these category theory posts.&lt;/p&gt;
&lt;p&gt;ParallelQuery&amp;lt;&amp;gt; can be used with laziness and purity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ParallelQuery&amp;lt;int&amp;gt; query = from value in Enumerable.Range(0, 1000).AsParallel()
                           from repeat in Enumerable.Repeat(value, 2)
                           select repeat; // Laziness.

query.ForAll(Console.WriteLine); // Execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above code is just an example of using ParallelQuery&amp;lt;&amp;gt; monad with LINQ syntax. In real world parallel query, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd997403.aspx&quot;&gt;some performance pitfalls&lt;/a&gt; has to be noticed.&lt;/p&gt;
&lt;h2&gt;IObservable&amp;lt;&amp;gt; monad&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd990377.aspx&quot;&gt;IObservable&amp;lt;&amp;gt;&lt;/a&gt; is built-in in mscorlib. Then &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/gg577609.aspx&quot;&gt;Rx (Reactive Extensions)&lt;/a&gt; makes IObservable&amp;lt;&amp;gt; a monad. In &lt;a href=&quot;http://www.nuget.org/packages/Rx-Linq/&quot;&gt;System.Reactive.Linq.dll&lt;/a&gt;, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.selectmany.aspx&quot;&gt;SelectMany&lt;/a&gt; is implemented for IObservable&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Observable
{
    public static IObservable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;
        (this IObservable&amp;lt;TSource&amp;gt; source,
         Func&amp;lt;TSource, IObservable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
         Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector) =&amp;gt;
            new SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
                source, collectionSelector, resultSelector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;System.Reactive.Linq.ObservableImpl.SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt; class’s source code can be viewed &lt;a href=&quot;https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable/SelectMany.cs&quot;&gt;on github here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So IObservable becomes a monad andcan be used in LINQ with laziness and purity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IObservable&amp;lt;int&amp;gt; query = from value in Observable.Range(0, 1000)
                         from repeat in Observable.Repeat(value, 2)
                         select repeat; // Laziness.
query = query.Do(value =&amp;gt; Console.WriteLine(&quot;Do&quot;)); // Laziness.

query.Subscribe(Console.WriteLine); // Execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is the MouseDrag event implementation in WPF:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class UIElementExtensions
{
    public static IObservable&amp;lt;EventPattern&amp;lt;MouseEventArgs&amp;gt;&amp;gt; MouseDrag
        (this UIElement element) =&amp;gt;
            from _ in Observable.FromEventPattern&amp;lt;MouseEventArgs&amp;gt;(element, nameof(element.MouseDown))
            from @event in Observable.FromEventPattern&amp;lt;MouseEventArgs&amp;gt;(element, nameof(element.MouseMove))
                .TakeUntil(Observable.FromEventPattern&amp;lt;MouseEventArgs&amp;gt;(element, nameof(element.MouseUp)))
            select @event;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The observing starts from MouseDown event, then keep taking MouseMove event, until MouseUp event is observed. So that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;element.MouseDrag()
    .Subscribe(@event =&amp;gt; OnMouseDrag(@event.EventArgs));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void LazyTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        bool isExecuted3 = false;
        Lazy&amp;lt;int&amp;gt; one = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; { isExecuted1 = true; return 1; });
        Lazy&amp;lt;int&amp;gt; two = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; { isExecuted2 = true; return 2; });
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; add = x =&amp;gt; y =&amp;gt; { isExecuted3 = true; return x + y; };
        Lazy&amp;lt;int&amp;gt; query = from x in one
                            from y in two
                            from _ in one
                            select add(x)(y);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.AreEqual(1 + 2, query.Value); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted3);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Lazy&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Lazy();
        Lazy&amp;lt;int&amp;gt; left = 1.Lazy().SelectMany(addOne);
        Lazy&amp;lt;int&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Value, right.Value);
        // Monad law 2: M.SelectMany(Monad) == M
        Lazy&amp;lt;int&amp;gt; M = 1.Lazy();
        left = M.SelectMany(LazyExtensions.Lazy);
        right = M;
        Assert.AreEqual(left.Value, right.Value);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Lazy&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Lazy();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Value, right.Value);
    }

    [TestMethod()]
    public void FuncTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        bool isExecuted3 = false;
        bool isExecuted4 = false;
        Func&amp;lt;int&amp;gt; f1 = () =&amp;gt; { isExecuted1 = true; return 1; };
        Func&amp;lt;int&amp;gt; f2 = () =&amp;gt; { isExecuted2 = true; return 2; };
        Func&amp;lt;int, int&amp;gt; f3 = x =&amp;gt; { isExecuted3 = true; return x + 1; };
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; f4 = x =&amp;gt; y =&amp;gt; { isExecuted4 = true; return x + y; };
        Func&amp;lt;int&amp;gt; query1 = from x in f1
                            from y in f2
                            from z in f3.Partial(y)
                            from _ in &quot;abc&quot;.Func()
                            let f4x = f4(x)
                            select f4x(z);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.IsFalse(isExecuted4); // Laziness.
        Assert.AreEqual(1 + 2 + 1, query1()); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted3);
        Assert.IsTrue(isExecuted4);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Func();
        Func&amp;lt;int&amp;gt; left = 1.Func().SelectMany(addOne);
        Func&amp;lt;int&amp;gt; right = addOne(1);
        Assert.AreEqual(left(), right());
        // Monad law 2: M.SelectMany(Monad) == M
        Func&amp;lt;int&amp;gt; M = 1.Func();
        left = M.SelectMany(FuncExtensions.Func);
        right = M;
        Assert.AreEqual(left(), right());
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Func();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left(), right());

        bool isExecuted5 = false;
        bool isExecuted6 = false;
        bool isExecuted7 = false;
        Func&amp;lt;int, int&amp;gt; f5 = x =&amp;gt; { isExecuted5 = true; return x + 1; };
        Func&amp;lt;string, int&amp;gt; f6 = x =&amp;gt; { isExecuted6 = true; return x.Length; };
        Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt; f7 = x =&amp;gt; y =&amp;gt;
        { isExecuted7 = true; return new string(&apos;a&apos;, x + y); };
        Func&amp;lt;int, Func&amp;lt;string, string&amp;gt;&amp;gt; query2 = a =&amp;gt; b =&amp;gt;
            (from x in f5(a).Func()
                from y in f6(b).Func()
                from z in 0.Func()
                select f7(x)(y))();
        Assert.IsFalse(isExecuted5); // Laziness.
        Assert.IsFalse(isExecuted6); // Laziness.
        Assert.IsFalse(isExecuted7); // Laziness.
        Assert.AreEqual(new string(&apos;a&apos;, 1 + 1 + &quot;abc&quot;.Length), query2(1)(&quot;abc&quot;)); // Execution.
        Assert.IsTrue(isExecuted5);
        Assert.IsTrue(isExecuted6);
        Assert.IsTrue(isExecuted7);
    }

    [TestMethod()]
    public void NullableTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt; add = x =&amp;gt; y =&amp;gt;
        { isExecuted1 = true; return (x + y).ToString(CultureInfo.InvariantCulture); };
        Nullable&amp;lt;int&amp;gt; nullable1 = new Nullable&amp;lt;int&amp;gt;();
        Nullable&amp;lt;int&amp;gt; nullable2 = new Nullable&amp;lt;int&amp;gt;();
        Nullable&amp;lt;string&amp;gt; query1 = from x in nullable1
                                    from y in nullable2
                                    from _ in nullable1
                                    select add(x)(y);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(query1.HasValue); // Execution.
        Assert.IsFalse(isExecuted1);

        bool isExecuted3 = false;
        bool isExecuted4 = false;
        bool isExecuted5 = false;
        add = x =&amp;gt; y =&amp;gt;
        { isExecuted3 = true; return (x + y).ToString(CultureInfo.InvariantCulture); };
        Nullable&amp;lt;int&amp;gt; one = new Nullable&amp;lt;int&amp;gt;(() =&amp;gt;
        { isExecuted4 = true; return Tuple.Create(true, 1); });
        Nullable&amp;lt;int&amp;gt; two = new Nullable&amp;lt;int&amp;gt;(() =&amp;gt;
        { isExecuted5 = true; return Tuple.Create(true, 2); });
        Nullable&amp;lt;string&amp;gt; query2 = from x in one
                                    from y in two
                                    from _ in one
                                    select add(x)(y);
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.IsFalse(isExecuted4); // Laziness.
        Assert.IsFalse(isExecuted5); // Laziness.
        Assert.IsTrue(query2.HasValue); // Execution.
        Assert.AreEqual(&quot;3&quot;, query2.Value);
        Assert.IsTrue(isExecuted3);
        Assert.IsTrue(isExecuted4);
        Assert.IsTrue(isExecuted5);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, Nullable&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Nullable();
        Nullable&amp;lt;int&amp;gt; left = 1.Nullable().SelectMany(addOne);
        Nullable&amp;lt;int&amp;gt; right = addOne(1);
        Assert.AreEqual(left.Value, right.Value);
        // Monad law 2: M.SelectMany(Monad) == M
        Nullable&amp;lt;int&amp;gt; M = 1.Nullable();
        left = M.SelectMany(NullableExtensions.Nullable);
        right = M;
        Assert.AreEqual(left.Value, right.Value);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, Nullable&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Nullable();
        left = M.SelectMany(addOne).SelectMany(addTwo);
        right = M.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo));
        Assert.AreEqual(left.Value, right.Value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (15) IEnumerable&lt;&gt; Monad And LINQ: SelectMany For All</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-15-ienumerable-monad-and-linq-selectmany-for-all/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-15-ienumerable-monad-and-linq-selectmany-for-all/</guid><description>Previous part introduced SelectMany for monad IEnumerable&lt;&gt;. Actually SelectMany is more than meets the eye, and can be used to implement other LINQ queries.</description><pubDate>Sun, 16 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-7-monad-and-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Previous part introduced SelectMany for monad IEnumerable&amp;lt;&amp;gt;. Actually SelectMany is more than meets the eye, and can be used to implement other LINQ queries.&lt;/p&gt;
&lt;h2&gt;Query methods implemented by SelectMany&lt;/h2&gt;
&lt;p&gt;This part will demonstrate how to use SelectMany to implement following LINQ query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restriction: Where&lt;/li&gt;
&lt;li&gt;Projection: Select&lt;/li&gt;
&lt;li&gt;Join: Join, GroupJoin&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Set: Zip, Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Cancatening: Concat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, create a help method to make the code shorter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class EnumerableSelectManyExtensions
{
    // value.Enumerable(isNotEmpty) is the alias of (isNotEmpty ? value.Enumerable() : Enumerable.Empty&amp;lt;TSource&amp;gt;())
    public static IEnumerable&amp;lt;TSource&amp;gt; Enumerable&amp;lt;TSource&amp;gt;(this TSource value, bool isNotEmpty = false)
    {
        // return isNotEmpty ? EnumerableEx.Return(value) : Enumerable.Empty&amp;lt;TSource&amp;gt;();
        if (isNotEmpty)
        {
            yield return value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here comes this long list of 15 methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second)
{
    return new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }
        .SelectMany(Functions.Id);
}

public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    return source
        .SelectMany(value =&amp;gt; value.Enumerable(hashSet.Add(value)));
}

public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(second, comparer);
    return first
        .SelectMany(firstValue =&amp;gt; firstValue.Enumerable(hashSet.Add(firstValue)));
}

public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    // return source.ToLookup(keySelector, elementSelector, comparer);
    HashSet&amp;lt;TKey&amp;gt; hashSet = new HashSet&amp;lt;TKey&amp;gt;(comparer);
    return source
        .SelectMany(value =&amp;gt; keySelector(value).Enumerable())
        .SelectMany(key =&amp;gt; key.Enumerable(hashSet.Add(key)))
        // Microsoft.FSharp.Linq.RuntimeHelpers.Grouping&amp;lt;K, T&amp;gt;
        .SelectMany(key =&amp;gt; new Grouping&amp;lt;TKey, TElement&amp;gt;(key, source
            // SelectMany inside SelectMany. Time complexity is O(N * N).
            .SelectMany(value =&amp;gt; elementSelector(value).Enumerable(comparer.Equals(key, keySelector(value))))).Enumerable());
}

public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; lookup = inner.ToLookup(innerKeySelector, comparer); // Lookup&amp;lt;TKey, TInner&amp;gt; cannot be created by public API.
    return outer
        .SelectMany(outerValue =&amp;gt; resultSelector(outerValue, lookup[outerKeySelector(outerValue)]).Enumerable());
}

public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(second, comparer);
    return first
        .SelectMany(firstValue =&amp;gt; firstValue.Enumerable(hashSet.Remove(firstValue)));
}

public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; lookup = inner.ToLookup(innerKeySelector, comparer); // Lookup&amp;lt;TKey, TInner&amp;gt; cannot be created by public API.
    return outer
        .SelectMany(outerValue =&amp;gt; lookup[outerKeySelector(outerValue)]
            .SelectMany(innerValue =&amp;gt; resultSelector(outerValue, innerValue).Enumerable()));
}

public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    return source.SelectMany(
        sourceValue =&amp;gt; selector(sourceValue).Enumerable());
}

public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    return source
        .SelectMany((value, index) =&amp;gt; value.Enumerable(index &amp;gt;= count));
}

public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    bool flag = false;
    return source
        .SelectMany(value =&amp;gt;
        {
            if (!flag &amp;amp;&amp;amp; !predicate(value))
            {
                flag = true; // Imperative.
            }

            return value.Enumerable(flag);
        });
}

public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    return source
        .SelectMany((value, index) =&amp;gt; value.Enumerable(index &amp;lt; count));
}

public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    bool flag = true;
    return source
        .SelectMany(value =&amp;gt;
        {
            if (!predicate(value))
            {
                flag = false; // Imperative.
            }

            return value.Enumerable(flag);
        });
}

public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    return new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }
        .SelectMany(Functions.Id)
        .SelectMany(value =&amp;gt; value.Enumerable(hashSet.Add(value)));
}

public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    return source
        .SelectMany(value =&amp;gt; value.Enumerable(predicate(value)));
}

public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(
    this IEnumerable&amp;lt;TFirst&amp;gt; first, IEnumerable&amp;lt;TSecond&amp;gt; second, Func&amp;lt;TFirst, TSecond, TResult&amp;gt; resultSelector)
{
    return first
        .SelectMany((firstValue, index) =&amp;gt; second
            // SelectMany inside SelectMany. Time complexity is O(N * N).
            .SelectMany((value, index2) =&amp;gt; value.Enumerable(index2 == index)), resultSelector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again these code are just for demonstration purpose. The performance of above code is no better than the built-in implementation in System.Linq.Enumerable. Also, some of above SelectMany code is imperative, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Skip, Take, Zip use the index&lt;/li&gt;
&lt;li&gt;SkipWhile and TakeWhile use a variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So these SelectMany usages are not authentically functional.&lt;/p&gt;
&lt;h3&gt;Query methods in LINQ syntax&lt;/h3&gt;
&lt;p&gt;Above implementations in LINQ syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second)
{
    return from enumerable in new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }
           from value in enumerable
           select value;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    return from value in source
           // where hashSet.Add(value)
           from distinct in value.Enumerable(hashSet.Add(value))
           select distinct;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(second, comparer);
    return from value in first
           // where hashSet.Add(value)
           from except in value.Enumerable(hashSet.Add(value))
           select except;
}

public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    HashSet&amp;lt;TKey&amp;gt; hashSet = new HashSet&amp;lt;TKey&amp;gt;(comparer);
    return from value in source
           let key = keySelector(value)
           // where hashSet.Add(key)
           from distinctKey in key.Enumerable(hashSet.Add(key))
           select new Grouping&amp;lt;TKey, TElement&amp;gt;(
               distinctKey,
               from value2 in source
               // where comparer.Equals(distinctKey, keySelector(value2))
               from element in elementSelector(value).Enumerable(comparer.Equals(key, keySelector(value2)))
               select elementSelector(value2));
}

public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; lookup = inner.ToLookup(innerKeySelector, comparer);
    return from outerValue in outer
           // select resultSelector(outerValue, lookup[outerKeySelector(outerValue)])
           from result in resultSelector(outerValue, lookup[outerKeySelector(outerValue)]).Enumerable()
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(second, comparer);
    return from firstValue in first
           // where hashSet.Remove(firstValue)
           from intersect in firstValue.Enumerable(hashSet.Remove(firstValue))
           select intersect;
}

public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; lookup = inner.ToLookup(innerKeySelector, comparer); // Lookup&amp;lt;TKey, TInner&amp;gt; cannot be created by public API.
    return from outerValue in outer
           from result in
               (from innerValue in lookup[outerKeySelector(outerValue)]
               // select resultSelector(outerValue, innerValue)
               from result2 in resultSelector(outerValue, innerValue).Enumerable()
               select result2)
           select result;
}

public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    return from value in source
           // select selector(value)
           from result in selector(value).Enumerable()
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    int index = 0;
    return from value in source
           // where index++ &amp;gt;= count
           from result in value.Enumerable(index++ &amp;gt;= count)
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    bool flag = false;
    return from value in source
           let _ = (!flag &amp;amp;&amp;amp; !predicate(value)) &amp;amp;&amp;amp; (flag = true)
           from result in value.Enumerable(flag)
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    int index = 0;
    return from value in source
           // where index++ &amp;lt; count
           from result in value.Enumerable(index++ &amp;lt; count)
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    bool flag = true;
    return from value in source
           let _ = (predicate(value)) || (flag = false)
           from result in value.Enumerable(flag)
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    return from enumerable in new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }
           from value in enumerable
           // where hashSet.Add(value)
           from result in value.Enumerable(hashSet.Add(value))
           select result;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    return from value in source
           from result in value.Enumerable(predicate(value))
           select result;
}

public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(
    this IEnumerable&amp;lt;TFirst&amp;gt; first, IEnumerable&amp;lt;TSecond&amp;gt; second, Func&amp;lt;TFirst, TSecond, TResult&amp;gt; resultSelector)
{
    int firstIndex = 0;
    int secondIndex = 0;
    return from firstValue in first
           let currentFirstIndex = firstIndex++
           let _ = secondIndex = 0
           from secondResult in
               (from secondValue in second
               // where firstIndex2 == secondIndex++
               // let secondIndex3 = secondIndex++
               from secondResult in secondValue.Enumerable(currentFirstIndex == secondIndex++)
               select secondResult)
           select resultSelector(firstValue, secondResult);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice that Skip, Take, Zip, SkipWhile and TakeWhile uses &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb383976.aspx&quot;&gt;let clause&lt;/a&gt; as trick.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;Once again, a long tedious list of test code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class EnumerableSelectManyExtensionsTests
{
    [TestMethod()]
    public void ConcatTest()
    {
        int[] first = new int[] { 0, 1, 2 };
        int[] second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Concat(first, second), 
            EnumerableSelectManyExtensions.Concat(first, second));

        first = new int[] { };
        second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Concat(first, second), 
            EnumerableSelectManyExtensions.Concat(first, second));

        first = new int[] { 0, 1, 2 };
        second = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Concat(first, second), 
            EnumerableSelectManyExtensions.Concat(first, second));
    }

    [TestMethod()]
    public void DistinctTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Distinct(enumerable), 
            EnumerableSelectManyExtensions.Distinct(enumerable, EqualityComparer&amp;lt;int&amp;gt;.Default));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Distinct(enumerable), 
            EnumerableSelectManyExtensions.Distinct(enumerable, EqualityComparer&amp;lt;int&amp;gt;.Default));
    }

    [TestMethod()]
    public void ExceptTest()
    {
        int[] first = new int[] { 0, 1, 2 };
        int[] second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Except(first, second), 
            EnumerableSelectManyExtensions.Except(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Except(first, second), 
            EnumerableSelectManyExtensions.Except(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { };
        second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Except(first, second), 
            EnumerableSelectManyExtensions.Except(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { 2, 3, 4 };
        EnumerableAssert.AreEqual(
            Enumerable.Except(first, second), 
            EnumerableSelectManyExtensions.Except(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));
    }

    [TestMethod()]
    public void GroupByTest()
    {
        int[] enumerable = new int[] { 0, 1, 2, 4, 5, 6 };
        IGrouping&amp;lt;int, int&amp;gt;[] expected = Enumerable.GroupBy(enumerable, value =&amp;gt; value % 3, value =&amp;gt; value).ToArray();
        IGrouping&amp;lt;int, int&amp;gt;[] actual = EnumerableSelectManyExtensions.GroupBy(enumerable, value =&amp;gt; value % 3, value =&amp;gt; value, EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((group, index) =&amp;gt;
            {
                Assert.AreEqual(group.Key, actual[index].Key);
                EnumerableAssert.AreEqual(group, actual[index]);
            });

        enumerable = new int[] { };
        expected = Enumerable.GroupBy(enumerable, value =&amp;gt; value % 3, value =&amp;gt; value).ToArray();
        actual = EnumerableSelectManyExtensions.GroupBy(enumerable, value =&amp;gt; value % 3, value =&amp;gt; value, EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((group, index) =&amp;gt;
            {
                Assert.AreEqual(group.Key, actual[index].Key);
                EnumerableAssert.AreEqual(group, actual[index]);
            });
    }

    [TestMethod()]
    public void GroupJoinTest()
    {
        Tuple&amp;lt;int, string&amp;gt;[] categories = new Tuple&amp;lt;int, string&amp;gt;[]
                                            {
                                                new Tuple&amp;lt;int, string&amp;gt;(1, &quot;A&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(2, &quot;B&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(3, &quot;C&quot;), 
                                            };
        Tuple&amp;lt;int, string, int&amp;gt;[] products = new Tuple&amp;lt;int, string, int&amp;gt;[]
                                                {
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(1, &quot;aa&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(2, &quot;bb&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(3, &quot;cc&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(4, &quot;dd&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(5, &quot;ee&quot;, 2), 
                                                };
        Tuple&amp;lt;string, int&amp;gt;[] expected = Enumerable.GroupJoin(
            categories,
            products,
            category =&amp;gt; category.Item1,
            product =&amp;gt; product.Item3,
            (category, categoryProducts) =&amp;gt; new Tuple&amp;lt;string, int&amp;gt;(category.Item2, categoryProducts.Count())).ToArray();
        Tuple&amp;lt;string, int&amp;gt;[] actual = EnumerableSelectManyExtensions.GroupJoin(
            categories,
            products,
            category =&amp;gt; category.Item1,
            product =&amp;gt; product.Item3,
            (category, categoryProducts) =&amp;gt; new Tuple&amp;lt;string, int&amp;gt;(category.Item2, categoryProducts.Count()),
            EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((product, index) =&amp;gt;
            {
                Assert.AreEqual(product.Item1, actual[index].Item1);
                Assert.AreEqual(product.Item2, actual[index].Item2);
            });
    }

    [TestMethod()]
    public void IntersectTest()
    {
        int[] first = new int[] { 0, 1, 2 };
        int[] second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Intersect(first, second), 
            EnumerableSelectManyExtensions.Intersect(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Intersect(first, second), 
            EnumerableSelectManyExtensions.Intersect(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { };
        second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Intersect(first, second), 
            EnumerableSelectManyExtensions.Intersect(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { 2, 3, 4 };
        EnumerableAssert.AreEqual(
            Enumerable.Intersect(first, second), 
            EnumerableSelectManyExtensions.Intersect(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));
    }

    [TestMethod()]
    public void JoinTest()
    {
        Tuple&amp;lt;int, string, int&amp;gt;[] products = new Tuple&amp;lt;int, string, int&amp;gt;[]
                                                {
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(1, &quot;aa&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(2, &quot;bb&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(3, &quot;cc&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(4, &quot;dd&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(5, &quot;ee&quot;, 2), 
                                                };
        Tuple&amp;lt;int, string&amp;gt;[] categories = new Tuple&amp;lt;int, string&amp;gt;[]
                                            {
                                                new Tuple&amp;lt;int, string&amp;gt;(1, &quot;A&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(2, &quot;B&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(3, &quot;C&quot;), 
                                            };
        Tuple&amp;lt;string, string&amp;gt;[] expected = Enumerable.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2)).ToArray();
        Tuple&amp;lt;string, string&amp;gt;[] actual = EnumerableSelectManyExtensions.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2),
            EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((product, index) =&amp;gt;
            {
                Assert.AreEqual(product.Item1, actual[index].Item1);
                Assert.AreEqual(product.Item2, actual[index].Item2);
            });

        products = new Tuple&amp;lt;int, string, int&amp;gt;[]
                                                {
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(1, &quot;aa&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(2, &quot;bb&quot;, 1), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(3, &quot;cc&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(4, &quot;dd&quot;, 2), 
                                                    new Tuple&amp;lt;int, string, int&amp;gt;(5, &quot;ee&quot;, 2), 
                                                };
        categories = new Tuple&amp;lt;int, string&amp;gt;[] { };
        expected = Enumerable.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2)).ToArray();
        actual = EnumerableSelectManyExtensions.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2),
            EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((product, index) =&amp;gt;
            {
                Assert.AreEqual(product.Item1, actual[index].Item1);
                Assert.AreEqual(product.Item2, actual[index].Item2);
            });

        products = new Tuple&amp;lt;int, string, int&amp;gt;[] { };
        categories = new Tuple&amp;lt;int, string&amp;gt;[]
                                            {
                                                new Tuple&amp;lt;int, string&amp;gt;(1, &quot;A&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(1, &quot;B&quot;), 
                                                new Tuple&amp;lt;int, string&amp;gt;(1, &quot;C&quot;), 
                                            };
        expected = Enumerable.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2)).ToArray();
        actual = EnumerableSelectManyExtensions.Join(
            products,
            categories,
            product =&amp;gt; product.Item3,
            category =&amp;gt; category.Item1,
            (product, category) =&amp;gt; new Tuple&amp;lt;string, string&amp;gt;(category.Item2, product.Item2),
            EqualityComparer&amp;lt;int&amp;gt;.Default).ToArray();
        Assert.AreEqual(expected.Count(), actual.Count());
        expected.ForEach((product, index) =&amp;gt;
            {
                Assert.AreEqual(product.Item1, actual[index].Item1);
                Assert.AreEqual(product.Item2, actual[index].Item2);
            });
    }

    [TestMethod()]
    public void SelectTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Select(enumerable, x =&amp;gt; x.ToString()), 
            EnumerableSelectManyExtensions.Select4(enumerable, x =&amp;gt; x.ToString()));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Select(enumerable, x =&amp;gt; x.ToString()), 
            EnumerableSelectManyExtensions.Select4(enumerable, x =&amp;gt; x.ToString()));
    }

    [TestMethod()]
    public void SkipTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Skip(enumerable, 2), 
            EnumerableSelectManyExtensions.Skip(enumerable, 2));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Skip(enumerable, 0), 
            EnumerableSelectManyExtensions.Skip(enumerable, 0));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Skip(enumerable, -1), 
            EnumerableSelectManyExtensions.Skip(enumerable, -1));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Skip(enumerable, 100), 
            EnumerableSelectManyExtensions.Skip(enumerable, 100));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Skip(enumerable, 100), 
            EnumerableSelectManyExtensions.Skip(enumerable, 100));
    }

    [TestMethod()]
    public void SkipWhileTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0));

        enumerable = new int[] { 2, 1, 0, -1 };
        EnumerableAssert.AreEqual(
            Enumerable.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.SkipWhile(enumerable, x =&amp;gt; x &amp;gt; 0));
    }

    [TestMethod()]
    public void TakeTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Take(enumerable, 2), 
            EnumerableSelectManyExtensions.Take(enumerable, 2));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Take(enumerable, 0), 
            EnumerableSelectManyExtensions.Take(enumerable, 0));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Take(enumerable, -1), 
            EnumerableSelectManyExtensions.Take(enumerable, -1));

        enumerable = new int[] { 0, 1, 1, 1, 2, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Take(enumerable, 100), 
            EnumerableSelectManyExtensions.Take(enumerable, 100));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Take(enumerable, 100), 
            EnumerableSelectManyExtensions.Take(enumerable, 100));
    }

    [TestMethod()]
    public void TakeWhileTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0));

        enumerable = new int[] { 2, 1, 0, -1 };
        EnumerableAssert.AreEqual(
            Enumerable.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.TakeWhile(enumerable, x =&amp;gt; x &amp;gt; 0));
    }

    [TestMethod()]
    public void UnionTest()
    {
        int[] first = new int[] { 0, 1, 2 };
        int[] second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Union(first, second), 
            EnumerableSelectManyExtensions.Union(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Union(first, second), 
            EnumerableSelectManyExtensions.Union(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { };
        second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Union(first, second), 
            EnumerableSelectManyExtensions.Union(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));

        first = new int[] { 0, 1, 2 };
        second = new int[] { 2, 3, 4 };
        EnumerableAssert.AreEqual(
            Enumerable.Union(first, second), 
            EnumerableSelectManyExtensions.Union(first, second, EqualityComparer&amp;lt;int&amp;gt;.Default));
    }

    [TestMethod()]
    public void WhereTest()
    {
        int[] enumerable = new int[] { 0, 1, 2 };
        EnumerableAssert.AreEqual(
            Enumerable.Where(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.Where(enumerable, x =&amp;gt; x &amp;gt; 0));

        enumerable = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Where(enumerable, x =&amp;gt; x &amp;gt; 0), 
            EnumerableSelectManyExtensions.Where(enumerable, x =&amp;gt; x &amp;gt; 0));
    }

    [TestMethod()]
    public void ZipTest()
    {
        int[] first = new int[] { 0, 1, 2 };
        int[] second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));

        first = new int[] { 0, 1, 2 };
        second = new int[] { };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));

        first = new int[] { };
        second = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));

        first = new int[] { 0, 1, 2 };
        second = new int[] { 2, 3, 4 };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));

        first = new int[] { 0, 1 };
        second = new int[] { 2, 3, 4 };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));

        first = new int[] { 0, 1, 2 };
        second = new int[] { 2, 3 };
        EnumerableAssert.AreEqual(
            Enumerable.Zip(first, second, (x, y) =&amp;gt; x * y), 
            EnumerableSelectManyExtensions.Zip(first, second, (x, y) =&amp;gt; x * y));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (14) Monad And IEnumerable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-14-monad-and-ienumerable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-14-monad-and-ienumerable/</guid><description>A previous part showed endofunctor category is a monoid (the entire category itself). An endofunctor In the endofunctor category can be monoid too. This kind of endofunctor is called monad. Formally,</description><pubDate>Sat, 15 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-7-monad-and-linq-to-monads&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-7-monad-and-linq-to-monads&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Monad and monad laws&lt;/h2&gt;
&lt;p&gt;A previous part showed endofunctor category is a monoid (the entire category itself). An endofunctor In the endofunctor category can be monoid too. This kind of endofunctor is called monad. Formally, &lt;a href=&quot;http://en.wikipedia.org/wiki/Monad_(category_theory)&quot;&gt;monad&lt;/a&gt; is an endofunctor of category C, equipped with 2 natural transformations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monoid binary operation, which a natural transformation μ: F ◎ F ⇒ F, where
&lt;ul&gt;
&lt;li&gt;(F ◎ F)(X) is F(F(X)), also denoted F2&lt;/li&gt;
&lt;li&gt;Similarly, (F ◎ F ◎ F)(X) is F(F(F(X))), also denoted F3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monoid unit, which is a natural transformation η: Id(X) ⇒ F(X)
&lt;ul&gt;
&lt;li&gt;Id (with an upper case I) is the Id endofunctor of C, not the id morphism&lt;/li&gt;
&lt;li&gt;Since functor Id(X) is merely a simple wrapper of X (e.g., in DotNet category, the Id endofunctor is just Lazy&amp;lt;X&amp;gt;), so in category C, the natural transformation η: Id(X) ⇒ F(X) is frequently simplified to morphism η: X → F(x)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;satisfying the monoid laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Left unit law λ: μ(η ◎ F) ≌ F&lt;/li&gt;
&lt;li&gt;Right unit law ρ: F ≌ μ(F ◎ η)&lt;/li&gt;
&lt;li&gt;Associative law α: μ(F ◎ F) ◎ F) ≌ F ◎ μ(F ◎ F)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;so that, similar to Monoid diagrams, there are:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-14-Monad_1276B/image_8.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-14-Monad_1276B/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-14-Monad_1276B/Untitled-1.fw_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-14-Monad_1276B/Untitled-1.fw_thumb.png&quot; alt=&quot;Untitled-1.fw&quot; title=&quot;Untitled-1.fw&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;commute.&lt;/p&gt;
&lt;p&gt;So, monad (F, μ, η) is monoid (M, ⊙, I). Its representation in pseudo C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IMonad&amp;lt;TCategory, TBinaryFunctor&amp;lt; , &amp;gt;, TUnit, TMonad&amp;lt;&amp;gt;&amp;gt;
    : IMonoidalFunctor&amp;lt;TCategory, TCategory, TBinaryFunctor&amp;lt; , &amp;gt;, TBinaryFunctor&amp;lt; , &amp;gt;, TUnit, TUnit, TMonad&amp;lt;&amp;gt;&amp;gt;
    where TMonad&amp;lt;&amp;gt; : IMonad&amp;lt;TCategory, TBinaryFunctor&amp;lt; , &amp;gt;, TBinaryFunctor&amp;lt; , &amp;gt;, TMonad&amp;lt;&amp;gt;&amp;gt;
    where TCategory : IMonoidalCategory&amp;lt;TCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
{
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TMonad&amp;lt;TSource&amp;gt; -&amp;gt; TMonad&amp;lt;TResult&amp;gt;)

    // φ: TBinaryFunctor&amp;lt;TMonad&amp;lt;T1&amp;gt;, TMonad&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; TMonad&amp;lt;TBinaryFunctor&amp;lt;T1, T2&amp;gt;&amp;gt;

    // ι: TUnit -&amp;gt; TMonad&amp;lt;TUnit&amp;gt;

    // μ: TMonad&amp;lt;&amp;gt; ◎ TMonad&amp;lt;&amp;gt; =&amp;gt; TMonad&amp;lt;&amp;gt;
    TMonad&amp;lt;TSource&amp;gt; Flatten&amp;lt;TSource&amp;gt;(TMonad&amp;lt;TMonad&amp;lt;TSource&amp;gt;&amp;gt; source);

    // η: Id&amp;lt;T&amp;gt; =&amp;gt; TMonad&amp;lt;T&amp;gt;, equivalent to T -&amp;gt; TMonad&amp;lt;T&amp;gt;
    TMonad&amp;lt;TSource&amp;gt; Monad&amp;lt;TSource&amp;gt;(TSource value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;μ is called flatten, and η is called Monad, since it is like a constructor of a monad.&lt;/p&gt;
&lt;p&gt;Monad is monoidal functor, which will be explained later.&lt;/p&gt;
&lt;h2&gt;C#/.NET monads&lt;/h2&gt;
&lt;p&gt;A previous part has explained DotNet category is monoid category. So monad in DotNet category will be like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IDotNetMonad&amp;lt;TDotNetMonad&amp;lt;&amp;gt;&amp;gt; 
    : IMonad&amp;lt;DotNet, Lazy&amp;lt; , &amp;gt;, Unit, TDotNetMonad&amp;lt;&amp;gt;&amp;gt;
    where TDotNetMonad&amp;lt;&amp;gt; : IDotNetMonad&amp;lt;TDotNetMonad&amp;lt;&amp;gt;&amp;gt;
{
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TDotNetMonad&amp;lt;TSource&amp;gt; -&amp;gt; TDotNetMonad&amp;lt;TResult&amp;gt;)

    // φ: Lazy&amp;lt;TDotNetMonad&amp;lt;T1&amp;gt;, TDotNetMonad&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; TDotNetMonad&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;

    // ι: TUnit -&amp;gt; TDotNetMonad&amp;lt;TUnit&amp;gt;

    // μ: TDotNetMonad&amp;lt;&amp;gt; ◎ TDotNetMonad&amp;lt;&amp;gt; =&amp;gt; TDotNetMonad&amp;lt;&amp;gt;

    // η: Lazy&amp;lt;T&amp;gt; =&amp;gt; TDotNetMonad&amp;lt;T&amp;gt;, equivalent to T -&amp;gt; TDotNetMonad&amp;lt;T&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As usual, Flatten and Monad will be implemented as extension methods.&lt;/p&gt;
&lt;h2&gt;IEnumerable&amp;lt;&amp;gt; monad and SelectMany&lt;/h2&gt;
&lt;p&gt;IEnumerable&amp;lt;&amp;gt; is the built-in monad, which is similar to the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Base.html#line-726&quot;&gt;Haskell List monad&lt;/a&gt;. Its Flatten (μ) extension method easy to implement with the yield syntactic sugar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TSource&amp;gt; Flatten&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; source)
    {
        foreach (IEnumerable&amp;lt;TSource&amp;gt; enumerable in source)
        {
            foreach (TSource value in enumerable)
            {
                yield return value;
            }
        }
    }

    public static IEnumerable&amp;lt;T&amp;gt; Enumerable&amp;lt;T&amp;gt;(this T value)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And its Monad (η) extension method is called Enumerable instead of Monad, because Enumerable is more specific than the general abstract name Monad. The enumerable function here is exactly the same Enumerable for monoidal functor IEnumerable&amp;lt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;In C#/LINQ, monad is implemented as another extension method called SelectMany. As a functor, IEnumerable&amp;lt;&amp;gt; already has a Select extension method, now with Flatten and Select, SelectMany is easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TSelector, TResult&amp;gt;
    (this IEnumerable&amp;lt;TSource&amp;gt; source, 
        Func&amp;lt;TSource, IEnumerable&amp;lt;TSelector&amp;gt;&amp;gt; selector, 
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector) =&amp;gt;
            // (from sourceItem in source
            //     select (from selectorItem in selector(sourceItem)
            //         select resultSelector(sourceItem, selectorItem))).Flatten();
            source.Select(sourceValue =&amp;gt; selector(sourceValue)
                    .Select(selectorValue =&amp;gt; resultSelector(sourceValue, selectorValue)))
                .Flatten();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, (SelectMany + Enumerable) is equivalent to (Flatten + Enumerable), either pair makes IEnumerable&amp;lt;&amp;gt; a monad. That is, (SelectMany + Enumerable) and (Flatten + Enumerable) can replace each other. So above Flatten can be implemented by SelectMany too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany2&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, IEnumerable&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector)
    {
        foreach (TSource sourceItem in source)
        {
            foreach (TSelector selectorItem in selector(sourceItem))
            {
                yield return resultSelector(sourceItem, selectorItem);
            }
        }
    }

    public static IEnumerable&amp;lt;TSource&amp;gt; Flatten2&amp;lt;TSource&amp;gt;
        (this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; source) =&amp;gt;
            // source.SelectMany(enumerable =&amp;gt; enumerable);
            source.SelectMany2(Functions.Id);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows SelectMany is more powerful than Flatten, because Flatten is just a special case of SelectMany - SelectMany(Functions.Id). The future monad posts will focus on SelectMany extension methods of the monads. In other languages, e.g. in Haskell, SelectMany is called Bind.&lt;/p&gt;
&lt;p&gt;.NET also provide a SelectMany overload without the last parameter resultSelector, which is so easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;
    (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
        source.SelectMany(selector, (sourceValue, selectorValue) =&amp;gt; selectorValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last lambda expression, (sourveValue, resultValue) =&amp;gt; resultValue, is similar to &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Church Boolean&lt;/a&gt;’s &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;generic version of False function&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    // False = @true =&amp;gt; @false =&amp;gt; @false
    public static Func&amp;lt;TFalse, object&amp;gt; False&amp;lt;TTrue, TFalse&amp;gt;
        (TTrue @true) =&amp;gt; @false =&amp;gt; @false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, if defining a uncurried version of above function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class Functions
{
    public static TFalse False&amp;lt;TTrue, TFalse&amp;gt;
        (TTrue @true, TFalse @false) =&amp;gt; @false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then above SelectMany implementation can be even shorter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany2&amp;lt;TSource, TResult&amp;gt;
    (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
        source.SelectMany(selector, Functions.False);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is monoid&lt;/h3&gt;
&lt;p&gt;As above shown:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    // η: Lazy&amp;lt;T&amp;gt; =&amp;gt; IEnumerable&amp;lt;T&amp;gt;
    // or
    // η: T -&amp;gt; IEnumerable&amp;lt;T&amp;gt;
    public static IEnumerable&amp;lt;T&amp;gt; Enumerable&amp;lt;T&amp;gt;(this T value)
    {
        yield return value;
    }

    // μ: IEnumerable&amp;lt;&amp;gt; ◎ IEnumerable&amp;lt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;&amp;gt;
    // or 
    // μ: IEnumerable&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;T&amp;gt;
    public static IEnumerable&amp;lt;TSource&amp;gt; Flatten&amp;lt;TSource&amp;gt;
        (this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; source) =&amp;gt; source.SelectMany(Functions.Id);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it satisfies the monoid laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public partial class MonadTests
{
    [TestMethod()]
    public void EnumerableMonoidTest()
    {
        // Left unit law: μ(η ∘ F) == F
        EnumerableAssert.AreEqual(
            new Enumerable&amp;lt;int&amp;gt;(1).Enumerable().Flatten(), 
            new Enumerable&amp;lt;int&amp;gt;(1));

        // Right unit law: F == μ(F ∘ η)
        EnumerableAssert.AreEqual(
            new Enumerable&amp;lt;int&amp;gt;(1), 
            new Enumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt;(1.Enumerable()).Flatten());

        // Associative law: μ(F ∘ F) ∘ F) == F ∘ μ(F ∘ F)
        IEnumerable&amp;lt;Enumerable&amp;lt;int&amp;gt;&amp;gt; left = new Enumerable&amp;lt;int&amp;gt;(1).Enumerable().Enumerable().Flatten();
        IEnumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; right = new Enumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt;(new Enumerable&amp;lt;int&amp;gt;(1)).Flatten().Enumerable();
        Assert.AreEqual(left.Count(), right.Count());
        for (int i = 0; i &amp;lt; left.Count(); i++)
        {
            EnumerableAssert.AreEqual(left.Skip(i-1).Take(1).Single(), right.Skip(i - 1).Take(1).Single());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;μ is the Flatten function&lt;/li&gt;
&lt;li&gt;η is the Enumerable function&lt;/li&gt;
&lt;li&gt;◎ can be read after&lt;/li&gt;
&lt;li&gt;To distinguish from η, sometimes F is represented by following Enumerable class:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public class Enumerable&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;
{
    private readonly T value;

    public Enumerable(T value)
    {
        this.value = value;
    }

    [Pure]
    public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()
    {
        yield return this.value;
    }

    [Pure]
    IEnumerator IEnumerable.GetEnumerator
        () =&amp;gt; this.GetEnumerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is monoidal functor&lt;/h3&gt;
&lt;p&gt;As a monad, IEnumerable can always implement (Binary + Unit) with (SelectMany + Enumerable):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    // φ: Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt; 
            binaryFunctor.Value1.SelectMany(
                value1 =&amp;gt; binaryFunctor.Value2,
                (value1, value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2));

    // ι: Unit -&amp;gt; IEnumerable&amp;lt;Unit&amp;gt;
    public static IEnumerable&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Enumerable();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures IEnumerable&amp;lt;&amp;gt; monad (SelectMany + Enumerable) is a monoidal functor.&lt;/p&gt;
&lt;h3&gt;IEnumerable&amp;lt;&amp;gt; monad (SelectMany) is functor&lt;/h3&gt;
&lt;p&gt;As a monad, IEnumerable can always implement Select too, (SelectMany + Enumerable):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    // Select: (TSource -&amp;gt; TResult) -&amp;gt; (TDotNetMonad&amp;lt;TSource&amp;gt; -&amp;gt; TDotNetMonad&amp;lt;TResult&amp;gt;)
    public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            source.SelectMany(sourceValue =&amp;gt; selector(sourceValue).Enumerable(), Functions.False);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures IEnumerable&amp;lt;&amp;gt; monad/monoidal functor (SelectMany + Enumerable) is a functor.&lt;/p&gt;
&lt;h2&gt;Monad pattern of LINQ&lt;/h2&gt;
&lt;p&gt;Generally in .NET, if a generic type F&amp;lt;TSource&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;has a instance method or extension method SelectMany, which:
&lt;ul&gt;
&lt;li&gt;takes a Func&amp;lt;TSource, F&amp;lt;TSelector&amp;gt;&amp;gt; parameter&lt;/li&gt;
&lt;li&gt;and a Func&amp;lt;TSource, TSelector, TResult&amp;gt; parameter&lt;/li&gt;
&lt;li&gt;and returns a F&amp;lt;TResult&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;then:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F&amp;lt;&amp;gt; is a C#/LINQ monad, and its SelectMany method can be recognized by C# compiler, so the LINQ syntax can be used:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, with the built in System.Linq.Enumerable.SelectMany implementation, these “&quot;compound “from” LINQ queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TResult&amp;gt; Select3&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            from sourceValue in source
            from selectorValue in selector(sourceValue).Enumerable()
            select selectorValue;

    public static IEnumerable&amp;lt;TSource&amp;gt; Flatten3&amp;lt;TSource&amp;gt;
        (this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; source) =&amp;gt;
            from enumerable in source
            from value in enumerable
            select value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be compiled to SelectMany applications:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TResult&amp;gt; Select4&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            source.SelectMany(
                sourceValue =&amp;gt; selector(sourceValue).Enumerable(),
                (sourceValue, selectorValue) =&amp;gt; selectorValue);

    public static IEnumerable&amp;lt;TSource&amp;gt; Flatten4&amp;lt;TSource&amp;gt;
        (this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; source) =&amp;gt;
            source.SelectMany(enumerable =&amp;gt; enumerable);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For any .NET generic type F&amp;lt;&amp;gt; with such a SelectMany instance/extension method, if F&amp;lt;X&amp;gt; also satisfies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F&amp;lt;T&amp;gt; can be constructed directly from T value(s)&lt;/li&gt;
&lt;li&gt;its SelectMany method (either instance or extension) is pure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;then F&amp;lt;&amp;gt; is a general abstract monad of category theory too.&lt;/p&gt;
&lt;p&gt;Here an IEnumerable&amp;lt;T&amp;gt; can be constructed from 0 or more T values in many ways. And in NET, IEnumerable&amp;lt;T&amp;gt;’s built in SelectMany implementation is pure (yes, it is the same as the SelectMany2 function above):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
{
    [Pure]
    public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany2&amp;lt;TSource, TSelector, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, IEnumerable&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;TSource, TSelector, TResult&amp;gt; resultSelector)
    {
        foreach (TSource sourceItem in source)
        {
            foreach (TSelector selectorItem in selector(sourceItem))
            {
                yield return resultSelector(sourceItem, selectorItem);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So finally, the essence of LINQ has been touched, as &lt;a href=&quot;https://www.linkedin.com/in/brianbeckman&quot;&gt;Brian Beckman&lt;/a&gt; said in &lt;a href=&quot;http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads&quot;&gt;this Channel 9 video&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LINQ is monad. It is very carefully designed by &lt;a href=&quot;http://en.wikipedia.org/wiki/Erik_Meijer_(computer_scientist)&quot;&gt;Erik Meijer&lt;/a&gt; so that it is monad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://ericlippert.com&quot;&gt;Eric Lippert&lt;/a&gt; also &lt;a href=&quot;http://stackoverflow.com/questions/4683506/are-there-any-connections-between-haskell-and-linq&quot;&gt;mentioned&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The LINQ syntax is designed specifically to make operations on the sequence monad feel natural, but in fact the implementation is more general; what C# calls &quot;SelectMany&quot; is a slightly modified form of the &quot;Bind&quot; operation on an arbitrary monad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because monad is such an important but psychedelic concept, later parts will continue to demystify other monads via C#: Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Null&amp;lt;&amp;gt;, ParallelQuery&amp;lt;&amp;gt;, IObservable&amp;lt;&amp;gt;, IO monad, state monad, reader monad, writer monad, continuation monad, and even more.&lt;/p&gt;
&lt;h2&gt;Monad laws, and unit test&lt;/h2&gt;
&lt;p&gt;As fore mentioned, a monad is a monoid in the endofunctor category, so monad follows the monoid laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Left unit law: μ(η ◎ T) ≌ T&lt;/li&gt;
&lt;li&gt;Right unit law: T ≌ μ(T ◎ η)&lt;/li&gt;
&lt;li&gt;Associative law: μ(T ◎ T) ◎ T) ≌ T ◎ μ(T ◎ T)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now in C#, after introducing Monad (Here Enumerable) as η, SelectMany as a more powerful μ, above general monad law becomes following C# &lt;a href=&quot;http://en.wikipedia.org/wiki/Monad_(functional_programming)#Monad_laws&quot;&gt;monad laws&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Left unit law: m.Monad().SelectMany(f) == f(m)&lt;/li&gt;
&lt;li&gt;Right unit law: M.SelectMany(Monad) == M&lt;/li&gt;
&lt;li&gt;Associative law: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;where M is a monad (here a IEnumerable&amp;lt;&amp;gt;), Monad is the “constructor” function (here Enumerable).&lt;/p&gt;
&lt;p&gt;The following unit tests demonstrates how IEnumerable&amp;lt;&amp;gt; satisfies these laws:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonadTests
{
    [TestMethod()]
    public void EnumerableTest()
    {
        bool isExecuted1 = false;
        IEnumerable&amp;lt;int&amp;gt; enumerable1 = new int[] { 0, 1 };
        IEnumerable&amp;lt;int&amp;gt; enumerable2 = new int[] { 1, 2 };
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; f = x =&amp;gt; y =&amp;gt; { isExecuted1 = true; return x + y; };
        IEnumerable&amp;lt;int&amp;gt; query1 = from x in enumerable1
                                  from y in enumerable2
                                  let z = f(x)(y)
                                  where z &amp;gt; 1
                                  select z;
        Assert.IsFalse(isExecuted1); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 2, 2, 3 }, query1); // Execution.
        Assert.IsTrue(isExecuted1);

        // Monad law 1: m.Monad().SelectMany(f) == f(m)
        Func&amp;lt;int, IEnumerable&amp;lt;int&amp;gt;&amp;gt; addOne = x =&amp;gt; (x + 1).Enumerable();
        EnumerableAssert.AreEqual(1.Enumerable().SelectMany(addOne), addOne(1));
        // Monad law 2: M.SelectMany(Monad) == M
        EnumerableAssert.AreEqual(enumerable1.SelectMany(EnumerableExtensions.Enumerable), enumerable1);
        // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x =&amp;gt; f1(x).SelectMany(f2))
        Func&amp;lt;int, IEnumerable&amp;lt;int&amp;gt;&amp;gt; addTwo = x =&amp;gt; (x + 2).Enumerable();
        EnumerableAssert.AreEqual(
            enumerable2.SelectMany(addOne).SelectMany(addTwo), 
            enumerable2.SelectMany(x =&amp;gt; addOne(x).SelectMany(addTwo)));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (13) Monoidal Functor-like Tuple&lt;&gt; And Task&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-13-monoidal-functor-like-tuple-and-task/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-13-monoidal-functor-like-tuple-and-task/</guid><description>Theoretically, Tuple&lt;&gt; should be counted as the Id&lt;&gt; monoidal functor. However, as previously mentioned, it is lack of laziness.</description><pubDate>Fri, 14 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Tuple&amp;lt;&amp;gt;: lack of laziness&lt;/h2&gt;
&lt;p&gt;Theoretically, Tuple&amp;lt;&amp;gt; should be counted as the Id&amp;lt;&amp;gt; monoidal functor. However, as previously mentioned, it is lack of laziness.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class TupleExtensions
{
    public static Tuple&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this Tuple&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, Tuple&amp;lt;TSource&amp;gt; source) =&amp;gt;
            new Tuple&amp;lt;TResult&amp;gt;(selectorFunctor.Item1(source.Item1));

    public static Tuple&amp;lt;T&amp;gt; Tuple&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; new Tuple&amp;lt;T&amp;gt;(value);

    // φ: Lazy&amp;lt;Tuple&amp;lt;T1&amp;gt;, Tuple&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Tuple&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Tuple&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Tuple&amp;lt;T1&amp;gt;, Tuple&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y))
                .Tuple()
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; Tuple&amp;lt;Unit&amp;gt;
    public static Tuple&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Tuple();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tuple&amp;lt;&amp;gt; is most close to the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/Data-Functor-Identity.html#line-85&quot;&gt;Haskell Id Applicative&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Task&amp;lt;&amp;gt;: lack of purity&lt;/h2&gt;
&lt;p&gt;Task&amp;lt;&amp;gt; also seems monoidal functor, but is lack of purity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    public static async Task&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this Task&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, Task&amp;lt;TSource&amp;gt; source) =&amp;gt;
            (await selectorFunctor)(await source);

    public static Task&amp;lt;T&amp;gt; Task&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; System.Threading.Tasks.Task.FromResult(value);

    // φ: Lazy&amp;lt;Task&amp;lt;T1&amp;gt;, Task&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Task&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Task&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Task&amp;lt;T1&amp;gt;, Task&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y))
                .Task()
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; Func&amp;lt;Unit&amp;gt;
    public static Task&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Task();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;Following unit tests demonstrate the usage of Tuple&amp;lt;&amp;gt; and Task&amp;lt;&amp;gt;. Notice Tuple is lack of laziness, and Task&amp;lt;&amp;gt;’s extension methods work for both cold tasks and hot tasks.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonoidalFunctorTests
{
    [TestMethod()]
    public void TupleTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Tuple&amp;lt;int&amp;gt; query1 = addOne.Tuple().Apply(2.Tuple());
        Assert.IsTrue(isExecuted1); // No laziness.
        Assert.AreEqual(2 + 1, query1.Item1); // Execution.
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(addOne.Tuple().Apply(1.Tuple()).Item1, 1.Tuple().Select(addOne).Item1);
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(id.Tuple().Apply(1.Tuple()).Item1, 1.Tuple().Item1);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Tuple&amp;lt;int&amp;gt; left1 = o.Tuple().Apply(addOne.Tuple()).Apply(addTwo.Tuple()).Apply(1.Tuple());
        Tuple&amp;lt;int&amp;gt; right1 = addOne.Tuple().Apply(addTwo.Tuple().Apply(1.Tuple()));
        Assert.AreEqual(left1.Item1, right1.Item1);
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(addOne.Tuple().Apply(1.Tuple()).Item1, addOne(1).Tuple().Item1);
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Tuple&amp;lt;int&amp;gt; left2 = addOne.Tuple().Apply(1.Tuple());
        Tuple&amp;lt;int&amp;gt; right2 = new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1)).Tuple().Apply(addOne.Tuple());
        Assert.AreEqual(left2.Item1, right2.Item1);
    }

    [TestMethod()]
    public void HotTaskTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; hotAddOne = Task.Run(() =&amp;gt; addOne);
        Task&amp;lt;int&amp;gt; hotTwo = Task.Run(() =&amp;gt; 2);
        Task&amp;lt;int&amp;gt; query1 = hotAddOne.Apply(hotTwo);
        Assert.AreEqual(2 + 1, query1.Result);
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(addOne.Task().Apply(1.Task()).Result, 1.Task().Select(addOne).Result);
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(id.Task().Apply(1.Task()).Result, 1.Task().Result);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Task&amp;lt;int&amp;gt; left1 = o.Task().Apply(addOne.Task()).Apply(addTwo.Task()).Apply(1.Task());
        Task&amp;lt;int&amp;gt; right1 = addOne.Task().Apply(addTwo.Task().Apply(1.Task()));
        Assert.AreEqual(left1.Result, right1.Result);
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(addOne.Task().Apply(1.Task()).Result, addOne(1).Task().Result);
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Task&amp;lt;int&amp;gt; left2 = addOne.Task().Apply(1.Task());
        Task&amp;lt;int&amp;gt; right2 = new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1)).Task().Apply(addOne.Task());
        Assert.AreEqual(left2.Result, right2.Result);
    }

    [TestMethod()]
    public void ColdTaskTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; coldAddOne = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addOne);
        Task&amp;lt;int&amp;gt; coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; { isExecuted2 = true; return 2; });
        Task&amp;lt;int&amp;gt; query2 = coldAddOne.Apply(coldTwo);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        coldAddOne.Start(); // Execution.
        coldTwo.Start(); // Execution.
        Assert.AreEqual(2 + 1, query2.Result);
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);

        // f.Functor().Apply(F) == F.Select(f)
        coldAddOne = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addOne);
        coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 2);
        Task&amp;lt;int&amp;gt; left = coldAddOne.Apply(coldTwo);
        Task&amp;lt;int&amp;gt; right = coldTwo.Select(addOne);
        coldAddOne.Start();
        coldTwo.Start();
        Assert.AreEqual(left.Result, right.Result);
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; coldId = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; id);
        coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 2);
        left = coldId.Apply(coldTwo);
        right = coldTwo;
        coldId.Start();
        coldTwo.Start();
        Assert.AreEqual(left.Result, right.Result);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        coldAddOne = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addOne);
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; coldAddTwo = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addTwo);
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Task&amp;lt;Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;&amp;gt; coldComposite =
            new Task&amp;lt;Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;&amp;gt;(() =&amp;gt; o);
        coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 2);
        left = coldComposite.Apply(coldAddOne).Apply(coldAddTwo).Apply(coldTwo);
        right = coldAddOne.Apply(coldAddTwo.Apply(coldTwo));
        coldComposite.Start();
        coldAddOne.Start();
        coldAddTwo.Start();
        coldTwo.Start();
        Assert.AreEqual(left.Result, right.Result);
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        coldAddOne = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addOne);
        coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 2);
        left = coldAddOne.Apply(coldTwo);
        right = new Task&amp;lt;int&amp;gt;(() =&amp;gt; addOne(2));
        coldAddOne.Start();
        coldTwo.Start();
        right.Start();
        Assert.AreEqual(left.Result, right.Result);
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        coldAddOne = new Task&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(() =&amp;gt; addOne);
        coldTwo = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 2);
        left = coldAddOne.Apply(coldTwo);
        Task&amp;lt;Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;&amp;gt; coldApplyTwo =
            new Task&amp;lt;Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;&amp;gt;(() =&amp;gt; f =&amp;gt; f(2));
        right = coldApplyTwo.Apply(coldAddOne);
        coldAddOne.Start();
        coldTwo.Start();
        coldApplyTwo.Start();
        Assert.AreEqual(left.Result, right.Result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (12) More Monoidal Functors: Lazy&lt;&gt;, Func&lt;&gt; And Nullable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-12-more-monoidal-functors-lazy-func-and-nullable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-12-more-monoidal-functors-lazy-func-and-nullable/</guid><description>Lazy&lt;&gt; should be the simplest monoid functor - it is just the lazy version of Tuple&lt;&gt;. And in these posts it will be considered as the Id&lt;&gt; monoidal functor.</description><pubDate>Thu, 13 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Lazy&amp;lt;&amp;gt; monoidal functor&lt;/h2&gt;
&lt;p&gt;Lazy&amp;lt;&amp;gt; should be the simplest monoid functor - it is just the lazy version of Tuple&amp;lt;&amp;gt;. And in these posts it will be considered as the Id&amp;lt;&amp;gt; monoidal functor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    public static Lazy&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this Lazy&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, Lazy&amp;lt;TSource&amp;gt; source) =&amp;gt;
            new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; selectorFunctor.Value(source.Value));

    public static Lazy&amp;lt;T&amp;gt; Lazy&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; new Lazy&amp;lt;T&amp;gt;(() =&amp;gt; value);

    // φ: Lazy&amp;lt;Lazy&amp;lt;T1&amp;gt;, Lazy&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Lazy&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Lazy&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Lazy&amp;lt;T1&amp;gt;, Lazy&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y))
                .Lazy()
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; Lazy&amp;lt;Unit&amp;gt;
    public static Lazy&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Lazy();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tuple&amp;lt;&amp;gt; is similar to the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/Data-Functor-Identity.html#line-85&quot;&gt;Haskell Id Applicative&lt;/a&gt;. The usage will be demonstrated in later tests unit.&lt;/p&gt;
&lt;h2&gt;Func&amp;lt;&amp;gt; monoidal functor&lt;/h2&gt;
&lt;p&gt;Func&amp;lt;&amp;gt; is also monoidal functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class FuncExtensions
{
    public static Func&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this Func&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, Func&amp;lt;TSource&amp;gt; source) =&amp;gt;
            () =&amp;gt; selectorFunctor()(source());

    public static Func&amp;lt;T&amp;gt; Func&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; () =&amp;gt; value;

    // φ: Lazy&amp;lt;Func&amp;lt;T1&amp;gt;, Func&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Func&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Func&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Func&amp;lt;T1&amp;gt;, Func&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            FuncExtensions.Func(new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y)))
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; Func&amp;lt;Unit&amp;gt;
    public static Func&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Func();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Nullable&amp;lt;&amp;gt; monoidal functor&lt;/h2&gt;
&lt;p&gt;Nullable&amp;lt;&amp;gt; created previously is monoidal functor too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class NullableExtensions
{
    public static Nullable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this Nullable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, Nullable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            new Nullable&amp;lt;TResult&amp;gt;(() =&amp;gt; selectorFunctor.HasValue &amp;amp;&amp;amp; source.HasValue ?
                new Tuple&amp;lt;bool, TResult&amp;gt;(true, selectorFunctor.Value(source.Value)) :
                new Tuple&amp;lt;bool, TResult&amp;gt;(false, default(TResult)));

    public static Nullable&amp;lt;T&amp;gt; Nullable&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; new Nullable&amp;lt;T&amp;gt;(() =&amp;gt; Tuple.Create(true, value));

    // φ: Lazy&amp;lt;Nullable&amp;lt;T1&amp;gt;, Nullable&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; Nullable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static Nullable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;Nullable&amp;lt;T1&amp;gt;, Nullable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y))
                .Nullable()
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; Nullable&amp;lt;Unit&amp;gt;
    public static Nullable&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Nullable();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonoidalFunctorTests
{
    [TestMethod()]
    public void LazyTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Lazy&amp;lt;int&amp;gt; query1 = addOne.Lazy().Apply(2.Lazy());
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.AreEqual(2 + 1, query1.Value); // Execution.
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(addOne.Lazy().Apply(1.Lazy()).Value, 1.Lazy().Select(addOne).Value);
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(id.Lazy().Apply(1.Lazy()).Value, 1.Lazy().Value);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Lazy&amp;lt;int&amp;gt; left1 = o.Lazy().Apply(addOne.Lazy()).Apply(addTwo.Lazy()).Apply(1.Lazy());
        Lazy&amp;lt;int&amp;gt; right1 = addOne.Lazy().Apply(addTwo.Lazy().Apply(1.Lazy()));
        Assert.AreEqual(left1.Value, right1.Value);
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(addOne.Lazy().Apply(1.Lazy()).Value, addOne(1).Lazy().Value);
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Lazy&amp;lt;int&amp;gt; left2 = addOne.Lazy().Apply(1.Lazy());
        Lazy&amp;lt;int&amp;gt; right2 = new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1)).Lazy().Apply(addOne.Lazy());
        Assert.AreEqual(left2.Value, right2.Value);
    }

    [TestMethod()]
    public void FuncTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Func&amp;lt;int&amp;gt; query1 = FuncExtensions.Func(addOne).Apply(2.Func());
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.AreEqual(addOne(2), query1()); // Execution.
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(FuncExtensions.Func(addOne).Apply(1.Func())(), 1.Func().Select(addOne)());
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(FuncExtensions.Func(id).Apply(1.Func())(), 1.Func()());
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Func&amp;lt;int&amp;gt; left1 = FuncExtensions.Func(o).Apply(FuncExtensions.Func(addOne)).Apply(FuncExtensions.Func(addTwo)).Apply(1.Func());
        Func&amp;lt;int&amp;gt; right1 = FuncExtensions.Func(addOne).Apply(FuncExtensions.Func(addTwo).Apply(1.Func()));
        Assert.AreEqual(left1(), right1());
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(FuncExtensions.Func(addOne).Apply(1.Func())(), addOne(1).Func()());
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Func&amp;lt;int&amp;gt; left2 = FuncExtensions.Func(addOne).Apply(1.Func());
        Func&amp;lt;int&amp;gt; right2 = FuncExtensions.Func(new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1))).Apply(FuncExtensions.Func(addOne));
        Assert.AreEqual(left2(), right2());
    }

    [TestMethod()]
    public void FuncTest2()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt; add = x =&amp;gt; y =&amp;gt;
            { isExecuted1 = true; return (x + y).ToString(CultureInfo.InvariantCulture); };
        Func&amp;lt;string&amp;gt; query2 = FuncExtensions.Func(add).Apply(1.Func()).Apply(2.Func());
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.AreEqual(add(1)(2), query2()); // Execution.
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(FuncExtensions.Func(add).Apply(1.Func())()(2), 1.Func().Select(add)()(2));
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(FuncExtensions.Func(id).Apply(1.Func())(), 1.Func()());
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;Func&amp;lt;int, string&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt; length = f =&amp;gt; x =&amp;gt; f(x).Length;
        Func&amp;lt;Func&amp;lt;Func&amp;lt;int, string&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;, Func&amp;lt;Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt;, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;Func&amp;lt;int, string&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;, Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt;, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; left1 = FuncExtensions.Func(o).Apply(FuncExtensions.Func(length)).Apply(FuncExtensions.Func(add)).Apply(1.Func());
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; right1 = FuncExtensions.Func(length).Apply(FuncExtensions.Func(add).Apply(1.Func()));
        Assert.AreEqual(left1()(2), right1()(2));
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(FuncExtensions.Func(add).Apply(1.Func())()(2), FuncExtensions.Func(add(1))()(2));
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Func&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt; left2 = FuncExtensions.Func(add).Apply(1.Func());
        Func&amp;lt;Func&amp;lt;int, string&amp;gt;&amp;gt; right2 = FuncExtensions.Func(new Func&amp;lt;Func&amp;lt;int, Func&amp;lt;int, string&amp;gt;&amp;gt;, Func&amp;lt;int, string&amp;gt;&amp;gt;(
                f =&amp;gt; f(1))).Apply(FuncExtensions.Func(add));
        Assert.AreEqual(left2()(2), right2()(2));

        bool isExecuted3 = false;
        Func&amp;lt;string&amp;gt; consoleReadLine1 = () =&amp;gt; &quot;a&quot;;
        Func&amp;lt;string&amp;gt; consoleReadLine2 = () =&amp;gt; &quot;b&quot;;
        Func&amp;lt;string, Func&amp;lt;string, string&amp;gt;&amp;gt; concat = x =&amp;gt; y =&amp;gt;
            { isExecuted3 = true; return string.Concat(x, y); };
        Func&amp;lt;string&amp;gt; concatLines = FuncExtensions.Func(concat).Apply(consoleReadLine1).Apply(consoleReadLine2);
        Assert.IsFalse(isExecuted3); // Laziness.
        Assert.AreEqual(string.Concat(consoleReadLine1(), consoleReadLine2()), concatLines());
        Assert.IsTrue(isExecuted3);
    }

    [TestMethod()]
    public void NullableTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Nullable&amp;lt;int&amp;gt; query1 = addOne.Nullable().Apply(2.Nullable());
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsTrue(query1.HasValue); // Execution.
        Assert.AreEqual(addOne(2), query1.Value);
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        Assert.AreEqual(addOne.Nullable().Apply(1.Nullable()).Value, 1.Nullable().Select(addOne).Value);
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        Assert.AreEqual(id.Nullable().Apply(1.Nullable()).Value, 1.Nullable().Value);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        Nullable&amp;lt;int&amp;gt; left1 = o.Nullable().Apply(addOne.Nullable()).Apply(addTwo.Nullable()).Apply(1.Nullable());
        Nullable&amp;lt;int&amp;gt; right1 = addOne.Nullable().Apply(addTwo.Nullable().Apply(1.Nullable()));
        Assert.AreEqual(left1.Value, right1.Value);
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        Assert.AreEqual(addOne.Nullable().Apply(1.Nullable()).Value, addOne(1).Nullable().Value);
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        Nullable&amp;lt;int&amp;gt; left2 = addOne.Nullable().Apply(1.Nullable());
        Nullable&amp;lt;int&amp;gt; right2 = new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1)).Nullable().Apply(addOne.Nullable());
        Assert.AreEqual(left2.Value, right2.Value);

        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addTwo2 = x =&amp;gt; { isExecuted2 = true; return x + 2; };
        Nullable&amp;lt;int&amp;gt; query2 = addTwo2.Nullable().Apply(new Nullable&amp;lt;int&amp;gt;());
        Assert.IsFalse(isExecuted2); // Laziness.
        Assert.IsFalse(query2.HasValue); // Execution.
        Assert.IsFalse(isExecuted2);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (11) Monoidal Functor And IEnumerable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-11-monoidal-functor-and-ienumerable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-11-monoidal-functor-and-ienumerable/</guid><description>Given monoidal categories (C, ⊗, IC) and (D, ⊛, ID), a  (or lax monoidal functors) is a functor F: C → D equipped with:</description><pubDate>Wed, 12 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Monoidal functor&lt;/h2&gt;
&lt;p&gt;Given monoidal categories (C, ⊗, IC) and (D, ⊛, ID), a &lt;a href=&quot;http://en.wikipedia.org/wiki/Monoidal_functor&quot;&gt;monoidal functor&lt;/a&gt; (or lax monoidal functors) is a functor F: C → D equipped with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monoid binary operation, which is a natural transformation φ: F(X) ⊛ F(Y) ⇒ F(X ⊗ Y)&lt;/li&gt;
&lt;li&gt;Monoid unit, which is a morphism ι: ID → F(IC)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;satisfying the monoid laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Left unit law in D, denoted λD: &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/image_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Right unit law in D, denoted ρD: &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/Untitled-3..fw_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/Untitled-3..fw_thumb.png&quot; alt=&quot;Untitled-3..fw&quot; title=&quot;Untitled-3..fw&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Associativity law in D, denoted αD: &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/Untitled-4.fw_4.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/c89f78dd27b4_ABC1/Untitled-4.fw_thumb_1.png&quot; alt=&quot;Untitled-4.fw&quot; title=&quot;Untitled-4.fw&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The α, λ, ρ are the fore mentioned natural transformations of monoidal category D.&lt;/p&gt;
&lt;p&gt;The definition of monoidal functor in pseudo C# is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IMonoidalFunctor&amp;lt;in TSourceCategory, out TTargetCategory, TSourceBinaryFunctor&amp;lt; , &amp;gt;, TTargetBinaryFunctor&amp;lt; , &amp;gt;, TSourceUnit, TTargetUnit, TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt; 
    : IFunctor&amp;lt;TSourceCategory, TTargetCategory, TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
    where TSourceCategory : ICategory&amp;lt;TSourceCategory&amp;gt;
    where TTargetCategory : ICategory&amp;lt;TTargetCategory&amp;gt;
    where TSourceBinaryFunctor&amp;lt; , &amp;gt; : IBinaryFunctor&amp;lt;TSourceCategory, TSourceCategory, TSourceCategory, TSourceBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
    where TTargetBinaryFunctor&amp;lt; , &amp;gt; : IBinaryFunctor&amp;lt;TTargetCategory, TTargetCategory, TTargetCategory, TTargetBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
    where TMonoidalFunctor&amp;lt;&amp;gt; : IMonoidalFunctor&amp;lt;TSourceCategory, TTargetCategory, TSourceBinaryFunctor&amp;lt; , &amp;gt;, TTargetBinaryFunctor&amp;lt; , &amp;gt;, TMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
{
    // φ: TTargetBinaryFunctor&amp;lt;TMonoidalFunctor&amp;lt;T1&amp;gt;, TMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; TMonoidalFunctor&amp;lt;TSourceBinaryFunctor&amp;lt;T1, T2&amp;gt;&amp;gt;
    TMonoidalFunctor&amp;lt;TSourceBinaryFunctor&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
        TTargetBinaryFunctor&amp;lt;TMonoidalFunctor&amp;lt;T1&amp;gt;, TMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor);

    // ι: TTargetUnit -&amp;gt; TMonoidalFunctor&amp;lt;TSourceUnit&amp;gt;
    TMonoidalFunctor&amp;lt;TSourceUnit&amp;gt; Unit(TTargetUnit unit);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s a ton of type information.&lt;/p&gt;
&lt;p&gt;Once again, the extension method approach will be used.&lt;/p&gt;
&lt;h2&gt;C#/.NET lax monoidal endofunctors&lt;/h2&gt;
&lt;p&gt;Again, dealing with one single monoidal category - DotNet is much easier. According to the definition, A (lax) monoidal functor in monoidal category DotNet is a (lax) monoidal endofunctor F : DotNet → DotNet, equipped with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bifunctor Lazy&amp;lt; , &amp;gt; : DotNet → DotNet&lt;/li&gt;
&lt;li&gt;Natural transformation (binary operation) φ: Lazy&amp;lt;F&amp;lt;X&amp;gt;, F&amp;lt;Y&amp;gt;&amp;gt; ⇒ F&amp;lt;Lazy&amp;lt;X, Y&amp;gt;&amp;gt;, since Lazy&amp;lt; , &amp;gt; is the bifunctor ⊗, and ⊛ too&lt;/li&gt;
&lt;li&gt;Morphism (unit) ι: Unit → F&amp;lt;Unit&amp;gt;, since Unit is IDotNet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lax monoidal endofunctor is a little long for a name. In the rest of this post, monoidal functor will be used for it.&lt;/p&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IDotNetMonoidalFunctor&amp;lt;T&amp;gt; // F&amp;lt;&amp;gt;
    : IMonoidalFunctor&amp;lt;DotNet, DotNet, Lazy&amp;lt; , &amp;gt;, Lazy&amp;lt; , &amp;gt;, Unit, Unit, IDotNetMonoidalFunctor&amp;lt;&amp;gt;&amp;gt;
{
    // φ: Lazy&amp;lt;F&amp;lt;T1&amp;gt;, F&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; F&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    // IDotNetMonoidalFunctor&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
    //     Lazy&amp;lt;IDotNetMonoidalFunctor&amp;lt;T1&amp;gt;, IDotNetMonoidalFunctor&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor);

    // ι: Unit -&amp;gt; F&amp;lt;Unit&amp;gt;
    // IDotNetMonoidalFunctor&amp;lt;Unit&amp;gt; Unit(Unit unit);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the Binary operator becomes more intuitive, because Lazy&amp;lt; , &amp;gt; is just a (lazy) tuple. So above Binary function is close to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// φ: Lazy&amp;lt;F&amp;lt;T1&amp;gt;, F&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; F&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
// is equivalent to
// φ: (F&amp;lt;T1&amp;gt;, F&amp;lt;T2&amp;gt;&amp;gt;) =&amp;gt; F&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
IDotNetMonoidalFunctor&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
    IDotNetMonoidalFunctor&amp;lt;T1&amp;gt; functor1, IDotNetMonoidalFunctor&amp;lt;T2&amp;gt; functor2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which clearly shows monoidal functor F&amp;lt;&amp;gt;’s monoidal structure: (F&amp;lt;X&amp;gt;, F&amp;lt;Y&amp;gt;&amp;gt;) ⇒ F&amp;lt;Z&amp;gt;.&lt;/p&gt;
&lt;h2&gt;IEnumerable&amp;lt;&amp;gt; monoidal functor&lt;/h2&gt;
&lt;p&gt;To implement Binary for IEnumerable&amp;lt;&amp;gt;, just need to take values from each IEnumerable&amp;lt;&amp;gt; in the pair, and result a IEnumerable&amp;lt;&amp;gt; of the values’ Cartesian product:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    // φ: Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
        this Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor)
    {
        foreach (T1 value1 in binaryFunctor.Value1)
        {
            foreach (T2 value2 in binaryFunctor.Value2)
            {
                yield return new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2);
            }
        }
    }

    // ι: Unit -&amp;gt; IEnumerable&amp;lt;Unit&amp;gt;
    public static IEnumerable&amp;lt;Unit&amp;gt; Unit(Unit unit)
    {
        yield return unit;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;N-arity selector for functor&lt;/h3&gt;
&lt;p&gt;How can this be useful? Remember IEnumerable&amp;lt;&amp;gt;’s Select function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    foreach (TSource item in source)
    {
        yield return selector(item);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The selector takes a TSource parameter. What if selector is a N-arity function? For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; selector = (x, y, z) =&amp;gt; x + y + z;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not a problem, because N-arity function can always be curried to 1-arity function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; selector = x =&amp;gt; y =&amp;gt; z =&amp;gt; x + y + z;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in scenario like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; selector = x =&amp;gt; y =&amp;gt; z =&amp;gt; x + y + z;
IEnumerable&amp;lt;int&amp;gt; xs = Enumerable.Range(0, 2);
IEnumerable&amp;lt;int&amp;gt; ys = Enumerable.Range(2, 2);
IEnumerable&amp;lt;int&amp;gt; zs = Enumerable.Range(4, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;how selector’s add algorithm can be applied with these values in functors? Try starting from xs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var query1 = from x in xs select selector(x); // IEnumerable&amp;lt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; query = xs.Select(selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, now query1’s type becomes IEnumerable&amp;lt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;. The selector got wrapped in the functor. How to apply a function in functor with value(s) in functor? Now lax monoidal endofunctor can be useful. Its binary operator takes a pair of functors - here one functor wraps function, the other wraps argument, and returns another functor, which wraps a pair of function and argument together.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; query1 = from x in xs select selector(x);
IEnumerable&amp;lt;Lazy&amp;lt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;, int&amp;gt;&amp;gt; query2 = new Lazy&amp;lt;IEnumerable&amp;lt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt;(query1, ys).Binary();
IEnumerable&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; query3 = from pair in query2 select pair.Value1(pair.Value2);
// Continue with zs...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It works. And this approach can be more fluent.&lt;/p&gt;
&lt;p&gt;First, replace T1 with Func&amp;lt;T2, T1&amp;gt;, since this is for applying functions wrapped in functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;Lazy&amp;lt;Func&amp;lt;T2, T1&amp;gt;, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
    this Lazy&amp;lt;IEnumerable&amp;lt;Func&amp;lt;T2, T1&amp;gt;&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Second, get rid of Lazy&amp;lt; , &amp;gt; in the parameter, it just pairs 2 parameters. “this” keyword remains for the first parameter.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;Lazy&amp;lt;Func&amp;lt;T2, T1&amp;gt;, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
    this IEnumerable&amp;lt;Func&amp;lt;T2, T1&amp;gt;&amp;gt;, IEnumerable&amp;lt;T2&amp;gt; binaryFunctor)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the return type IEnumerable&amp;lt;Lazy&amp;lt;Func&amp;lt;T2, T1&amp;gt;, T2&amp;gt;&amp;gt;, Lazy&amp;lt;…&amp;gt; will be dismantled to Func&amp;lt;T2, T1&amp;gt; and T2, then Func&amp;lt;T2, T1&amp;gt; will be applied with T2 and return T1, so eventually the return type will be IEnumerable&amp;lt;T1&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;T1&amp;gt; Binary&amp;lt;T1, T2&amp;gt;(
    this IEnumerable&amp;lt;Func&amp;lt;T2, T1&amp;gt;&amp;gt;, IEnumerable&amp;lt;T2&amp;gt; binaryFunctor)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Last step - rename T1 to TResult, T2 to TSource, Binary to Apply, so they make more sense than “general abstract”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
    (this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; 
        new Lazy&amp;lt;IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;(selectorFunctor, source)
            .Binary().Select(pair =&amp;gt; pair.Value1(pair.Value2));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is easier to apply selector with xs, ys, and zs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; query = xs.Select(selector).Apply(ys).Apply(zs);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If selector can be wrapped in the IEnumerable&amp;lt;&amp;gt; functor from the beginning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;T&amp;gt; Enumerable&amp;lt;T&amp;gt;(this T value)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then the application becomes more consistent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; query = selector.Enumerable().Apply(xs).Apply(ys).Apply(zs);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apply is also called Merge, because this function merges 2 monoidal functors into one. But in scenarios like above, Apply can be more intuitive.&lt;/p&gt;
&lt;h3&gt;Binary vs. Apply&lt;/h3&gt;
&lt;p&gt;Actually, monoidal functor IEnumerable&amp;lt;T&amp;gt; is functor and already has a Select function, its (Apply + Enumerable) is equivalent to (Binary + Unit). These 2 groups of functions express each other.&lt;/p&gt;
&lt;p&gt;This is how (Binary + Unit) can implement (Apply + Enumerable):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            new Lazy&amp;lt;IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;(selectorFunctor, source)
                .Binary().Select(pair =&amp;gt; pair.Value1(pair.Value2));

    public static IEnumerable&amp;lt;T&amp;gt; Enumerable&amp;lt;T&amp;gt;
        (this T value) =&amp;gt; Unit(null).Select(unit =&amp;gt; value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how (Apply + Enumerable) implement (Binary + Unit):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source)
    {
        foreach (Func&amp;lt;TSource, TResult&amp;gt; selector in selectorFunctor)
        {
            foreach (TSource value in source)
            {
                yield return selector(value);
            }
        }
    }

    public static IEnumerable&amp;lt;T&amp;gt; Enumerable&amp;lt;T&amp;gt;(this T value)
    {
        yield return value;
    }

    // φ: Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;
    public static IEnumerable&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;&amp;gt; Binary&amp;lt;T1, T2&amp;gt;
        (this Lazy&amp;lt;IEnumerable&amp;lt;T1&amp;gt;, IEnumerable&amp;lt;T2&amp;gt;&amp;gt; binaryFunctor) =&amp;gt;
            new Func&amp;lt;T1, Func&amp;lt;T2, Lazy&amp;lt;T1, T2&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(x, y))
                .Enumerable()
                .Apply(binaryFunctor.Value1)
                .Apply(binaryFunctor.Value2);

    // ι: Unit -&amp;gt; IEnumerable&amp;lt;Unit&amp;gt;
    public static IEnumerable&amp;lt;Unit&amp;gt; Unit
        (Unit unit) =&amp;gt; unit.Enumerable();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the future the latter style will be used, because (Apply + Enumerable) can be less general abstract.&lt;/p&gt;
&lt;h2&gt;Monoidal functor and LINQ&lt;/h2&gt;
&lt;p&gt;The Binary/Apply function merges 2 IEnumerable&amp;lt;&amp;gt; functors into 1 IEnumerable&amp;lt;&amp;gt;, which is similar to the semantics of Enumerable.Zip and Enumerable.Join:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class EnumerableExtensions2
{
    public static IEnumerable&amp;lt;TResult&amp;gt; ApplyWithZip&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorFunctor
                .Aggregate(
                    Enumerable.Empty&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;(),
                    (current, selector) =&amp;gt; current.Concat(source.Select(sourceValue =&amp;gt; selector)))
                .Zip(
                    selectorFunctor.Aggregate(
                        Enumerable.Empty&amp;lt;TSource&amp;gt;(),
                        (current, selector) =&amp;gt; current.Concat(source)),
                    (selector, value) =&amp;gt; selector(value));

    public static IEnumerable&amp;lt;TResult&amp;gt; ApplyWithJoin&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            selectorFunctor.Join(
                source,
                selector =&amp;gt; true,
                value =&amp;gt; true,
                (selector, value) =&amp;gt; selector(value),
                EqualityComparer&amp;lt;bool&amp;gt;.Default);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb311040.aspx&quot;&gt;Join has LINQ support&lt;/a&gt;, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class EnumerableExtensions2
{
    public static IEnumerable&amp;lt;TResult&amp;gt; ApplyWithLinqJoin&amp;lt;TSource, TResult&amp;gt;
        (this IEnumerable&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
            from selector in selectorFunctor
            join value in source on true equals true // Cross join.
            select selector(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the tricky &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb882533.aspx&quot;&gt;cross join&lt;/a&gt;. It works but is not straightforward. Later code will keep using Apply function.&lt;/p&gt;
&lt;h2&gt;Applicative functor&lt;/h2&gt;
&lt;p&gt;As above code demonstrated, besides the standard (Binary + Unit) definition, a monoidal functor MonoidalFunctor can also be defined by (Apply + MonoidalFunctor). Actually, in &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt;, the latter way is used, and monoidal functor is called &lt;a href=&quot;https://wiki.haskell.org/Applicative_functor&quot;&gt;applicative functor&lt;/a&gt;. The pseudo C# is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt; // Lax monoidal endofunctor in DotNet category.
    : IFunctor&amp;lt;DotNet, DotNet, TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;
    where TApplicativeFunctor&amp;lt;&amp;gt; : IApplicativeFunctor&amp;lt;TApplicativeFunctor&amp;lt;&amp;gt;&amp;gt;
{
    TApplicativeFunctor&amp;lt;TResult&amp;gt; Apply&amp;lt;TSource, TResult&amp;gt;(
        TApplicativeFunctor&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selectorFunctor, TApplicativeFunctor&amp;lt;TSource&amp;gt; source);

    TApplicativeFunctor&amp;lt;T&amp;gt; Pure&amp;lt;T&amp;gt;(T value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In applicative functor (monoidal functor) definition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first function the same Apply function.&lt;/li&gt;
&lt;li&gt;The second function has a confusing name Pure. It does not indicate the purity. It is just the Enumerable function above. It can be read as Functor, or Wrap, which wraps a value into an applicative functor (monoidal functor).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Applicative laws, and unit tests&lt;/h2&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; is like the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Base.html#line-717&quot;&gt;List Appliative in Haskell&lt;/a&gt;. The following unit tests are following the &lt;a href=&quot;http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors&quot;&gt;applicative laws of Haskell&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;f.Functor().Apply(F) == F.Select(f)&lt;/li&gt;
&lt;li&gt;Id.Functor().Apply(F) == F&lt;/li&gt;
&lt;li&gt;o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))&lt;/li&gt;
&lt;li&gt;f.Functor().Apply(a.Functor()) == f(a).Functor()&lt;/li&gt;
&lt;li&gt;F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;where f is a function, F, F1, F2, F3 are monoidal functors, o is the composition of functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public partial class MonoidalFunctorTests
{
    [TestMethod()]
    public void EnumerableTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        IEnumerable&amp;lt;int&amp;gt; numbers = new int[] { 0, 1, 2 };
        IEnumerable&amp;lt;int&amp;gt; query = addOne.Enumerable().Apply(numbers);
        Assert.IsFalse(isExecuted1); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 1, 2, 3 }, query); // Execution.
        Assert.IsTrue(isExecuted1);

        // f.Functor().Apply(F) == F.Select(f)
        EnumerableAssert.AreEqual(addOne.Enumerable().Apply(numbers), numbers.Select(addOne));
        // id.Functor().Apply(F) == F
        Func&amp;lt;int, int&amp;gt; id = Functions.Id;
        EnumerableAssert.AreEqual(id.Enumerable().Apply(numbers), numbers);
        // o.Functor().Apply(F1).Apply(F2).Apply(F3) == F1.Apply(F2.Apply(F3))
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; x + 2;
        Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; o =
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;, Func&amp;lt;int, int&amp;gt;&amp;gt;(FuncExtensions.o).Curry();
        EnumerableAssert.AreEqual(
            o.Enumerable().Apply(addOne.Enumerable()).Apply(addTwo.Enumerable()).Apply(numbers), 
            addOne.Enumerable().Apply(addTwo.Enumerable().Apply(numbers)));
        // f.Functor().Apply(a.Functor()) == f(a).Functor()
        EnumerableAssert.AreEqual(addOne.Enumerable().Apply(1.Enumerable()), addOne(1).Enumerable());
        // F.Apply(a.Functor()) == (f =&amp;gt; f(a)).Functor().Apply(F)
        EnumerableAssert.AreEqual(
            addOne.Enumerable().Apply(1.Enumerable()),
            new Func&amp;lt;Func&amp;lt;int, int&amp;gt;, int&amp;gt;(f =&amp;gt; f(1)).Enumerable().Apply(addOne.Enumerable()));
    }

    [TestMethod()]
    public void EnumerableTest2()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        IEnumerable&amp;lt;int&amp;gt; numbers = new int[] { 0, 1, 2 };
        IEnumerable&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; addTwoAddOne = new Func&amp;lt;int, int&amp;gt;(
            x =&amp;gt; { isExecuted2 = true; return x + 2; }).Enumerable().Concat(addOne.Enumerable());
        IEnumerable&amp;lt;int&amp;gt; query = addTwoAddOne.Apply(numbers);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 2, 3, 4, 1, 2, 3 }, query); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And unit tests for LINQ implementations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonoidalFunctorTests
{
    [TestMethod()]
    public void EnumerableApplyWithZipTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        IEnumerable&amp;lt;int&amp;gt; numbers = new int[] { 0, 1, 2, 3 };
        IEnumerable&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; addTwoAddOne = new Func&amp;lt;int, int&amp;gt;(
            x =&amp;gt; { isExecuted2 = true; return x + 2; }).Enumerable().Concat(addOne.Enumerable());
        IEnumerable&amp;lt;int&amp;gt; query = addTwoAddOne.ApplyWithZip(numbers);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 2, 3, 4, 5, 1, 2, 3, 4 }, query); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
    }

    [TestMethod()]
    public void EnumerableApplyWithJoinTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        IEnumerable&amp;lt;int&amp;gt; numbers = new int[] { 0, 1, 2 };
        IEnumerable&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; addTwoAddOne = new Func&amp;lt;int, int&amp;gt;(
            x =&amp;gt; { isExecuted2 = true; return x + 2; }).Enumerable().Concat(addOne.Enumerable());
        IEnumerable&amp;lt;int&amp;gt; query = addTwoAddOne.ApplyWithJoin(numbers);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 2, 3, 4, 1, 2, 3 }, query); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
    }

    [TestMethod()]
    public void EnumerableApplyWithLinqJoinTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        IEnumerable&amp;lt;int&amp;gt; numbers = new int[] { 0, 1, 2 };
        IEnumerable&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; functions = new Func&amp;lt;int, int&amp;gt;(
            x =&amp;gt; { isExecuted2 = true; return x + 2; }).Enumerable().Concat(addOne.Enumerable());
        IEnumerable&amp;lt;int&amp;gt; query = functions.ApplyWithLinqJoin(numbers);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.
        EnumerableAssert.AreEqual(new int[] { 2, 3, 4, 1, 2, 3 }, query); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (10) Monoidal Category</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-10-monoidal-category/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-10-monoidal-category/</guid><description>A previous part demonstrated endofunctor category is monoidal. Now with the help of bifunctor, the general abstract  can be defined.</description><pubDate>Tue, 11 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-6-monoidal-functor-and-applicative-functor&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Monoidal category&lt;/h2&gt;
&lt;p&gt;A previous part demonstrated endofunctor category is monoidal. Now with the help of bifunctor, the general abstract &lt;a href=&quot;http://en.wikipedia.org/wiki/Monoidal_category&quot;&gt;monoidal category&lt;/a&gt; can be defined. A monoidal category is a category C equipped with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A bifunctor ⊗: C ⊗ C → C, as the monoid binary operation, also called the &lt;a href=&quot;http://en.wikipedia.org/wiki/Tensor_product&quot;&gt;monoidal product&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;An unit object I ∈ C as the monoid unit&lt;/li&gt;
&lt;li&gt;A natural transformation λX: I ⊗ X ⇒ X, called left unitor&lt;/li&gt;
&lt;li&gt;A natural transformation ρX: X ⊗ I ⇒ X, called right unitor&lt;/li&gt;
&lt;li&gt;A natural transformation αX, Y, Z: (X ⊗ Y) ⊗ Z ⇒ X ⊗ (Y ⊗ Z), called associator&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;so that C satisfies the monoid laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Left unit law λX: I ⊗ X ⇒ X (according to definition)&lt;/li&gt;
&lt;li&gt;and right unit law ρX: X ⊗ I ⇒ X (definition)&lt;/li&gt;
&lt;li&gt;Associative law αX, Y, Z: (X ⊗ Y) ⊗ Z ⇒ X ⊗ (Y ⊗ Z) (definition)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following triangle identity and pentagon identity diagrams copied from the monoid part still commute for monoidal category:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/7dadeb2d634a_AAEC/image_thumb1%5B2%5D.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/7dadeb2d634a_AAEC/image_thumb1%5B2%5D_thumb.png&quot; alt=&quot;image_thumb1[2]&quot; title=&quot;image_thumb1[2]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/7dadeb2d634a_AAEC/Untitled-2.fw_thumb_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/7dadeb2d634a_AAEC/Untitled-2.fw_thumb_thumb.png&quot; alt=&quot;Untitled-2.fw_thumb&quot; title=&quot;Untitled-2.fw_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just read the ⊙ (general binary operator) as ⊗ (bifunctor).&lt;/p&gt;
&lt;p&gt;The existence of bifunctor ⊗ makes it possible to ⊗ (can be read as multiply) any 2 elements in the category, and get another element still in the category (the &lt;a href=&quot;http://en.wikipedia.org/wiki/Cartesian_product&quot;&gt;Cartesian product&lt;/a&gt; represented by that bifunctor). So, bifunctor ⊗ and unit I forms the monoid structure of the category, and the 3 natural transformations make sure this binary “multiply” operation satisfies the monoidal rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;left unit law: λX(I ⊗ X) ≌ X&lt;/li&gt;
&lt;li&gt;right unit law: ρX(X ⊗ I) ≌ X&lt;/li&gt;
&lt;li&gt;associative law: αX, Y, Z((X ⊗ Y) ⊗ Z) ≌ X ⊗ (Y ⊗ Z)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In pseudo C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IMonoidalCategory&amp;lt;TMonoidalCategory, out TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt; 
    : ICategory&amp;lt;TMonoidalCategory&amp;gt;
    where TBinaryFunctor&amp;lt; , &amp;gt; : IBinaryFunctor&amp;lt;TMonoidalCategory, TMonoidalCategory, TMonoidalCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
{
    TBinaryFunctor&amp;lt;T1, T2&amp;gt; x&amp;lt;T1, T2&amp;gt;(T1 value1, T2 value2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DotNet category is monoidal category&lt;/h2&gt;
&lt;p&gt;In above definition, x represents ⊗ (multiple). However, this cannot be expressed in real C# because IBinaryFunctor&amp;lt;…&amp;gt; is involved, which requires C# language to have higher-kinded polymorphism:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IBinaryFunctor&amp;lt;in TSourceCategory1, in TSourceCategory2, out TTargetCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
    where TSourceCategory1 : ICategory&amp;lt;TSourceCategory1&amp;gt;
    where TSourceCategory2 : ICategory&amp;lt;TSourceCategory2&amp;gt;
    where TTargetCategory : ICategory&amp;lt;TTargetCategory&amp;gt;
    where TBinaryFunctor&amp;lt; , &amp;gt; : IBinaryFunctor&amp;lt;TSourceCategory1, TSourceCategory2, TTargetCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
{
    IMorphism&amp;lt;TBinaryFunctor&amp;lt;TSource1, TSource2&amp;gt;, TBinaryFunctor&amp;lt;TResult1, TResult2&amp;gt;, TTargetCategory&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        IMorphism&amp;lt;TSource1, TResult1, TSourceCategory1&amp;gt; selector1, IMorphism&amp;lt;TSource2, TResult2, TSourceCategory2&amp;gt; selector2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, just like the functor and bifunctor, go with the extension method approach.&lt;/p&gt;
&lt;p&gt;For DotNet category, the bifunctor can be Lazy&amp;lt; , &amp;gt;. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class DotNetExtensions
{
    public static Lazy&amp;lt;T1, T2&amp;gt; x&amp;lt;T1, T2&amp;gt;
        (this DotNet category, T1 value1, T2 value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(() =&amp;gt; value1, () =&amp;gt; value2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To be more intuitive, the following “x” extension method can be created for elements in DotNet category:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    public static Lazy&amp;lt;T1, T2&amp;gt; x&amp;lt;T1, T2&amp;gt;
        (this T1 value1, T2 value2) =&amp;gt; new Lazy&amp;lt;T1, T2&amp;gt;(value1, value2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that the multiplication binary operation can be applied with any 2 elements in DotNet category, and result another element in DotNet category - the Cartesian product represented by Lazy&amp;lt; , &amp;gt; bifunctor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var x = 1.x(true);
var y = &quot;abc&quot;.x(2).x(new HttpClient().x((Unit)null));
var z = y.x(typeof(Unit));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This demonstrates the monoidal structure of DotNet category.&lt;/p&gt;
&lt;p&gt;Next, the 3 natural transformations can be implemented as bifunctor’s extension methods too, by borrowing &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee370443.aspx&quot;&gt;Microsoft.FSharp.Core.Unit&lt;/a&gt; from F# as the unit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    public static T2 LeftUnit&amp;lt;T2&amp;gt;
        (this Lazy&amp;lt;Unit, T2&amp;gt; product) =&amp;gt; product.Value2;

    public static T1 RightUnit&amp;lt;T1&amp;gt;
        (this Lazy&amp;lt;T1, Unit&amp;gt; product) =&amp;gt; product.Value1;

    public static Lazy&amp;lt;T1, Lazy&amp;lt;T2, T3&amp;gt;&amp;gt; Associate&amp;lt;T1, T2, T3&amp;gt;
        (Lazy&amp;lt;Lazy&amp;lt;T1, T2&amp;gt;, T3&amp;gt; product) =&amp;gt; 
            new Lazy&amp;lt;T1, Lazy&amp;lt;T2, T3&amp;gt;&amp;gt;(
                () =&amp;gt; product.Value1.Value1,
                () =&amp;gt; new Lazy&amp;lt;T2, T3&amp;gt;(() =&amp;gt; product.Value1.Value2, () =&amp;gt; product.Value2));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, with Lazy&amp;lt; , &amp;gt; as bifunctor, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd483472.aspx&quot;&gt;F# unit&lt;/a&gt; as C# unit, plus above 3 natural transformations, DotNet category is a monoidal category (DotNet, Lazy&amp;lt; , &amp;gt;, Unit).&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (9) Bifunctor</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-9-bifunctor/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-9-bifunctor/</guid><description>As discussed in all the previous functor parts, a functor is a wrapper of a object with a “Select” ability to preserve a morphism to another‘</description><pubDate>Mon, 10 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-5-bifunctor&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-5-bifunctor&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Bifunctor&lt;/h2&gt;
&lt;p&gt;As discussed in all the previous functor parts, a functor is a wrapper of a object with a “Select” ability to preserve a morphism to another‘&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image_thumb2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image_thumb2_thumb.png&quot; alt=&quot;image_thumb[2]&quot; title=&quot;image_thumb[2]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor#Bifunctors_and_multifunctors&quot;&gt;bifunctor&lt;/a&gt;, as the name implies, is a wrapper of 2 objects, with a “Select” ability to preserve 2 morphisms to another morphism:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image1.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image1_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As above diagram represented, F:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;maps objects X ∈ ob(C), Y ∈ ob(D) to objects F(X, Y) ∈ ob(E)&lt;/li&gt;
&lt;li&gt;also maps morphism mC: X → X’ ∈ hom(C), mD: Y → Y’ ∈ hom(D) to a new morphism mE: F(X, Y) → F(X’, Y’) ∈ hom(E)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and satisfies the functor laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select(idX, idY) ≌ idF(X, Y) &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Select(m2 ∘ m1, n2 ∘ n1) ≌ Select(m2, n2) ∘ F(m1, n1) &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image3.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-9-Functor-Category_8A55/image3_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember the pseudo C# definition of functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IFunctor&amp;lt;in TSourceCategory, out TTargetCategory, TFunctor&amp;lt;&amp;gt;&amp;gt;
    where TSourceCategory : ICategory&amp;lt;TSourceCategory&amp;gt;
    where TTargetCategory : ICategory&amp;lt;TTargetCategory&amp;gt;
    where TFunctor&amp;lt;&amp;gt; : IFunctor&amp;lt;TSourceCategory, TTargetCategory, TFunctor&amp;lt;&amp;gt;&amp;gt;
{
    IMorphism&amp;lt;TFunctor&amp;lt;TSource&amp;gt;, TFunctor&amp;lt;TResult&amp;gt;, TTargetCategory&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        IMorphism&amp;lt;TSource, TResult, TSourceCategory&amp;gt; selector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, bifunctor can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled
public interface IBinaryFunctor&amp;lt;in TSourceCategory1, in TSourceCategory2, out TTargetCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
    where TSourceCategory1 : ICategory&amp;lt;TSourceCategory1&amp;gt;
    where TSourceCategory2 : ICategory&amp;lt;TSourceCategory2&amp;gt;
    where TTargetCategory : ICategory&amp;lt;TTargetCategory&amp;gt;
    where TBinaryFunctor&amp;lt; , &amp;gt; : IBinaryFunctor&amp;lt;TSourceCategory1, TSourceCategory2, TTargetCategory, TBinaryFunctor&amp;lt; , &amp;gt;&amp;gt;
{
    IMorphism&amp;lt;TBinaryFunctor&amp;lt;TSource1, TSource2&amp;gt;, TBinaryFunctor&amp;lt;TResult1, TResult2&amp;gt;, TTargetCategory&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;(
        IMorphism&amp;lt;TSource1, TResult1, TSourceCategory1&amp;gt; selector1, IMorphism&amp;lt;TSource2, TResult2, TSourceCategory2&amp;gt; selector2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As above definition mentioned, bifunctor wraps 2 objects. So here TBinaryFunctor&amp;lt; , &amp;gt; takes 2 parameters so that it can wrap 2 types. Later the Select function will be implemented as extension method for each bifunctor, the same as how functors are handled.&lt;/p&gt;
&lt;p&gt;Tri-functor, and multi-functor can be defined and implemented similarly.&lt;/p&gt;
&lt;h2&gt;C#/.NET bifunctor&lt;/h2&gt;
&lt;p&gt;Theoretically, the intuitive bifunctor is Tuple&amp;lt; , &amp;gt;. However, as a previous part mentioned, Tuple&amp;lt; , &amp;gt; can have unexpected behavior in C#/LINQ context, so it will only be considered functor-like. So, to be consistent, Tuple&amp;lt;&amp;gt; or Tuple&amp;lt; , &amp;gt;, … will only be used as utilities in the category theory via C# posts, instead of as functor or bifunctor. Here is a scenario for Tuple&amp;lt; , &amp;gt;, so its lazy version Lazy&amp;lt; , &amp;gt; can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Lazy&amp;lt;T1, T2&amp;gt;
{
    private readonly Lazy&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;&amp;gt; lazy;

    public Lazy(Func&amp;lt;T1&amp;gt; factory1, Func&amp;lt;T2&amp;gt; factory2)
        : this(() =&amp;gt; Tuple.Create(factory1(), factory2()))
    {
    }

    public Lazy(T1 value1, T2 value2)
        : this(() =&amp;gt; Tuple.Create(value1, value2))
    {
    }

    public Lazy(Func&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;&amp;gt; factory)
    {
        this.lazy = new Lazy&amp;lt;Tuple&amp;lt;T1, T2&amp;gt;&amp;gt;(factory);
    }

    public T1 Value1
    {
        [Pure]get { return this.lazy.Value.Item1; }
    }

    public T2 Value2
    {
        [Pure]get { return this.lazy.Value.Item2; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference from Lazy&amp;lt;&amp;gt; functor is, as the definition said, Lazy&amp;lt; , &amp;gt; wraps 2 types of values.&lt;/p&gt;
&lt;p&gt;To make Lazy&amp;lt; , &amp;gt; a bifunctor, just create these bi-Select extension methods (in &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt; this is called &lt;a href=&quot;https://hackage.haskell.org/package/bifunctors-3.2.0.1/docs/Data-Bifunctor.html&quot;&gt;bimap&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class LazyExtensions
{
    public static Lazy&amp;lt;TResult1, TResult2&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;
        (this Lazy&amp;lt;TSource1, TSource2&amp;gt; source, 
            Func&amp;lt;TSource1, TResult1&amp;gt; selector1, 
            Func&amp;lt;TSource2, TResult2&amp;gt; selector2) =&amp;gt;
                new Lazy&amp;lt;TResult1, TResult2&amp;gt;(() =&amp;gt; selector1(source.Value1), () =&amp;gt; selector2(source.Value2));

    public static IMorphism&amp;lt;Lazy&amp;lt;TSource1, TSource2&amp;gt;, Lazy&amp;lt;TResult1, TResult2&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource1, TSource2, TResult1, TResult2&amp;gt;
        (IMorphism&amp;lt;TSource1, TResult1, DotNet&amp;gt; selector1, IMorphism&amp;lt;TSource2, TResult2, DotNet&amp;gt; selector2) =&amp;gt; 
            new DotNetMorphism&amp;lt;Lazy&amp;lt;TSource1, TSource2&amp;gt;, Lazy&amp;lt;TResult1, TResult2&amp;gt;&amp;gt;(
                source =&amp;gt; source.Select(selector1.Invoke, selector2.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference from Lazy&amp;lt;&amp;gt; functor is - there are 2 selectors, one selector for each wrapped type.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;The following unit test demonstrates the usage and laziness of Lazy&amp;lt; , &amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class BinaryFunctorTests
{
    [TestMethod()]
    public void LazyTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Lazy&amp;lt;int, string&amp;gt; lazyBinaryFunctor = new Lazy&amp;lt;int, string&amp;gt;(1, &quot;abc&quot;);
        Func&amp;lt;int, bool&amp;gt; selector1 = x =&amp;gt; { isExecuted1= true; return x &amp;gt; 0; };
        Func&amp;lt;string, int&amp;gt; selector2 = x =&amp;gt; { isExecuted2 = true; return x.Length; };

        Lazy&amp;lt;bool, int&amp;gt; query = lazyBinaryFunctor.Select(selector1, selector2);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.

        Assert.AreEqual(true, query.Value1); // Execution.
        Assert.AreEqual(&quot;abc&quot;.Length, query.Value2); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2); 
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice Tuple&amp;lt; , &amp;gt; does not have such laziness.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (8) Functor Category</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-8-functor-category/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-8-functor-category/</guid><description>Given 2 categories C and D, functors C → D forms a , denoted DC:</description><pubDate>Sun, 09 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-3-functor-and-linq-to-functors&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Functor Category&lt;/h2&gt;
&lt;p&gt;Given 2 categories C and D, functors C → D forms a &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor_category&quot;&gt;functor category&lt;/a&gt;, denoted DC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ob(DC): those functors C → D&lt;/li&gt;
&lt;li&gt;hom(DC): natural transformations between those functors&lt;/li&gt;
&lt;li&gt;∘: natural transformations F ⇒ G and G ⇒ H compose to natural transformations F ⇒ H&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/3e08057eb6f3_80DE/image_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/3e08057eb6f3_80DE/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is an example of natural transformations composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class NaturalTransformations
{
    // Lazy&amp;lt;&amp;gt; =&amp;gt; Func&amp;lt;&amp;gt;
    public static Func&amp;lt;T&amp;gt; ToFunc&amp;lt;T&amp;gt;
        (this Lazy&amp;lt;T&amp;gt; lazy) =&amp;gt; () =&amp;gt; lazy.Value;

    // Func&amp;lt;&amp;gt; =&amp;gt; Nullable&amp;lt;&amp;gt;
    public static Nullable&amp;lt;T&amp;gt; ToNullable&amp;lt;T&amp;gt;
        (this Func&amp;lt;T&amp;gt; function) =&amp;gt; new Nullable&amp;lt;T&amp;gt;(() =&amp;gt; Tuple.Create(true, function()));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 natural transformation Lazy&amp;lt;&amp;gt; ⇒ Func&amp;lt;&amp;gt; and Func&amp;lt;&amp;gt; ⇒ Nullable&amp;lt;&amp;gt; can compose to a new natural transformation Lazy&amp;lt;&amp;gt; ⇒ Nullable&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Lazy&amp;lt;&amp;gt; =&amp;gt; Nullable&amp;lt;&amp;gt;
public static Nullable&amp;lt;T&amp;gt; ToNullable&amp;lt;T&amp;gt;
    (this Lazy&amp;lt;T&amp;gt; lazy) =&amp;gt;
        // new Func&amp;lt;Func&amp;lt;T&amp;gt;, Nullable&amp;lt;T&amp;gt;&amp;gt;(ToNullable).o(new Func&amp;lt;Lazy&amp;lt;T&amp;gt;, Func&amp;lt;T&amp;gt;&amp;gt;(ToFunc))(lazy);
        lazy.ToFunc().ToNullable();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Endofunctor category&lt;/h2&gt;
&lt;p&gt;Given category C, endofunctors C → C forms an endofunctor category, denoted CC, or End(C):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ob(End(C)): the endofunctors C → C&lt;/li&gt;
&lt;li&gt;hom(End(C)): the natural transformations between endofunctors: C → C&lt;/li&gt;
&lt;li&gt;∘: 2 natural transformations F ⇒ G and G ⇒ H can composte to natural transformation F ⇒ H&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/3e08057eb6f3_80DE/image3.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/3e08057eb6f3_80DE/image3_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Actually, all the above C# code examples are endofunctors DotNet → DotNet. They form the endofunctor category DotNetDotNet or End(DotNet).&lt;/p&gt;
&lt;h2&gt;Monoid laws for endofunctor category, and unit tests&lt;/h2&gt;
&lt;p&gt;An endofunctor category C is a monoid (C, ∘, Id):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Binary operator is ∘: the composition of 2 natural transformations F ⇒ G and G ⇒ H is still a natural transformation F ⇒ H&lt;/li&gt;
&lt;li&gt;Unit element: the Id natural transformation, which transforms any endofunctor X to itself - IdX: X ⇒ X&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apparently, Monoid (hom(CC), ∘, Id) satisfies the monoid laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;left unit law: IdF: F ⇒ F ∘ T: F ⇒ G ≌ T: F ⇒ G, T ∈ ob(End(C))&lt;/li&gt;
&lt;li&gt;right unit law: T: F ⇒ G ≌ T: F ⇒ G ∘ IdG: G ⇒ G, T ∈ ob(End(C))&lt;/li&gt;
&lt;li&gt;associative law: (T1 ∘ T2) ∘ T3 ≌ T1 ∘ (T2 ∘ T3)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Take the transformations above and in previous part as example, the following test shows how natural transformations Lazy&amp;lt;&amp;gt; ⇒ Func&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt; ⇒ Nullable&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt; ⇒ =&amp;gt; IEnumerable&amp;lt;&amp;gt; composite associatively:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public partial class NaturalTransformationsTests
{
    [TestMethod()]
    public void CompositionTest()
    {
        Lazy&amp;lt;int&amp;gt; functor = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; 1);
        Tuple&amp;lt;Func&amp;lt;Lazy&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt;, Func&amp;lt;Lazy&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt;&amp;gt; compositions = Compositions&amp;lt;int&amp;gt;();
        IEnumerable&amp;lt;int&amp;gt; x = compositions.Item1(functor);
        IEnumerable&amp;lt;int&amp;gt; y = compositions.Item2(functor);
        Assert.AreEqual(x.Single(), y.Single());
    }

    private Tuple&amp;lt;Func&amp;lt;Lazy&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;&amp;gt;, Func&amp;lt;Lazy&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;&amp;gt;&amp;gt; Compositions&amp;lt;T&amp;gt;()
    {
        Func&amp;lt;Lazy&amp;lt;T&amp;gt;, Func&amp;lt;T&amp;gt;&amp;gt; t1 = NaturalTransformations.ToFunc;
        Func&amp;lt;Func&amp;lt;T&amp;gt;, Nullable&amp;lt;T&amp;gt;&amp;gt; t2 = NaturalTransformations.ToNullable;
        Func&amp;lt;Nullable&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;&amp;gt; t3 = NaturalTransformations.ToEnumerable;
        Func&amp;lt;Lazy&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;&amp;gt; x = t3.o(t2).o(t1);
        Func&amp;lt;Lazy&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;&amp;gt; y = t3.o(t2.o(t1));
        return Tuple.Create(x, y);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (7) Natural Transformation</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-7-natural-transformation/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-7-natural-transformation/</guid><description>If F: C -&gt; D and G: C -&gt; D are both functors from categories C to category D, a mapping can be constructed between F and G, called [natural transformation](http://en.wikipedia.org/wiki/Natural_transfo</description><pubDate>Sat, 08 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-4-natural-transformation&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-4-natural-transformation&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Natural transformation&lt;/h2&gt;
&lt;p&gt;If F: C -&amp;gt; D and G: C -&amp;gt; D are both functors from categories C to category D, a mapping can be constructed between F and G, called &lt;a href=&quot;http://en.wikipedia.org/wiki/Natural_transformation&quot;&gt;natural transformation&lt;/a&gt; and denoted η : F ⇒ G.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Functorial-Task-_1256F/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Category-Theory-via-C-5-Functorial-Task-_1256F/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;η: F ⇒ G is a family of morphisms from F to G, satisfying:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;∀ X ∈ ob(C), there is a morphism ηX: F(X) → G(X) associated to X, called the component of η at X.&lt;/li&gt;
&lt;li&gt;∀ m: X → Y ∈ hom(C), there is ηY ∘ F(m) ≌ G(m) ∘ ηX&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Natural transformations for LINQ&lt;/h2&gt;
&lt;p&gt;Previous parts demonstrated IEnumerable&amp;lt;&amp;gt; is the built-in functor, and Tuple&amp;lt;&amp;gt;, Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt; are functors too. C# has full LINQ support for IEnumerable&amp;lt;&amp;gt; because all the required extension methods are built-in in .NET. In other functors, taking the simplest Id&amp;lt;&amp;gt; as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
Nullable&amp;lt;int&amp;gt; query = from x in nullable
                      where x &amp;gt; 0
                      select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This cannot be compiled. Apparently C# compiler does not know how to handle “where”. The &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms228593.aspx&quot;&gt;C# language spec&lt;/a&gt; requires a list query methods to be implemented for corresponding LINQ syntax support, like Where is required for the above query to be compiled. It would be nice if the other functors can be mapped to IEnumerable&amp;lt;&amp;gt; by some natural transformations, so that the built in IEnumerable&amp;lt;&amp;gt; query methods can be leveraged. Actually, with the &lt;a href=&quot;/posts/understanding-linq-to-objects-5-implementing-iterator&quot;&gt;yield syntactic sugar&lt;/a&gt;, these natural transformations are really easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class NaturalTransformations
{
    // Lazy&amp;lt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;&amp;gt;
    public static IEnumerable&amp;lt;T&amp;gt; ToEnumerable&amp;lt;T&amp;gt;(this Lazy&amp;lt;T&amp;gt; lazy)
    {
        yield return lazy.Value;
    }

    // Func&amp;lt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;&amp;gt;
    public static IEnumerable&amp;lt;T&amp;gt; ToEnumerable&amp;lt;T&amp;gt;(this Func&amp;lt;T&amp;gt; function)
    {
        yield return function();
    }

    // Nullable&amp;lt;&amp;gt; =&amp;gt; IEnumerable&amp;lt;&amp;gt;
    public static IEnumerable&amp;lt;T&amp;gt; ToEnumerable&amp;lt;T&amp;gt;(this Nullable&amp;lt;T&amp;gt; nullable)
    {
        if (nullable.HasValue)
        {
            yield return nullable.Value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now full LINQ support are available for all those functors too, with the laziness remains.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; query = from x in function.ToEnumerable() 
                         where x &amp;gt; 0 
                         select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;Please notice the query itself becomes IEnumerbale&amp;lt;&amp;gt; too, either empty or containing 1 item.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class NaturalTransformationsTests
{
    [TestMethod()]
    public void LazyToEnumerableTest()
    {
        Lazy&amp;lt;int&amp;gt; functor = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; 1);
        IEnumerable&amp;lt;int&amp;gt; query1 = from x in functor.ToEnumerable()
                                  where x &amp;gt; 0
                                  select x;
        Assert.IsTrue(query1.Any());
        Assert.AreEqual(1, query1.Single());
        IEnumerable&amp;lt;int&amp;gt; query2 = from x in functor.ToEnumerable()
                                  where x &amp;lt; 0
                                  select x;
        Assert.IsFalse(query2.Any());
    }

    [TestMethod()]
    public void FuncToEnumerableTest()
    {
        Func&amp;lt;int&amp;gt; functor = () =&amp;gt; 1;
        IEnumerable&amp;lt;int&amp;gt; query1 = from x in functor.ToEnumerable()
                                  where x &amp;gt; 0
                                  select x;
        Assert.IsTrue(query1.Any());
        Assert.AreEqual(1, query1.Single());
        IEnumerable&amp;lt;int&amp;gt; query2 = from x in functor.ToEnumerable()
                                  where x &amp;lt; 0
                                  select x;
        Assert.IsFalse(query2.Any());
    }

    [TestMethod()]
    public void NullableToEnumerableTest()
    {
        Nullable&amp;lt;int&amp;gt; functor = new Nullable&amp;lt;int&amp;gt;(() =&amp;gt; Tuple.Create(true, 1));
        IEnumerable&amp;lt;int&amp;gt; query1 = from x in functor.ToEnumerable()
                                  where x &amp;gt; 0
                                  select x;
        Assert.IsTrue(query1.Any());
        Assert.AreEqual(1, query1.Single());
        IEnumerable&amp;lt;int&amp;gt; query2 = from x in functor.ToEnumerable()
                                  where x &amp;lt; 0
                                  select x;
        Assert.IsFalse(query2.Any());

        IEnumerable&amp;lt;int&amp;gt; query3 = from x in new Nullable&amp;lt;int&amp;gt;().ToEnumerable()
                                  select x;
        Assert.IsFalse(query3.Any());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (6) Functor-like Tuple&lt;&gt;, Task&lt;&gt; And IQueryable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-6-functor-like-tuple-task-and-iqueryable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-6-functor-like-tuple-task-and-iqueryable/</guid><description>Tuple&lt;&gt; looks like the simplest functor by just wrapping a value. It is most close to the [Identity functor of Haskell](http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Data-Functor-Identi</description><pubDate>Fri, 07 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-3-functor-and-linq-to-functors&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Tuple&amp;lt;&amp;gt; is like a functor&lt;/h2&gt;
&lt;p&gt;Tuple&amp;lt;&amp;gt; looks like the simplest functor by just wrapping a value. It is most close to the &lt;a href=&quot;http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Data-Functor-Identity.html&quot;&gt;Identity functor of Haskell&lt;/a&gt;. Its Select functions are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class TupleExtensions
{
    // C# specific functor pattern.
    public static Tuple&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this Tuple&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            new Tuple&amp;lt;TResult&amp;gt;(selector(source.Item1));

    // General abstract functor definition of Tuple&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;Tuple&amp;lt;TSource&amp;gt;, Tuple&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (/* this */ IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;Tuple&amp;lt;TSource&amp;gt;, Tuple&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Tuple&amp;lt;&amp;gt; can be recognized functor by compiler, so the LINQ syntax applies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple&amp;lt;int&amp;gt; tupleFunctor = new Tuple&amp;lt;int&amp;gt;(0);
Tuple&amp;lt;int&amp;gt; query = from x in tupleFunctor select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Tuple&amp;lt; , &amp;gt; is also like a functor&lt;/h3&gt;
&lt;p&gt;Tuple&amp;lt; , &amp;gt; can also be functor-like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class TupleExtensions
{
    // C# specific functor pattern.
    public static Tuple&amp;lt;TResult, T2&amp;gt; Select&amp;lt;TSource, TResult, T2&amp;gt;
        (this Tuple&amp;lt;TSource, T2&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            new Tuple&amp;lt;TResult, T2&amp;gt;(selector(source.Item1), source.Item2);

    // General abstract functor definition of Tuple&amp;lt; , &amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;Tuple&amp;lt;TSource, T2&amp;gt;, Tuple&amp;lt;TResult, T2&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult, T2&amp;gt;
        (this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;Tuple&amp;lt;TSource, T2&amp;gt;, Tuple&amp;lt;TResult, T2&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Select function just apply selector with the first value, and use the second value remains. In LINQ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple&amp;lt;int, string&amp;gt; functor = new Tuple&amp;lt;int, string&amp;gt;(0, &quot;text&quot;);
Tuple&amp;lt;bool, string&amp;gt; query = from x in functor select x &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar Select functions can be implemented for Tuple&amp;lt; , ,&amp;gt;, Tuple&amp;lt; , , ,&amp;gt;, … too.&lt;/p&gt;
&lt;h2&gt;Laziness vs. eagerness&lt;/h2&gt;
&lt;p&gt;Unlike previous Lazy, Func&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt; functors, there is no laziness for these 2 LINQ queries above. When queries are constructed, selector functions (x + 1 and x &amp;gt; 0) are already applied. Again, a tuple is just a wrapper of value(s). Computing a immediate value is required to construct each query, which is a tuple.&lt;/p&gt;
&lt;p&gt;The following unit tests demonstrates tuples fully satisfy functor laws but are lack of laziness.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class FunctorTests
{
    [TestMethod()]
    public void TupleTest()
    {
        bool isExecuted1 = false;
        Tuple&amp;lt;int&amp;gt; tuple = new Tuple&amp;lt;int&amp;gt;(0);
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };

        Tuple&amp;lt;int&amp;gt; query1 = from x in tuple select addOne(x); // Execution when constructing query.
        Assert.IsTrue(isExecuted1); // No laziness.

        Assert.AreEqual(0 + 1, query1.Item1);
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(tuple.Select(Functions.Id).Item1, Functions.Id(tuple).Item1);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addTwo = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        Tuple&amp;lt;string&amp;gt; query2 = tuple.Select(addTwo.o(addOne));
        Tuple&amp;lt;string&amp;gt; query3 = tuple.Select(addOne).Select(addTwo);
        Assert.AreEqual(query2.Item1, query3.Item1);
    }

    [TestMethod()]
    public void Tuple2Test()
    {
        bool isExecuted1 = false;
        Tuple&amp;lt;int, string&amp;gt; tuple = new Tuple&amp;lt;int, string&amp;gt;(0, &quot;a&quot;);
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };

        Tuple&amp;lt;int, string&amp;gt; query1 = from x in tuple select addOne(x); // Execution.
        Assert.IsTrue(isExecuted1); // No laziness.

        Assert.AreEqual(0 + 1, query1.Item1);
        Assert.AreEqual(&quot;a&quot;, query1.Item2);
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(tuple.Select(Functions.Id).Item1, Functions.Id(tuple).Item1);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addTwo = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        Tuple&amp;lt;string, string&amp;gt; query2 = tuple.Select(addTwo.o(addOne));
        Tuple&amp;lt;string, string&amp;gt; query3 = tuple.Select(addOne).Select(addTwo);
        Assert.AreEqual(query2.Item1, query3.Item1);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comparing to functors in previous part, Lazy&amp;lt;T&amp;gt; is a lazy version of Tuple&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Task&amp;lt;T&amp;gt; is like a functor too&lt;/h2&gt;
&lt;p&gt;With the &lt;a href=&quot;/archive/?tag=Async&quot;&gt;async/await&lt;/a&gt; feature of C# 5.0, Select is easy to implement for Task&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static partial class TaskExtensions
{
    public static async Task&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this Task&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; selector(await source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unlike any previous Select implementations, the [Pure] tag is missing. Yes, this Select is impure. As explained in &lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;another post&lt;/a&gt;, the await keyword will be compiled to a state machine, and executing this Select function will start the state machine. This Select function cannot be considered to be a pure function.&lt;/p&gt;
&lt;h2&gt;Purity vs. impurity&lt;/h2&gt;
&lt;p&gt;A function can be considered &lt;a href=&quot;http://en.wikipedia.org/wiki/Pure_function&quot;&gt;pure&lt;/a&gt; if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It returns the same value when given the same argument(s).&lt;/li&gt;
&lt;li&gt;It does not change state.&lt;/li&gt;
&lt;li&gt;It does not cause semantically observable &lt;a href=&quot;http://en.wikipedia.org/wiki/Side_effect_(computer_science)&quot;&gt;side effect&lt;/a&gt;. Every function application has side effect (like consuming certain amount of energy with the CPU), but here only semantically observable side effect matters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are some examples of pure functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All functions/lambda expressions in the &lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;lambda calculus&lt;/a&gt; posts.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.math.sin.aspx&quot;&gt;Math.Sin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Func&amp;lt;int&amp;gt; zero = () =&amp;gt; 0&lt;/li&gt;
&lt;li&gt;Func&amp;lt;int, bool&amp;gt; isPositive = x =&amp;gt; x &amp;gt; 0&lt;/li&gt;
&lt;li&gt;The Select functions for IEnumerable&amp;lt;&amp;gt;, Tuple&amp;lt;&amp;gt;, Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;/posts/understanding-linq-to-objects-3-query-methods&quot;&gt;built-in query methods&lt;/a&gt; for IEnumerable&amp;lt;&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and examples of impure functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/9b3ta19y.aspx&quot;&gt;Random.Next&lt;/a&gt;, which may return different value for each application&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IO: &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms143368.aspx&quot;&gt;File.ReadAllText&lt;/a&gt;/&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms143375.aspx&quot;&gt;File.WriteAllText&lt;/a&gt;, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh138332.aspx&quot;&gt;WebClient.DownloadStringTaskAsync&lt;/a&gt;. &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hebffx2d.aspx&quot;&gt;Console.Write&lt;/a&gt;/&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.console.read.aspx&quot;&gt;Console.Read&lt;/a&gt; for console application, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms598674.aspx&quot;&gt;MessageBox.Show&lt;/a&gt; for WPF, …&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;async method with await keyword, which &lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;creates a state machine and start it&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EnumerableEx.ForEach, and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/vstudio/ttw7t8t6.aspx&quot;&gt;foreach iteration&lt;/a&gt; on a IEnumerable&amp;lt;T&amp;gt;, which changes that IEnumerable&amp;lt;T&amp;gt;’s state.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd270682.aspx&quot;&gt;Task.Start&lt;/a&gt;/&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd321703.aspx&quot;&gt;CancellationTokenSource.Cancel&lt;/a&gt;, which can change the state of Task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.submitchanges.aspx&quot;&gt;DataContext.SubmitChanges&lt;/a&gt; in &lt;a href=&quot;/posts/understanding-linq-to-sql-7-data-changing&quot;&gt;LINQ to SQL&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Purity and category theory&lt;/h3&gt;
&lt;p&gt;In a category, it does not make sense if a morphism (an arrow from one object to another object) becomes uncertain, or changes state, or causes side effects. So here in DotNet category, where morphisms becomes C#/.NET functions, these C#/.NET functions must be pure. Usually in C# programming, side effects and purity is not specially managed, but here in the category theory posts, function’s purity will be carefully taken care of.&lt;/p&gt;
&lt;h3&gt;Purity and .NET&lt;/h3&gt;
&lt;p&gt;C# language is not designed to be purely functional, neither are .NET framework libraries. To demonstrate this, an easy way is to use &lt;a href=&quot;https://www.nuget.org/packages/Mono.Cecil/&quot;&gt;Mono.Cecil library&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Install-Package Mono.Cecil&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;MethodDefinition&amp;gt; GetMethods
        (string assemblyPath, bool isPublicOnly) =&amp;gt;
            from module in AssemblyDefinition.ReadAssembly(assemblyPath).Modules
            from type in module.Types
            from method in type.Methods
            where !isPublicOnly || method.IsPublic
            select method;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be used to query the public methods in a library. Take mscorlib.dll as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string mscorlib = new Uri(typeof(object).Assembly.GetName().EscapedCodeBase).AbsolutePath;
int methodsCount = ReflectionHelper.GetMethods(mscorlib, true).Count();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are 15627 public methods in mscorlib.dll.&lt;/p&gt;
&lt;p&gt;The following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;MethodDefinition&amp;gt; GetMethods&amp;lt;TAttribute&amp;gt;
        (string assemblyPath, bool isPublicOnly)
        where TAttribute : Attribute =&amp;gt;
            from method in GetMethods(assemblyPath, isPublicOnly)
            where method.CustomAttributes.Any(attribute =&amp;gt; attribute.AttributeType.FullName.Equals(
                typeof (TAttribute).FullName, StringComparison.Ordinal))
            select method;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be used to query pure methods of a library, that is, how many methods are tagged with [Pure] attribute in its contract reference assembly. For mscorlib.all, just query mscorlib.contracts.dll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const string mscorlibContracts = @&quot;C:\Program Files (x86)\Microsoft\Contracts\Contracts\.NETFramework\v4.5\mscorlib.Contracts.dll&quot;;
int pureMethodsCount = ReflectionHelper.GetMethods&amp;lt;PureAttribute&amp;gt;(mscorlibContracts, true).Count();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is, in mscorlib.dll, only 1202 (about 8%) public methods are pure (attributed with [Pure] in mscorlib.contracts.dll).&lt;/p&gt;
&lt;p&gt;Here Mono.Cecil’s AssemblyDefinition.ReadAssembly is used instead of .NET built in Assembly.Load:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;MethodInfo&amp;gt; _GetMethods&amp;lt;TAttribute&amp;gt;
        (string assemblyPath, bool isPublicOnly)
        where TAttribute : Attribute =&amp;gt;
            from type in Assembly.Load(AssemblyName.GetAssemblyName(assemblyPath)).GetTypes()
            from method in type.GetMethods()
            where (!isPublicOnly || method.IsPublic) 
                    &amp;amp;&amp;amp; method.GetCustomAttributes(typeof (TAttribute), false).Any()
            select method;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;because when getting types from special assemblies like mscorlib.contracts.dll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int pureMethodsCount = ReflectionHelper._GetMethods&amp;lt;PureAttribute&amp;gt;(mscorlibContracts, true).Count();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assembly.GetTypes() throws exception:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Could not load type &apos;System.Object&apos; from assembly &apos;mscorlib.Contracts, Version=0.0.0.0, Culture=neutral, PublicKeyToken=188286aac86319f9&apos; because the parent does not exist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a demonstration of Linq to Object&lt;/p&gt;
&lt;p&gt;One last thing to notice: in C#/.NET world, there is no analysis tools to identify the purity of any API. [Pure] is used based on manual analysis.&lt;/p&gt;
&lt;h2&gt;Purity, laziness and LINQ&lt;/h2&gt;
&lt;p&gt;When working with LINQ to Objects, one great feature is LINQ query has no side effect:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; functor = Enumerable.Range(0, 3);
Func&amp;lt;int, int&amp;gt; selector = x =&amp;gt; x + 1;
IEnumerable&amp;lt;int&amp;gt; query = from x in functor where x &amp;gt; 0 select selector(x);
// At runtime, here execution of query is deferred, the selector function is guaranteed not applied.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the query is a cold IEnumerable&amp;lt;T&amp;gt;. selector’s application is guaranteed to be deferred because the query methods (Select/Where/… functions) are pure functions. Such purity and laziness are expected in LINQ query.&lt;/p&gt;
&lt;h3&gt;Functor vs. functor-like&lt;/h3&gt;
&lt;p&gt;At compile time, C# compiler does not have knowledge about laziness. In the case of Tuple&amp;lt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple&amp;lt;int&amp;gt; functor = new Tuple&amp;lt;int&amp;gt;(0);
Func&amp;lt;int, int&amp;gt; selector = x =&amp;gt; x + 1;
Tuple&amp;lt;int&amp;gt; query = from x in functor select selector(x);
// At runtime, here the selector function is already applied.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Theoretically, Tuple&amp;lt;&amp;gt; is a functor (again, just like the Identity functor in Haskell). However, in these C# posts, because its unexpected behavior (lack of laziness) in LINQ query, it will only be called functor-like.&lt;/p&gt;
&lt;p&gt;At compile time, C# compiler does not have knowledge about side effect or purity either. With the help of above (impure) Select extension method, the LINQ syntax still works with Task&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Task&amp;lt;int&amp;gt; functorial = Task.Run(() =&amp;gt; 0);
Func&amp;lt;int, int&amp;gt; selector = x =&amp;gt; x + 1;
Task&amp;lt;int&amp;gt; query = from x in functorial select selector(x);
// At runtime, here query is not used yet, but the selector function may be already applied, or not.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This usage looks as “functorial” as any other LINQ to Objects examples. The big difference is, this query can be a hot Task&amp;lt;int&amp;gt;, and the application of selector is unpredictable. When query is created, selector may be not applied, being applied, or already applied.&lt;/p&gt;
&lt;p&gt;Also consider the equivalent selecting/mapping of morphisms in DotNet category:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// General abstract functor definition is invalid.
public static IMorphism&amp;lt;Task&amp;lt;TSource&amp;gt;, Task&amp;lt;TResult&amp;gt;, DotNet&amp;gt; _Select&amp;lt;TSource, TResult&amp;gt;(
    this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector)
{
    return new DotNetMorphism&amp;lt;Task&amp;lt;TSource&amp;gt;, Task&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The new impure DotNetMorphism in DotNet category becomes an invalid morphism because of the impurity. So Task&amp;lt;T&amp;gt; is not a functor. Just like in the lambda calculus posts, this function is prefixed with a underscore, meaning it is syntactically legal in C#, but semantically invalid in category theory.&lt;/p&gt;
&lt;p&gt;In these posts, the term “functor”, “functorial”, “functor-like” will be carefully used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Something is functor/functorial: it is fully a functor and work with LINQ syntax. As fore mentioned, Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;, Nullable&amp;lt;&amp;gt; are all functors like the built-in IEnumerable&amp;lt;&amp;gt;.&lt;/li&gt;
&lt;li&gt;Something is functor-like: it looks like functor and can be work with LINQ syntax for C# functor, but strictly it is not a functor. Tuple&amp;lt;&amp;gt;, Task&amp;lt;&amp;gt; are functor-like. When using them in LINQ, their behavior can be unexpected.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;IQueryable&amp;lt;&amp;gt; is also like a functor&lt;/h2&gt;
&lt;p&gt;In the LINQ to SQL part, IQueryable&amp;lt;&amp;gt;’s Select extension method is used a lot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    var results = from product in source
                  select new
                      {
                          product.ProductName,
                          product.UnitPrice
                      }; // Laziness

    results.ForEach(value =&amp;gt; { }); // Execution
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or equivalently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    var results = source.Select(product =&amp;gt; new
                    {
                        product.ProductName,
                        product.UnitPrice
                    }); // Laziness

    results.ForEach(value =&amp;gt; { }); // Execution
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If looking into the implementation of Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class QueryableExtensions
{
    public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
            source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(Expression.Call(
                null, 
                ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
                    new Type[] { typeof(TSource), typeof(TResult) }),
                new Expression[] { source.Expression, Expression.Quote(selector) }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;discussed before&lt;/a&gt;, when working with IQueryable&amp;lt;T&amp;gt;, the lambda expressions are not functions but &lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;data structure - an abstract syntax tree&lt;/a&gt;. So that a lambda-like expression trees in the query can be compiled to something else - here a T-SQL query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very powerful feature of C# language and LINQ.&lt;/p&gt;
&lt;h2&gt;Hot task vs. cold task, and unit tests&lt;/h2&gt;
&lt;p&gt;The following unit tests demonstrate above Select function for Task&amp;lt;T&amp;gt; works for both hot (already started) and cold (not yet started) tasks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class FunctorialTests
{
    [TestMethod()]
    public void HotTaskTest()
    {
        bool isExecuted1 = false;
        Task&amp;lt;string&amp;gt; hotTask = System.Threading.Tasks.Task.Run(() =&amp;gt; &quot;a&quot;);
        Func&amp;lt;string, string&amp;gt; append = x =&amp;gt; { isExecuted1 = true; return x + &quot;b&quot;; };

        Task&amp;lt;string&amp;gt; query1 = from x in hotTask select append(x);
        Assert.AreEqual(&quot;a&quot; + &quot;b&quot;, query1.Result);
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(hotTask.Select(Functions.Id).Result, Functions.Id(hotTask).Result);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;string, int&amp;gt; length = x =&amp;gt; x.Length;
        Task&amp;lt;int&amp;gt; query2 = hotTask.Select(length.o(append));
        Task&amp;lt;int&amp;gt; query3 = hotTask.Select(append).Select(length);
        Assert.AreEqual(query2.Result, query3.Result);
    }

    [TestMethod()]
    public void ColdTaskTest()
    {
        bool isExecuted2 = false;
        bool isExecuted1 = false;
        Task&amp;lt;string&amp;gt; coldTask = new Task&amp;lt;string&amp;gt;(() =&amp;gt; { isExecuted2 = true; return &quot;c&quot;; });
        Func&amp;lt;string, string&amp;gt; append = x =&amp;gt; { isExecuted1 = true; return x + &quot;d&quot;; };

        Task&amp;lt;string&amp;gt; query1 = from x in coldTask select append(x);
        Assert.IsFalse(isExecuted2);
        Assert.IsFalse(isExecuted1);

        coldTask.Start();
        Assert.AreEqual(&quot;c&quot; + &quot;d&quot;, query1.Result);
        Assert.IsTrue(isExecuted2);
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(coldTask.Select(Functions.Id).Result, Functions.Id(coldTask).Result);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        coldTask = new Task&amp;lt;string&amp;gt;(() =&amp;gt; &quot;c&quot;);
        Func&amp;lt;string, int&amp;gt; length = x =&amp;gt; x.Length;
        Task&amp;lt;int&amp;gt; query2 = coldTask.Select(length.o(append));
        Task&amp;lt;int&amp;gt; query3 = coldTask.Select(append).Select(length);
        coldTask.Start();
        Assert.AreEqual(query2.Result, query3.Result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (5) More Functors: Lazy&lt;&gt;, Func&lt;&gt; And Nullable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-5-more-functors-lazy-func-and-nullable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-5-more-functors-lazy-func-and-nullable/</guid><description>A simple functor in DotNet category is Lazy&lt;&gt;. Its Select functions can be easily implemented:</description><pubDate>Thu, 06 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-3-functor-and-linq-to-functors&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Lazy&amp;lt;&amp;gt; functor&lt;/h2&gt;
&lt;p&gt;A simple functor in DotNet category is Lazy&amp;lt;&amp;gt;. Its Select functions can be easily implemented:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class LazyExtensions
{
    // C# specific functor pattern.
    public static Lazy&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this Lazy&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            new Lazy&amp;lt;TResult&amp;gt;(() =&amp;gt; selector(source.Value));

    // General abstract functor definition of Lazy&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;Lazy&amp;lt;TSource&amp;gt;, Lazy&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (/* this */ IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;Lazy&amp;lt;TSource&amp;gt;, Lazy&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, above 2 Select functions are equivalent. The second one looks the same as IEnumerable&amp;lt;&amp;gt;’s: source =&amp;gt; source.Select(selector.Invoke), except the type info IEnumerable&amp;lt;&amp;gt; are replaced by Lazy&amp;lt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;In LINQ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Lazy&amp;lt;int&amp;gt; lazyFunctor = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; 0);
Lazy&amp;lt;int&amp;gt; query = from x in lazyFunctor select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is similar to the &lt;a href=&quot;http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Data-Functor-Identity.html&quot;&gt;Identity functor of Haskell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the second Select function, keyword “this” is commented out; otherwise, the EnumerableGeneralTest function in previous part cannot be compiled. In :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EnumerableAssert.AreEqual(
    addTwoMorphism.o(addOneMorphism).Select().Invoke(functor), 
    addTwoMorphism.Select().o(addOneMorphism.Select()).Invoke(functor));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When compiling the Select function application, compiler will look for the Select extension method in the context. If looking at EnumerableExtensions.Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IMorphism&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
    (this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
        new DotNetMorphism&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;from previous part, and LazyExtensions.Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IMorphism&amp;lt;Lazy&amp;lt;TSource&amp;gt;, Lazy&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
    (this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
        new DotNetMorphism&amp;lt;Lazy&amp;lt;TSource&amp;gt;, Lazy&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;they have the same the same function parameter (this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector), and type parameters&amp;lt;TSource, TResult&amp;gt; . The compiler will report an ambiguity error:&lt;/p&gt;
&lt;p&gt;Error CS0121 The call is ambiguous between the following methods or properties: &apos;LazyExtensions.Select&amp;lt;TSource, TResult&amp;gt;(IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt;)&apos; and &apos;EnumerableExtensions.Select&amp;lt;TSource, TResult&amp;gt;(IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt;)&apos;&lt;/p&gt;
&lt;p&gt;So above “this” keyword is commented out to make EnumerableExtensions.Select the only available extension method for IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Func&amp;lt;&amp;gt; functor&lt;/h2&gt;
&lt;p&gt;Func&amp;lt;&amp;gt; is a functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class FuncExtensions
{
    public static Func&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this Func&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; () =&amp;gt; selector(source());

    // General abstract functor definition of Func&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;Func&amp;lt;TSource&amp;gt;, Func&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (/* this */ IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;Func&amp;lt;TSource&amp;gt;, Func&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the general abstract version of Select is the same as IEnumerable&amp;lt;&amp;gt;’s and Lazy&amp;lt;&amp;gt;’s.&lt;/p&gt;
&lt;p&gt;In LINQ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int&amp;gt; functionFunctor = new Func&amp;lt;int&amp;gt;(() =&amp;gt; 1);
Func&amp;lt;int&amp;gt; query = from x in functionFunctor select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually any function can be Func&amp;lt;&amp;gt; (Func&amp;lt;T&amp;gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functions with N-arity can be transformed to Func&amp;lt;T&amp;gt; with closure.&lt;/li&gt;
&lt;li&gt;Functions without return value like an Action, can be transformed to Func&amp;lt;Void&amp;gt;. In C# Func&amp;lt;Void&amp;gt; Be compiled, so they can be transformed to Func&amp;lt;Unit&amp;gt;, borrowed &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd483472.aspx&quot;&gt;unit from F#.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = x =&amp;gt; x &amp;gt; 0;
Func&amp;lt;int, Func&amp;lt;bool&amp;gt;&amp;gt; isNegative = x =&amp;gt; from y in isPositive.Partial(x) select !y;

Action&amp;lt;int&amp;gt; action = x =&amp;gt; { int y = x + 1; };
Func&amp;lt;int, Unit&amp;gt; returnUnit = x =&amp;gt; { action(x); return null; };
Func&amp;lt;int, Func&amp;lt;Unit&amp;gt;&amp;gt; query = x =&amp;gt; from y in returnUnit.Partial(0) select y;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In last query expression, y’s type is &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee370443.aspx&quot;&gt;Microsoft.FSharp.Core.Unit&lt;/a&gt;, and it is always null.&lt;/p&gt;
&lt;h3&gt;Fun&amp;lt; , &amp;gt; functor&lt;/h3&gt;
&lt;p&gt;Func&amp;lt;T, TResult&amp;gt; can also have its own Select function and becomes a natural functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [Pure]
public static partial class FuncExtensions
{
    public static Func&amp;lt;TSourceArg, TResult&amp;gt; Select&amp;lt;TSourceArg, TSource, TResult&amp;gt;
        (this Func&amp;lt;TSourceArg, TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; arg =&amp;gt; selector(source(arg));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or equivalently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Func&amp;lt;TSource, TResult&amp;gt; Select2&amp;lt;TSource, TMiddle, TResult&amp;gt;
    (this Func&amp;lt;TSource, TMiddle&amp;gt; source, Func&amp;lt;TMiddle, TResult&amp;gt; selector) =&amp;gt; selector.o(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now LINQ syntax applies without closure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = x =&amp;gt; x &amp;gt; 0;
Func&amp;lt;int, bool&amp;gt; isNegative = from x in isPositive select !x;

Action&amp;lt;int&amp;gt; action = x =&amp;gt; { int y = x + 1; };
Func&amp;lt;int, Unit&amp;gt; returnUnit = x =&amp;gt; { action(x); return null; };
Func&amp;lt;int, Unit&amp;gt; query = from x in returnUnit select x;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Nullable&amp;lt;&amp;gt; functor&lt;/h2&gt;
&lt;p&gt;System.Nullable&amp;lt;&amp;gt; can be a functor too. To be more general, the Nullable&amp;lt;T&amp;gt; for any type will be used again.&lt;/p&gt;
&lt;p&gt;Here are the Select functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class NullableExtensions
{
    // C# specific functor pattern.
    public static Nullable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this Nullable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
            new Nullable&amp;lt;TResult&amp;gt;(() =&amp;gt; source.HasValue
                    ? Tuple.Create(true, selector(source.Value))
                    : Tuple.Create(false, default(TResult)));

    // General abstract functor definition of Nullable&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;Nullable&amp;lt;TSource&amp;gt;, Nullable&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (/* this */ IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;Nullable&amp;lt;TSource&amp;gt;, Nullable&amp;lt;TResult&amp;gt;&amp;gt;(source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, the general version of Select looks the same as the code for IEnumerable&amp;lt;&amp;gt;, Lazy&amp;lt;&amp;gt;, Func&amp;lt;&amp;gt;. As explained in previous part, C#/CLR does not support &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_class#Higher-kinded_polymorphism&quot;&gt;higher-kinded polymorphism&lt;/a&gt;, so the same algorithm has to repeat again and again.&lt;/p&gt;
&lt;p&gt;And the LINQ syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Nullable&amp;lt;int&amp;gt; noValue = new Nullable&amp;lt;int&amp;gt;(); // or new Nullable&amp;lt;int&amp;gt;(() =&amp;gt; Tuple.Create(false, default(int)))
Nullable&amp;lt;int&amp;gt; query1 = from x in noValue select x + 1;

Nullable&amp;lt;int&amp;gt; hasValue = new Nullable&amp;lt;int&amp;gt;(() =&amp;gt; Tuple.Create(true, 0));
Nullable&amp;lt;int&amp;gt; query2 = from x in noValue select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Functor laws, laziness, and unit tests&lt;/h2&gt;
&lt;p&gt;All the above generics satisfy functor laws, and they have laziness in LINQ queries. These properties are demonstrated by the following unit tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class FunctorTests
{
    [TestMethod()]
    public void LazyTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Lazy&amp;lt;int&amp;gt; lazy = new Lazy&amp;lt;int&amp;gt;(() =&amp;gt; { isExecuted1 = true; return 0; });
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted2 = true; return x + 1; };

        Lazy&amp;lt;int&amp;gt; query1 = from x in lazy select addOne(x);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.

        Assert.AreEqual(0 + 1, query1.Value); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(lazy.Select(Functions.Id).Value, Functions.Id(lazy).Value);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addTwo = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        Lazy&amp;lt;string&amp;gt; query2 = lazy.Select(addTwo.o(addOne));
        Lazy&amp;lt;string&amp;gt; query3 = lazy.Select(addOne).Select(addTwo);
        Assert.AreEqual(query2.Value, query3.Value);
    }

    [TestMethod()]
    public void FuncTest()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int&amp;gt; zero = () =&amp;gt; { isExecuted1 = true; return 0; };
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted2 = true; return x + 1; };

        Func&amp;lt;int&amp;gt; query1 = from x in zero select addOne(x);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.

        Assert.AreEqual(0 + 1, query1()); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(zero.Select(Functions.Id)(), Functions.Id(zero)());
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addTwo = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        Func&amp;lt;string&amp;gt; query2 = zero.Select(addTwo.o(addOne));
        Func&amp;lt;string&amp;gt; query3 = zero.Select(addOne).Select(addTwo);
        Assert.AreEqual(query2(), query3());
    }

    [TestMethod()]
    public void Func2Test()
    {
        bool isExecuted1 = false;
        bool isExecuted2 = false;
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; { isExecuted1 = true; return x + 1; };
        Func&amp;lt;int, int&amp;gt; addTwo = x =&amp;gt; { isExecuted2 = true; return x + 2; };

        Func&amp;lt;int, int&amp;gt; query1 = from x in addOne select addTwo(x);
        Assert.IsFalse(isExecuted1); // Laziness.
        Assert.IsFalse(isExecuted2); // Laziness.

        Assert.AreEqual(0 + 1 + 2, query1(0)); // Execution.
        Assert.IsTrue(isExecuted1);
        Assert.IsTrue(isExecuted2);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(addOne.Select(Functions.Id)(1), Functions.Id(addOne)(1));
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addThree = x =&amp;gt; (x + 3).ToString(CultureInfo.InvariantCulture);
        Func&amp;lt;int, string&amp;gt; query2 = addOne.Select(addThree.o(addTwo));
        Func&amp;lt;int, string&amp;gt; query3 = addOne.Select(addTwo).Select(addThree);
        Assert.AreEqual(query2(2), query3(2));
    }

    [TestMethod()]
    public void NullableWithoutValueTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, string&amp;gt; append = x =&amp;gt; { isExecuted1 = true; return x + &quot;b&quot;; };
        Nullable&amp;lt;int&amp;gt; nullable = new Nullable&amp;lt;int&amp;gt;();

        Nullable&amp;lt;string&amp;gt; query1 = from x in nullable select append(x);
        Assert.IsFalse(isExecuted1); // Laziness.

        Assert.IsFalse(query1.HasValue); // Execution.
        Assert.IsFalse(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(query1.Select(Functions.Id).HasValue, Functions.Id(query1).HasValue);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;string, int&amp;gt; length = x =&amp;gt; x.Length;
        Nullable&amp;lt;int&amp;gt; query2 = nullable.Select(length.o(append));
        Nullable&amp;lt;int&amp;gt; query3 = nullable.Select(append).Select(length);
        Assert.AreEqual(query2.HasValue, query3.HasValue);
    }

    [TestMethod()]
    public void NullableWithValueTest()
    {
        bool isExecuted1 = false;
        Func&amp;lt;int, string&amp;gt; append = x =&amp;gt; { isExecuted1 = true; return x + &quot;b&quot;; };
        Nullable&amp;lt;int&amp;gt; nullable = new Nullable&amp;lt;int&amp;gt;(() =&amp;gt; Tuple.Create(true, 1));

        Nullable&amp;lt;string&amp;gt; query1 = from x in nullable select append(x);
        Assert.IsFalse(isExecuted1); // Laziness.

        Assert.IsTrue(query1.HasValue); // Execution.
        Assert.AreEqual(&quot;1b&quot;, query1.Value);
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        Assert.AreEqual(query1.Select(Functions.Id).HasValue, Functions.Id(query1).HasValue);
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;string, int&amp;gt; length = x =&amp;gt; x.Length;
        Nullable&amp;lt;int&amp;gt; query2 = nullable.Select(length.o(append));
        Nullable&amp;lt;int&amp;gt; query3 = nullable.Select(append).Select(length);
        Assert.AreEqual(query2.Value, query3.Value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tests for the general version of Select functions are not showing here, since they are equivalent with these C# specific Select functions.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (4) Functor And IEnumerable&lt;&gt;</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-4-functor-and-ienumerable/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-4-functor-and-ienumerable/</guid><description>A  F: C → D is a structure-preserving ) from category C to category D:</description><pubDate>Wed, 05 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-3-functor-and-linq-to-functors&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-3-functor-and-linq-to-functors&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Functor and functor laws&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor&quot;&gt;functor&lt;/a&gt; F: C → D is a structure-preserving &lt;a href=&quot;http://en.wikipedia.org/wiki/Map_(mathematics)&quot;&gt;mapping&lt;/a&gt; from category C to category D:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/32db27394385_12912/image6_thumb_thumb_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/32db27394385_12912/image6_thumb_thumb_thumb_1.png&quot; alt=&quot;image6_thumb_thumb&quot; title=&quot;image6_thumb_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As above diagram represented, F:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;maps objects X, Y ∈ ob(C) to objects F(X), F(Y) ∈ ob(D)&lt;/li&gt;
&lt;li&gt;also maps morphism mC: X → Y ∈ hom(C) to a new morphism mD: F(X) → F(Y) ∈ hom(D)
&lt;ul&gt;
&lt;li&gt;To align to C#/.NET terms, this mapping ability of functor will be called “select” instead of “map”. That is, F selects mC to mD .&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and satisfies the functor laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;F(idX) ≌ idF(X), see above image&lt;/li&gt;
&lt;li&gt;Select(m2 ∘ m1) ≌ Select(m2) ∘ Select(m1)&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/32db27394385_12912/image3_thumb_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/32db27394385_12912/image3_thumb_thumb_thumb.png&quot; alt=&quot;image3_thumb_thumb&quot; title=&quot;image3_thumb_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So the general functor should be like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IFunctor&amp;lt;in TSourceCategory, out TTargetCategory, TFunctor&amp;lt;&amp;gt;&amp;gt;
    where TSourceCategory : ICategory&amp;lt;TSourceCategory&amp;gt;
    where TTargetCategory : ICategory&amp;lt;TTargetCategory&amp;gt;
    where TFunctor&amp;lt;&amp;gt; : IFunctor&amp;lt;TSourceCategory, TTargetCategory, TFunctor&amp;lt;&amp;gt;&amp;gt;
{
    IMorphism&amp;lt;TFunctor&amp;lt;TSource&amp;gt;, TFunctor&amp;lt;TResult&amp;gt;, TTargetCategory&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        IMorphism&amp;lt;TSource, TResult, TSourceCategory&amp;gt; selector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A TFunctor&amp;lt;&amp;gt;, which implements IFunctor&amp;lt;…&amp;gt; interface, should have a method Select, which takes a morphism from TSource to TResult in TFromCategory, and returns a morphism from TFunctor&amp;lt;TSource&amp;gt; to TFunctor&amp;lt;TResult&amp;gt; in TToCategory.&lt;/p&gt;
&lt;h2&gt;C#/.NET functors&lt;/h2&gt;
&lt;p&gt;A C# functor can select (maps) a morphism in &lt;a href=&quot;/posts/category-theory-via-c-sharp-1-fundamentals-category-object-and-morphism&quot;&gt;DotNet category&lt;/a&gt; to another morphism still in DotNet category, such functor maps from a category to itself is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Functor#Examples&quot;&gt;endofunctor&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Endofunctor&lt;/h3&gt;
&lt;p&gt;A endofunctor can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public interface IEndofunctor&amp;lt;TCategory, TEndofunctor&amp;lt;&amp;gt;&amp;gt;
    : IFunctor&amp;lt;TCategory, TCategory, TEndofunctor&amp;lt;&amp;gt;&amp;gt;
    where TCategory : ICategory&amp;lt;TCategory&amp;gt;
    where TEndofunctor&amp;lt;&amp;gt; : IFunctor&amp;lt;TEndofunctor, TEndofunctor&amp;lt;&amp;gt;&amp;gt;
{
    IMorphism&amp;lt;TEndofunctor&amp;lt;TSource&amp;gt;, TEndofunctor&amp;lt;TResult&amp;gt;, TCategory&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        IMorphism&amp;lt;TSource, TResult, TCategory&amp;gt; selector);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So an endofunctor in DotNet category, e.g. EnumerableFunctor&amp;lt;T&amp;gt;, should be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
// EnumerableFunctor&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet 
public class EnumerableFunctor&amp;lt;T&amp;gt; : IFunctor&amp;lt;DotNet, DotNet, EnumerableFunctor&amp;lt;&amp;gt;&amp;gt;
{
    public IMorphism&amp;lt;EnumerableFunctor&amp;lt;TSource&amp;gt;, EnumerableFunctor&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
        IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector)
    {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, all the above code cannot be compiled, because C# does not support &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_class#Higher-kinded_polymorphism&quot;&gt;higher-kinded polymorphism&lt;/a&gt;. This is actually the biggest challenge of explaining category theory in C#.&lt;/p&gt;
&lt;h3&gt;Kind issue of C# language/CLR&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Kind_(type_theory)&quot;&gt;Kind&lt;/a&gt; is the (meta) type of a type. In another word, a type’s kind is like a function’s type. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;int’s kind is *, where * can be read as a concrete type or closed type. This is like function (() =&amp;gt; 0)’s type is Func&amp;lt;int&amp;gt;.&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;int&amp;gt; is a closed type, its kind is also *.&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;&amp;gt; is a open type, its kind is * → *, which can be read as taking a closed type (e.g. int) and constructs another closed type (IEnumerable&amp;lt;int&amp;gt;). This is like function ((int x) =&amp;gt; x)’s type is Func&amp;lt;int, int&amp;gt;.&lt;/li&gt;
&lt;li&gt;In above IFunctor&amp;lt;TFromCategory, TToCategory, TFunctor&amp;lt;&amp;gt;&amp;gt; definition, its type parameter TFunctor&amp;lt;&amp;gt; has a kind * → *, which makes IFunctor&amp;lt;TFromCategory, TToCategory, TFunctor&amp;lt;&amp;gt;&amp;gt; having a higher order kind: * → * → (* → *) → *. This is like a function become a higher order function if its parameter is a function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, C# does not support type with higher order kind. As &lt;a href=&quot;http://en.wikipedia.org/wiki/Erik_Meijer_(computer_scientist)&quot;&gt;Erik Meijer&lt;/a&gt; mentioned in &lt;a href=&quot;https://channel9.msdn.com/Shows/Going+Deep/Erik-Meijer-Functional-Programming&quot;&gt;this video&lt;/a&gt;, the reasons are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CLR does not support higher order kind&lt;/li&gt;
&lt;li&gt;Supporting higher order kind causes more kind issues. For example, IDictionary&amp;lt;,&amp;gt; is a IEnumerble&amp;lt;&amp;gt;, but they have different kinds: * → * → * vs. * → *.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, instead of higher-kinded polymorphism, C# &lt;a href=&quot;http://stackoverflow.com/questions/4411279/haskell-typeclasses-and-c-template-classes/4412319#4412319&quot;&gt;recognizes the functor pattern&lt;/a&gt; of each functor, which will be demonstrated by following code.&lt;/p&gt;
&lt;h3&gt;The built-in IEnumerable&amp;lt;&amp;gt; functor&lt;/h3&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; is the a built-in functor in C#/.NET. Why it is a functor and How is this implemented? First, in DotNet category, if IEnumerable&amp;lt;&amp;gt; is a functor, it should be an endofunctor IEnumerable&amp;lt;&amp;gt;: DotNet → DotNet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IMorphism&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; should be able to do the above select/map from DotNet category to DotNet category.&lt;/p&gt;
&lt;p&gt;Second, in DotNet category, morphisms are functions. That is, IMorphism&amp;lt;TSouece, TResult, DotNet&amp;gt; and Func&amp;lt;TSouece, TResult&amp;gt; can convert to each other. So above select/map is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Select = selector -&amp;gt; (source =&amp;gt; result)
public static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Select’s type is Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt;, so it is a curried function. It can be uncurried to a equivalent Func&amp;lt;T1, T2, TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Select = (selector, source) -&amp;gt; result
public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;( // Uncurried
    Func&amp;lt;TSource, TResult&amp;gt; selector, IEnumerable&amp;lt;TSource&amp;gt; source)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The positions of 2 parameters can be swapped:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Select = (source, selector) -&amp;gt; result
public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;( // Parameter swapped
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final step is to make Select &lt;a href=&quot;/posts/understanding-csharp-3-0-features-5-extension-method&quot;&gt;an extension method by adding a this keyword&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Select = (this source, selector) -&amp;gt; result
public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;( // Extension method
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is just &lt;a href=&quot;/posts/understanding-csharp-3-0-features-5-extension-method&quot;&gt;a syntactic sugar&lt;/a&gt; and does not change anything. The above transformation shows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In DotNet category, IEnumerable&amp;lt;&amp;gt;’s functoriality is equivalent to a simple familiar extension method Select&lt;/li&gt;
&lt;li&gt;If the last Select version above can be implemented, then IEnumerable&amp;lt;T&amp;gt; is a functor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;’s Select extension method is already implemented as System.Linq.Enumerable.Select. But it is easy to implement manually:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class EnumerableExtensions
{
    // C# specific functor pattern.
    public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;( // Extension
        this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
    {
        foreach (TSource item in source)
        {
            yield return selector(item);
        }
    }

    // General abstract functor definition of IEnumerable&amp;lt;&amp;gt;: DotNet -&amp;gt; DotNet.
    public static IMorphism&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;, DotNet&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;
        (this IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; selector) =&amp;gt; 
            new DotNetMorphism&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;(
                source =&amp;gt; source.Select(selector.Invoke));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So IEnumerable&amp;lt;T&amp;gt; is a functor, The both Select functions are implemented as extension method for convenience.&lt;/p&gt;
&lt;h2&gt;Functor pattern of LINQ&lt;/h2&gt;
&lt;p&gt;Generally in C#, if a type F&amp;lt;TSource&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;have a instance method or extension method Select, taking a Func&amp;lt;TSource, TResult&amp;gt; parameter and returning a F&amp;lt;TResult&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;then:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F&amp;lt;&amp;gt; is an endofunctor F&amp;lt;&amp;gt;: DotNet → DotNet
&lt;ul&gt;
&lt;li&gt;F&amp;lt;&amp;gt; maps objects TSource, TResult ∈ ob(DotNet) to objects F&amp;lt;TSource&amp;gt;, F&amp;lt;TResult&amp;gt; ∈ ob(DotNet)&lt;/li&gt;
&lt;li&gt;F&amp;lt;&amp;gt; also selects morphism selector : TSource → TResult ∈ hom(DotNet) to new morphism : F&amp;lt;TSource&amp;gt; → F&amp;lt;TResult&amp;gt; ∈ hom(DotNet)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F&amp;lt;&amp;gt; is a C# functor, its Select method can be recognized by C# compiler, so the LINQ syntax can be used:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; enumerableFunctor = Enumerable.Range(0, 3);
IEnumerable&amp;lt;int&amp;gt; query = from x in enumerableFunctor select x + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; enumerableFunctor = Enumerable.Range(0, 3);
Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; x + 1;
IEnumerable&amp;lt;int&amp;gt; query = enumerableFunctor.Select(addOne);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IEnumerable&amp;lt;&amp;gt;, functor laws, and unit tests&lt;/h2&gt;
&lt;p&gt;To test IEnumerable&amp;lt;&amp;gt; with the functor laws, some helper functions can be created for shorter code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class MorphismExtensions
{
    public static IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;(
        this IMorphism&amp;lt;TMiddle, TResult, DotNet&amp;gt; m2, IMorphism&amp;lt;TSource, TMiddle, DotNet&amp;gt; m1)
    {
        Contract.Requires(m2.Category == m1.Category, &quot;m2 and m1 are not in the same category.&quot;);

        return m1.Category.o(m2, m1);
    }

    public static IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; DotNetMorphism&amp;lt;TSource, TResult&amp;gt;
        (this Func&amp;lt;TSource, TResult&amp;gt; function) =&amp;gt; new DotNetMorphism&amp;lt;TSource, TResult&amp;gt;(function);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above extension methods are created to use ∘ as infix operator instead of prefix, for &lt;a href=&quot;/posts/understanding-linq-to-objects-2-method-chaining&quot;&gt;fluent coding&lt;/a&gt;, and to convert a C# function to a morphism in DotNet category.&lt;/p&gt;
&lt;p&gt;And an Id helper function can make code shorter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class Functions
{
    // Id is alias of DotNet.Category.Id().Invoke
    public static T Id&amp;lt;T&amp;gt;
        (T value) =&amp;gt; DotNet.Category.Id&amp;lt;T&amp;gt;().Invoke(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, an assertion method for IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Impure.
public static class EnumerableAssert
{
    public static void AreEqual&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; expected, IEnumerable&amp;lt;T&amp;gt; actual)
    {
        Assert.IsTrue(expected.SequenceEqual(actual));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is the tests for IEnumerable&amp;lt;T&amp;gt; as a general functor - selecting/mapping between objects and morphisms:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public partial class FunctorTests
{
    [TestMethod()]
    public void EnumerableGeneralTest()
    {
        IEnumerable&amp;lt;int&amp;gt; functor = new int[] { 0, 1, 2 };
        Func&amp;lt;int, int&amp;gt; addOne = x =&amp;gt; x + 1;

        // Functor law 1: F.Select(Id) == Id(F)
        EnumerableAssert.AreEqual(functor.Select(Functions.Id), Functions.Id(functor));
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; addTwo = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        IMorphism&amp;lt;int, int, DotNet&amp;gt; addOneMorphism = addOne.DotNetMorphism();
        IMorphism&amp;lt;int, string, DotNet&amp;gt; addTwoMorphism = addTwo.DotNetMorphism();
        EnumerableAssert.AreEqual(
            addTwoMorphism.o(addOneMorphism).Select().Invoke(functor), 
            addTwoMorphism.Select().o(addOneMorphism.Select()).Invoke(functor));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following is the tests for IEnumerable&amp;lt;T&amp;gt; as a C# functor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class FunctorTests
{
    [TestMethod()]
    public void EnumerableCSharpTest()
    {
        bool isExecuted1 = false;
        IEnumerable&amp;lt;int&amp;gt; enumerable = new int[] { 0, 1, 2 };
        Func&amp;lt;int, int&amp;gt; f1 = x =&amp;gt; { isExecuted1 = true; return x + 1; };

        IEnumerable&amp;lt;int&amp;gt; query1 = from x in enumerable select f1(x);
        Assert.IsFalse(isExecuted1); // Laziness.

        EnumerableAssert.AreEqual(new int[] { 1, 2, 3 }, query1); // Execution.
        Assert.IsTrue(isExecuted1);

        // Functor law 1: F.Select(Id) == Id(F)
        EnumerableAssert.AreEqual(enumerable.Select(Functions.Id), Functions.Id(enumerable));
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        Func&amp;lt;int, string&amp;gt; f2 = x =&amp;gt; (x + 2).ToString(CultureInfo.InvariantCulture);
        EnumerableAssert.AreEqual(
            enumerable.Select(f2.o(f1)), 
            enumerable.Select(f1).Select(f2));
        // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2)
        EnumerableAssert.AreEqual(
            from x in enumerable select f2.o(f1)(x), 
            from y in (from x in enumerable select f1(x)) select f2(y));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEnumerable&amp;lt;&amp;gt; is like the &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Base.html#line-712&quot;&gt;List functor in Haskell&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (3) Monoid as Category</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-3-monoid-as-category/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-3-monoid-as-category/</guid><description>An individual monoid (T, ⊙, I) can be a category M:</description><pubDate>Tue, 04 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-2-monoid&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-2-monoid&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;One monoid, one category&lt;/h2&gt;
&lt;p&gt;An individual monoid (T, ⊙, I) can be a category M:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ob(M) ≌ { T } - yes, a one-object category&lt;/li&gt;
&lt;li&gt;hom(M) are morphisms from source object T to result object (target object) T, since there is only one object in category M.&lt;/li&gt;
&lt;li&gt;∘, composition of morphisms, is just ⊙&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Representing a monoid itself as category is straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial interface IMonoid&amp;lt;T&amp;gt; : ICategory&amp;lt;IMonoid&amp;lt;T&amp;gt;&amp;gt;
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its morphism is quite different from DotNetMorphism&amp;lt;TSource, TResult&amp;gt; previously implemented:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MonoidMorphism&amp;lt;T&amp;gt; : IMorphism&amp;lt;T, T, IMonoid&amp;lt;T&amp;gt;&amp;gt;
{
    private readonly Func&amp;lt;T, T&amp;gt; function;

    public MonoidMorphism(IMonoid&amp;lt;T&amp;gt; category, Func&amp;lt;T, T&amp;gt; function)
    {
        this.function = function;
        this.Category = category;
    }

    public IMonoid&amp;lt;T&amp;gt; Category { [Pure] get; }

    [Pure]
    public T Invoke
        (T source) =&amp;gt; this.function(source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since there is only 1 object in the category, the source object and result object are always the same object. So MonoidMorphism&amp;lt;T&amp;gt; only take one type parameter. And apparently, its category is IMonoid&amp;lt;T&amp;gt; instead of DotNet.&lt;/p&gt;
&lt;p&gt;The implementation of Monoid&amp;lt;T&amp;gt; for ICategory&amp;lt;IMonoid&amp;lt;T&amp;gt;&amp;gt; is a little tricky:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Monoid&amp;lt;T&amp;gt;
{
    [Pure]
    public IMorphism&amp;lt;TSource, TResult, IMonoid&amp;lt;T&amp;gt;&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;(
        IMorphism&amp;lt;TMiddle, TResult, IMonoid&amp;lt;T&amp;gt;&amp;gt; m2, IMorphism&amp;lt;TSource, TMiddle, IMonoid&amp;lt;T&amp;gt;&amp;gt; m1)
    {
        if (!(typeof(T).IsAssignableFrom(typeof(TSource)) &amp;amp;&amp;amp; typeof(T).IsAssignableFrom(typeof(TMiddle))
            &amp;amp;&amp;amp; typeof(T).IsAssignableFrom(typeof(TResult))))
        {
            throw new InvalidOperationException($&quot;Category {nameof(Monoid&amp;lt;T&amp;gt;)} has only 1 object {nameof(T)}.&quot;);
        }

        return new MonoidMorphism&amp;lt;T&amp;gt;(
            this,
            _ =&amp;gt; this.Binary(
                (T)(object)m1.Invoke((TSource)(object)this.Unit),
                (T)(object)m2.Invoke((TMiddle)(object)this.Unit)))
            as IMorphism&amp;lt;TSource, TResult, IMonoid&amp;lt;T&amp;gt;&amp;gt;;
    }

    [Pure]
    public IMorphism&amp;lt;TObject, TObject, IMonoid&amp;lt;T&amp;gt;&amp;gt; Id&amp;lt;TObject&amp;gt;()
    {
        if (!typeof(T).IsAssignableFrom(typeof(TObject)))
        {
            throw new InvalidOperationException($&quot;Category {nameof(Monoid&amp;lt;T&amp;gt;)} has only 1 object {nameof(T)}.&quot;);
        }

        return new MonoidMorphism&amp;lt;T&amp;gt;(this, value =&amp;gt; value) as IMorphism&amp;lt;TObject, TObject, IMonoid&amp;lt;T&amp;gt;&amp;gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a category, it expects all the type parameters are the same as T, because - once again - T is the only object in it. Then it uses the ⊙ operator (this.Binary) to compose morphisms.&lt;/p&gt;
&lt;h2&gt;Category laws, and unit tests&lt;/h2&gt;
&lt;p&gt;The following unit test shows how it works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MonoidTests
{
    [TestMethod()]
    public void CategoryTest()
    {
        IMonoid&amp;lt;int&amp;gt; addInt32Monoid = 0.Monoid(a =&amp;gt; b =&amp;gt; a + b);

        // Category law 1: ability to compose
        IMorphism&amp;lt;int, int, IMonoid&amp;lt;int&amp;gt;&amp;gt; m1 = addInt32Monoid.MonoidMorphism(unit =&amp;gt; 1);
        IMorphism&amp;lt;int, int, IMonoid&amp;lt;int&amp;gt;&amp;gt; m2 = addInt32Monoid.MonoidMorphism(unit =&amp;gt; 2);
        IMorphism&amp;lt;int, int, IMonoid&amp;lt;int&amp;gt;&amp;gt; m3 = addInt32Monoid.MonoidMorphism(unit =&amp;gt; 3);
        Assert.AreEqual(
            1 + 2 + 3,
            // (m1 ∘ m2) ∘ m3
            addInt32Monoid.o&amp;lt;int, int, int&amp;gt;(addInt32Monoid.o&amp;lt;int, int, int&amp;gt;(m1, m2), m3).Invoke(0));
        Assert.AreEqual(
            1 + 2 + 3,
            // m1 ∘ (m2 ∘ m3)
            addInt32Monoid.o&amp;lt;int, int, int&amp;gt;(m1, addInt32Monoid.o&amp;lt;int, int, int&amp;gt;(m2, m3)).Invoke(0));
        // Category law 2: existence of an identity morphism
        Assert.AreEqual(1, addInt32Monoid.Id&amp;lt;int&amp;gt;().Invoke(1));
        Assert.AreEqual(addInt32Monoid.Unit, addInt32Monoid.Id&amp;lt;int&amp;gt;().Invoke(addInt32Monoid.Unit));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here monoid (T, ⊙, I), as a category now, has 2 kinds of morphisms&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Each element of T can be associated with a morphism: ∀ x ∈ T, there is a mx: I → T
&lt;ul&gt;
&lt;li&gt;For example, in (int, +, 0) or addInt32Monoid implementation, it has a family of η morphisms (functions) - from unit to each element of int, apparently those morphisms (+ arithmetic) can be composited.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;id: the normal IdT morphism.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thus it satisfies the category laws.&lt;/p&gt;
</content:encoded></item><item><title>Category Theory via C# (2) Monoid</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-2-monoid/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-2-monoid/</guid><description>A ), denoted a 3-tuple (M, ⊙, I), is a set M with</description><pubDate>Mon, 03 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-2-monoid&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-2-monoid&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Monoid and monoid laws&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Monoid_(category_theory)&quot;&gt;monoid&lt;/a&gt;, denoted a 3-tuple (M, ⊙, I), is a set M with&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a binary operator ⊙ : M ⊙ M → M
&lt;ul&gt;
&lt;li&gt;This operation M ⊙ M → M is denoted μ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;and a special element unit, denoted I, I ∈ M
&lt;ul&gt;
&lt;li&gt;I → M is denoted η&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;satisfying:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;left unit law λX: I ⊙ X ≌ X&lt;/li&gt;
&lt;li&gt;right unit law ρX: X ≌ X ⊙ I&lt;/li&gt;
&lt;li&gt;associative law αX, Y, Z: (X ⊙ Y) ⊙ Z ≌ X ⊙ (Y ⊙ Z)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the triangle identity commutes: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and the pentagon identity commutes:: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/Untitled-2.fw_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/Untitled-2.fw_thumb.png&quot; alt=&quot;Untitled-2.fw&quot; title=&quot;Untitled-2.fw&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and apparently: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/LINQ-via-C-Series-C-Functional-Programmi_921F/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is quite general and abstract. A intuitive example is the set of all integers, with operator + and unit 0. So this 3-tuple (integer, +, 0) satisfies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;0 + x ≌ x&lt;/li&gt;
&lt;li&gt;x ≌ x + 0&lt;/li&gt;
&lt;li&gt;(x + y) + z ≌ x + (y + z)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;where x, y, z are elements of the set of integers. Therefore (integer, +, 0) is a monoid.&lt;/p&gt;
&lt;p&gt;A monoid can be represented in C# as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial interface IMonoid&amp;lt;T&amp;gt;
{
    T Unit { [Pure] get; }

    Func&amp;lt;T, T, T&amp;gt; Binary { [Pure] get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A default implementation is straight forward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Monoid&amp;lt;T&amp;gt; : IMonoid&amp;lt;T&amp;gt;
{
    public Monoid(T unit, [Pure] Func&amp;lt;T, T, T&amp;gt; binary)
    {
        this.Unit = unit;
        this.Binary = binary;
    }

    public T Unit { [Pure] get; }

    public Func&amp;lt;T, T, T&amp;gt; Binary { [Pure] get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C#/.NET monoids&lt;/h2&gt;
&lt;p&gt;First of all, an extension method is created for convenience:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static class MonoidExtensions
{
    public static IMonoid&amp;lt;T&amp;gt; Monoid&amp;lt;T&amp;gt;(this T unit, Func&amp;lt;T, T, T&amp;gt; binary)
    {
        return new Monoid&amp;lt;T&amp;gt;(unit, binary);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Void and Unit monoids&lt;/h3&gt;
&lt;p&gt;Theoretically &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.void.aspx&quot;&gt;System.Void&lt;/a&gt; can be a monoid. Its source code is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct Void
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which leads to only one way to get the Void value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Void value = new Void();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a monoid can be constructed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMonoid&amp;lt;Void&amp;gt; voidMonoid = new Void().Monoid((a, b) =&amp;gt; new Void());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, C# compiler does not allow System.Void to be used like this. There are 2 workarounds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Copy above Void definition to local&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee370443.aspx&quot;&gt;Microsoft.FSharp.Core.Unit&lt;/a&gt; to replace System.Void&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd483472.aspx&quot;&gt;F#’s unit&lt;/a&gt; is equivalent to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/yah0tteb.aspx&quot;&gt;C#’s void&lt;/a&gt;, and Microsoft.FSharp.Core.Unit is semantically close to System.Void. Unit’s &lt;a href=&quot;https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs&quot;&gt;source code&lt;/a&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Unit() =
    override x.GetHashCode() = 0
    override x.Equals(obj:obj) = 
        match obj with null -&amp;gt; true | :? Unit -&amp;gt; true | _ -&amp;gt; false
    interface System.IComparable with 
        member x.CompareTo(_obj:obj) = 0
        
and unit = Unit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, Unit is a class, and its only possible value is null.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unit unit = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a monoid can be constructed by Unit too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMonoid&amp;lt;Unit&amp;gt; unitMonoid = ((Unit)null).Monoid((a, b) =&amp;gt; null);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;More examples&lt;/h3&gt;
&lt;p&gt;As fore mentioned, (int, +, 0) is a monoid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMonoid&amp;lt;int&amp;gt; addInt32 = 0.Monoid((a, b) =&amp;gt; a + b);
Assert.AreEqual(0, addInt32.Unit);
Assert.AreEqual(1 + 2, addInt32.Binary(1, 2));

// Monoid law 1: Unit Binary m == m
Assert.AreEqual(1, addInt32.Binary(addInt32.Unit, 1));
// Monoid law 2: m Binary Unit  == m
Assert.AreEqual(1, addInt32.Binary(1, addInt32.Unit));
// Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
Assert.AreEqual(addInt32.Binary(addInt32.Binary(1, 2), 3), addInt32.Binary(1, addInt32.Binary(2, 3)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/brianbeckman&quot;&gt;Brian Beckman&lt;/a&gt; had a clock monoid &lt;a href=&quot;http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads&quot;&gt;in a video&lt;/a&gt; - consider numbers on the clock:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.ikea.com/PIAimages/0175112_PE332983_S5.JPG&quot;&gt;&lt;img src=&quot;http://www.ikea.com/PIAimages/0175112_PE332983_S5.JPG&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If a ⊙ b is defined as a =&amp;gt; b =&amp;gt; (a + b) % 12, then 12 becomes the unit. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMonoid&amp;lt;int&amp;gt; clock = 12.Monoid((a, b) =&amp;gt; (a + b) % 12);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are more similar examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(int, *, 1)&lt;/li&gt;
&lt;li&gt;(string, string.Concat, string.Empty)&lt;/li&gt;
&lt;li&gt;(bool, ||, false)&lt;/li&gt;
&lt;li&gt;(bool, &amp;amp;&amp;amp;, true)&lt;/li&gt;
&lt;li&gt;(IEnumerable&amp;lt;T&amp;gt;, Enumerable.Concat, Enumerable.Empty&amp;lt;T&amp;gt;())&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Nullable&amp;lt;T&amp;gt; monoid&lt;/h3&gt;
&lt;p&gt;And monoid (Nullable&amp;lt;T&amp;gt;, ⊙, I) is interesting.&lt;/p&gt;
&lt;p&gt;First of all, the built-in System.Nullable&amp;lt;&amp;gt; only works for value type, since reference type can naturally be null. Here for the category theory discussion, a Nullable&amp;lt;T&amp;gt; for any type can be reinvented:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Nullable&amp;lt;T&amp;gt;
{
    private readonly Lazy&amp;lt;Tuple&amp;lt;bool, T&amp;gt;&amp;gt; factory;

    public Nullable(Func&amp;lt;Tuple&amp;lt;bool, T&amp;gt;&amp;gt; factory = null)
    {
        this.factory = factory == null ? null : new Lazy&amp;lt;Tuple&amp;lt;bool, T&amp;gt;&amp;gt;(factory);
    }

    public bool HasValue
    {
        [Pure]
        get
        {
            return this.factory?.Value != null &amp;amp;&amp;amp; this.factory.Value.Item1 &amp;amp;&amp;amp; this.factory.Value.Item2 != null;
        }
    }

    public T Value
    {
        [Pure]
        get
        {
            // Message is copied from mscorlib.dll string table, where key is InvalidOperation_NoValue.
            Contract.Requires&amp;lt;InvalidOperationException&amp;gt;(this.HasValue, &quot;Nullable object must have a value.&quot;);

            return this.factory.Value.Item2;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Nullable&amp;lt;T&amp;gt;’s constructor takes a factory function which returns a tuple of bool and T value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When factory function is not provided (null), Nullable&amp;lt;T&amp;gt; does not have value.&lt;/li&gt;
&lt;li&gt;When factory function is provided, the function returns a tuple if executed.
&lt;ul&gt;
&lt;li&gt;The tuple’s bool value indicates there is a value available (because when T is a value type, the other item in the tuple cannot be null).&lt;/li&gt;
&lt;li&gt;When the bool is true and the other T value is not null, Nullable&amp;lt;T&amp;gt; has a value.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below is one way to define the binary operator ⊙, taking new Nullable&amp;lt;T&amp;gt;() - a Nullable&amp;lt;T&amp;gt; has no value - as the unit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
public static partial class MonoidExtensions
{
    public static IMonoid&amp;lt;T&amp;gt; Monoid&amp;lt;T&amp;gt;
        (this T unit, Func&amp;lt;T, T, T&amp;gt; binary) =&amp;gt; new Monoid&amp;lt;T&amp;gt;(unit, binary);

    public static IMonoid&amp;lt;Nullable&amp;lt;TSource&amp;gt;&amp;gt; MonoidOfNullable&amp;lt;TSource&amp;gt;
        (this IMonoid&amp;lt;TSource&amp;gt; monoid) =&amp;gt; 
            new Monoid&amp;lt;Nullable&amp;lt;TSource&amp;gt;&amp;gt;(
                new Nullable&amp;lt;TSource&amp;gt;(),
                (a, b) =&amp;gt; new Nullable&amp;lt;TSource&amp;gt;(() =&amp;gt;
                    {
                        if (a.HasValue &amp;amp;&amp;amp; b.HasValue)
                        {
                            return Tuple.Create(true, monoid.Binary(a.Value, b.Value));
                        }

                        if (a.HasValue)
                        {
                            return Tuple.Create(true, a.Value);
                        }

                        if (b.HasValue)
                        {
                            return Tuple.Create(true, b.Value);
                        }

                        return Tuple.Create(false, default(TSource));
                    }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that (Nullable&amp;lt;T&amp;gt;, ⊙, Nullable&amp;lt;T&amp;gt;()) becomes a monoid.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;These unit tests demonstrate how the monoids are constructed and how the monoid laws are satisfied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class MonoidTests
{
    [TestMethod()]
    public void StringTest()
    {
        IMonoid&amp;lt;string&amp;gt; concatString = string.Empty.Monoid((a, b) =&amp;gt; string.Concat(a, b));
        Assert.AreEqual(string.Empty, concatString.Unit);
        Assert.AreEqual(&quot;ab&quot;, concatString.Binary(&quot;a&quot;, &quot;b&quot;));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(&quot;ab&quot;, concatString.Binary(concatString.Unit, &quot;ab&quot;));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(&quot;ab&quot;, concatString.Binary(&quot;ab&quot;, concatString.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(concatString.Binary(concatString.Binary(&quot;a&quot;, &quot;b&quot;), &quot;c&quot;), concatString.Binary(&quot;a&quot;, concatString.Binary(&quot;b&quot;, &quot;c&quot;)));
    }

    [TestMethod()]
    public void Int32Test()
    {
        IMonoid&amp;lt;int&amp;gt; addInt32 = 0.Monoid((a, b) =&amp;gt; a + b);
        Assert.AreEqual(0, addInt32.Unit);
        Assert.AreEqual(1 + 2, addInt32.Binary(1, 2));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(1, addInt32.Binary(addInt32.Unit, 1));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(1, addInt32.Binary(1, addInt32.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(addInt32.Binary(addInt32.Binary(1, 2), 3), addInt32.Binary(1, addInt32.Binary(2, 3)));

        IMonoid&amp;lt;int&amp;gt; multiplyInt32 = 1.Monoid((a, b) =&amp;gt; a * b);
        Assert.AreEqual(1, multiplyInt32.Unit);
        Assert.AreEqual(1 * 2, multiplyInt32.Binary(1, 2));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(2, multiplyInt32.Binary(multiplyInt32.Unit, 2));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(2, multiplyInt32.Binary(2, multiplyInt32.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(multiplyInt32.Binary(multiplyInt32.Binary(1, 2), 3), multiplyInt32.Binary(1, multiplyInt32.Binary(2, 3)));
    }

    [TestMethod()]
    public void ClockTest()
    {
        // Stolen from: http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads
        IMonoid&amp;lt;int&amp;gt; clock = 12.Monoid((a, b) =&amp;gt; (a + b) % 12);
        Assert.AreEqual(12, clock.Unit);
        Assert.AreEqual((7 + 10) % 12, clock.Binary(7, 10));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(111 % 12, clock.Binary(clock.Unit, 111));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(111 % 12, clock.Binary(111, clock.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(clock.Binary(clock.Binary(11, 22), 33), clock.Binary(11, clock.Binary(22, 33)));
    }

    [TestMethod()]
    public void BooleanTest()
    {
        IMonoid&amp;lt;bool&amp;gt; orBoolean = false.Monoid((a, b) =&amp;gt; a || b);
        Assert.IsFalse(orBoolean.Unit);
        Assert.AreEqual(true || false, orBoolean.Binary(true, false));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(true, orBoolean.Binary(orBoolean.Unit, true));
        Assert.AreEqual(false, orBoolean.Binary(orBoolean.Unit, false));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(true, orBoolean.Binary(true, orBoolean.Unit));
        Assert.AreEqual(false, orBoolean.Binary(false, orBoolean.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(orBoolean.Binary(orBoolean.Binary(true, false), true), orBoolean.Binary(true, orBoolean.Binary(false, true)));

        IMonoid&amp;lt;bool&amp;gt; andBoolean = true.Monoid((a, b) =&amp;gt; a &amp;amp;&amp;amp; b);
        Assert.IsTrue(andBoolean.Unit);
        Assert.AreEqual(true &amp;amp;&amp;amp; false, andBoolean.Binary(true, false));

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(true, andBoolean.Binary(andBoolean.Unit, true));
        Assert.AreEqual(false, andBoolean.Binary(andBoolean.Unit, false));
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(true, andBoolean.Binary(true, andBoolean.Unit));
        Assert.AreEqual(false, andBoolean.Binary(false, andBoolean.Unit));
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Assert.AreEqual(andBoolean.Binary(andBoolean.Binary(true, false), true), andBoolean.Binary(true, andBoolean.Binary(false, true)));
    }

    [TestMethod()]
    public void EnumerableTest()
    {
        IMonoid&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; concatEnumerable = Enumerable.Empty&amp;lt;int&amp;gt;().Monoid((a, b) =&amp;gt; a.Concat(b));
        Assert.IsFalse(concatEnumerable.Unit.Any());
        int[] x = new int[] { 0, 1, 2 };
        int[] y = new int[] { 3, 4, 5 };
        EnumerableAssert.AreEqual(concatEnumerable.Binary(x, y), x.Concat(y));

        // Monoid law 1: Unit Binary m == m
        EnumerableAssert.AreEqual(concatEnumerable.Binary(concatEnumerable.Unit, x), x);
        // Monoid law 2: m Binary Unit == m
        EnumerableAssert.AreEqual(concatEnumerable.Binary(x, concatEnumerable.Unit), x);
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        EnumerableAssert.AreEqual(
            concatEnumerable.Binary(concatEnumerable.Binary(x, y), x),
            concatEnumerable.Binary(x, concatEnumerable.Binary(y, x)));
    }

    [TestMethod()]
    public void NullableTest()
    {
        IMonoid&amp;lt;int&amp;gt; addInt32 = 0.Monoid((a, b) =&amp;gt; a + b);
        IMonoid&amp;lt;Nullable&amp;lt;int&amp;gt;&amp;gt; addNullable = addInt32.MonoidOfNullable();
        Assert.IsFalse(addNullable.Unit.HasValue);
        Assert.AreEqual(addInt32.Binary(1, 2), addNullable.Binary(1.Nullable(), 2.Nullable()).Value);
        Assert.AreEqual(1, addNullable.Binary(1.Nullable(), new Nullable&amp;lt;int&amp;gt;()).Value);
        Assert.AreEqual(2, addNullable.Binary(new Nullable&amp;lt;int&amp;gt;(), 2.Nullable()).Value);
        Assert.IsFalse(addNullable.Binary(new Nullable&amp;lt;int&amp;gt;(), new Nullable&amp;lt;int&amp;gt;()).HasValue);

        // Monoid law 1: Unit Binary m == m
        Assert.AreEqual(1, addNullable.Binary(addNullable.Unit, 1.Nullable()).Value);
        // Monoid law 2: m Binary Unit == m
        Assert.AreEqual(1, addNullable.Binary(1.Nullable(), addNullable.Unit).Value);
        // Monoid law 3: (m1 Binary m2) Binary m3 == m1 Binary (m2 Binary m3)
        Nullable&amp;lt;int&amp;gt; left = addNullable.Binary(addNullable.Binary(1.Nullable(), 2.Nullable()), 3.Nullable());
        Nullable&amp;lt;int&amp;gt; right = addNullable.Binary(1.Nullable(), addNullable.Binary(2.Nullable(), 3.Nullable()));
        Assert.AreEqual(left.Value, right.Value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Category Theory via C# (1) Fundamentals - Category, Object And Morphism</title><link>https://dixin.github.io/posts/category-theory-via-c-sharp-1-fundamentals-category-object-and-morphism/</link><guid isPermaLink="true">https://dixin.github.io/posts/category-theory-via-c-sharp-1-fundamentals-category-object-and-morphism/</guid><description>This post and the following posts will introduce category theory and its important concepts via C# and LINQ, including functor, applicative functor, monoid, monad, etc. Categories were first introduce</description><pubDate>Sat, 01 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Category%20Theory&quot;&gt;Category Theory via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/category-theory-via-csharp-1-fundamentals&quot;&gt;https://weblogs.asp.net/dixin/category-theory-via-csharp-1-fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This post and the following posts will introduce category theory and its important concepts via C# and LINQ, including functor, applicative functor, monoid, monad, etc. Categories were first introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Samuel_Eilenberg&quot;&gt;Samuel Eilenberg&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Saunders_Mac_Lane&quot;&gt;Saunders Mac Lane&lt;/a&gt; in 1942–45. It might be tedious, as Wikipedia pointed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A term dating from the 1940s, &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Abstract_nonsense&quot;&gt;general abstract nonsense&lt;/a&gt;&quot;, refers to its high level of abstraction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;so these posts will have minimum theory, and a lot of C#/LINQ code to make some “specific intuitive sense”.&lt;/p&gt;
&lt;h2&gt;Category and category laws&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Category_(mathematics)&quot;&gt;category&lt;/a&gt; C consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A collection of objects, denoted ob(C). This is not the &lt;a href=&quot;http://en.wikipedia.org/wiki/Object_(computer_science)&quot;&gt;objects&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;OOP&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A collection of morphisms between objects, denoted hom(C).
&lt;ul&gt;
&lt;li&gt;A morphism m from object A to object B is denoted m: X → Y:
&lt;ul&gt;
&lt;li&gt;X is called source object.&lt;/li&gt;
&lt;li&gt;Y is called target object. To align to C# terms, Y will be called result object in these posts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Composition operation of morphisms, denoted ∘. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;For objects X,Y, Z, and morphisms m1: X → Y, m2: Y → Z, m1 and m2 can compose as m2 ∘ m1: X → Z.&lt;/li&gt;
&lt;li&gt;The name of m1 of m2 also implies the order. m2 ∘ m1 can be read as m2 after m1.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and satisfies 2 category laws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The ability to compose the morphisms &lt;a href=&quot;http://en.wikipedia.org/wiki/Associativity&quot;&gt;associatively&lt;/a&gt;: For m1: W → X, m2: X → Y and m3: Y → Z, there is (m3 ∘ m2) ∘ m1 ≌ m3 ∘ (m2 ∘ m1). &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The existence of an &lt;a href=&quot;http://en.wikipedia.org/wiki/Identity_function&quot;&gt;identity&lt;/a&gt; morphism for each object: idx : X → X. For m: X → Y, there is idY ∘ m ≌ m ≌ m ∘ idX. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_9.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To make above general definitions more intuitive, category and its morphism can be represented by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ICategory&amp;lt;TCategory&amp;gt; where TCategory : ICategory&amp;lt;TCategory&amp;gt;
{
    // o = (m2, m1) -&amp;gt; composition
    [Pure]
    IMorphism&amp;lt;TSource, TResult, TCategory&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;(
        IMorphism&amp;lt;TMiddle, TResult, TCategory&amp;gt; m2, IMorphism&amp;lt;TSource, TMiddle, TCategory&amp;gt; m1);

    [Pure]
    IMorphism&amp;lt;TObject, TObject, TCategory&amp;gt; Id&amp;lt;TObject&amp;gt;();
}

public interface IMorphism&amp;lt;in TSource, out TResult, out TCategory&amp;gt; where TCategory : ICategory&amp;lt;TCategory&amp;gt;
{
    [Pure]
    TCategory Category { get; }

    [Pure]
    TResult Invoke(TSource source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For convenience, the composition function is uncurried with 2 arity. But this is no problem, because any function cannot &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;curried or uncurried&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All members in above interfaces are tagged as &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.pureattribute.aspx&quot;&gt;[Pure]&lt;/a&gt; to indicate all their are all pure functions (C# property will be compiled to get/set functions too). The &lt;a href=&quot;http://en.wikipedia.org/wiki/Pure_function&quot;&gt;purity&lt;/a&gt; will be explained later.&lt;/p&gt;
&lt;h2&gt;The .NET category and morphism&lt;/h2&gt;
&lt;p&gt;Instead of general abstraction, in C#, the main category to play with is the .NET category:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ob(DotNet) are .NET types, like int (System.Int32), bool (System.Boolean), etc.&lt;/li&gt;
&lt;li&gt;hom(DotNet) are C# pure functions, like f : int → bool, etc.&lt;/li&gt;
&lt;li&gt;Composition operation of morphisms is the composition of C# functions introduced in previous lambda calculus part.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now it starts to make more sense:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DotNet : ICategory&amp;lt;DotNet&amp;gt;
{
    [Pure]
    public IMorphism&amp;lt;TObject, TObject, DotNet&amp;gt; Id&amp;lt;TObject&amp;gt;
        () =&amp;gt; new DotNetMorphism&amp;lt;TObject, TObject&amp;gt;(@object =&amp;gt; @object);

    [Pure]
    public IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt; o&amp;lt;TSource, TMiddle, TResult&amp;gt;
        (IMorphism&amp;lt;TMiddle, TResult, DotNet&amp;gt; m2, IMorphism&amp;lt;TSource, TMiddle, DotNet&amp;gt; m1) =&amp;gt;
            new DotNetMorphism&amp;lt;TSource, TResult&amp;gt;(@object =&amp;gt; m2.Invoke(m1.Invoke(@object)));

    private DotNet()
    {
    }

    public static DotNet Category {[Pure] get; } = new DotNet();
}

public class DotNetMorphism&amp;lt;TSource, TResult&amp;gt; : IMorphism&amp;lt;TSource, TResult, DotNet&amp;gt;
{
    private readonly Func&amp;lt;TSource, TResult&amp;gt; function;

    public DotNetMorphism(Func&amp;lt;TSource, TResult&amp;gt; function)
    {
        this.function = function;
    }

    public DotNet Category
    {
        [Pure]get {return DotNet.Category;}
    }

    [Pure]
    public TResult Invoke
        (TSource source) =&amp;gt; this.function(source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As expected, DotNetMorphism&amp;lt;TSource, TResult&amp;gt; become just a wrapper of Func&amp;lt;TSource, TResult&amp;gt; function.&lt;/p&gt;
&lt;p&gt;And the DotNet category satisfies the category laws:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_11.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Category-Theory-via-C-1-Fundamentals_6A3A/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The associativity of morphisms’ (C# functions’) composition is already &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-3-fundamentals-function-composition&quot;&gt;proven before&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The morphism returned by Id() is a wrapper of generic function (@object =&amp;gt; @object), but it can be compiled to a copy for each closed type (each object ∈ ob(DotNet)), like Id&amp;lt;string&amp;gt;, Id&amp;lt;int&amp;gt;(), id&amp;lt;bool&amp;gt;(), etc. (This is also called &lt;a href=&quot;https://www.safaribooksonline.com/library/view/clr-via-c/9780735668737/ch12.html#code_explosion&quot;&gt;code explosion&lt;/a&gt; in .NET):&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (23) Y Combinator, And Divide</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide/</guid><description>p is the ) of function F :</description><pubDate>Fri, 23 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-7-fixed-point-combinator-and-recursion&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Fix point&lt;/h2&gt;
&lt;p&gt;p is the &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_(mathematics)&quot;&gt;fixed point&lt;/a&gt; of function F &lt;a href=&quot;http://en.wikipedia.org/wiki/If_and_only_if&quot;&gt;if and only if&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p
≡ F p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following picture is stolen from &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_(mathematics)#mediaviewer/File:Fixed_point_example.svg&quot;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Fixed_point_example.svg/220px-Fixed_point_example.svg.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A simple example:&lt;/p&gt;
&lt;p&gt;F := 0 - x&lt;/p&gt;
&lt;p&gt;has a fixed point 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0
≡ F 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above fixed point definition also leads to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p
≡ F p
≡ F (F p)
≡ ...
≡ F (F (F … (F p) …))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Fixed point combinator&lt;/h2&gt;
&lt;p&gt;In lambda calculus and combinatory logic, &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus&quot;&gt;Y combinator&lt;/a&gt; is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_combinator&quot;&gt;fixed point combinator&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y := λf.(λx.f (x x)) (λx.f (x x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is called so because it calculates a function F’s fixed point Y F.&lt;/p&gt;
&lt;p&gt;According to the above definition of fixed point p ≡ F p, there is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(Y F)
≡ F (Y F)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Proof:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y F
≡ (λf.(λx.f (x x)) (λx.f (x x))) F
≡ (λx.F (x x)) (λx.F (x x))
≡ F ((λx.F (x x)) (λx.F (x x)))
≡ F (Y F)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y combinator was discovered by &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://matt.might.net/articles/compiling-up-to-lambda-calculus/&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3c3b4cb86227_12489/y_combinator_1.jpg&quot; alt=&quot;y_combinator&quot; title=&quot;y_combinator&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As a fixed point combinator, Y also has the same property of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y F
≡ F (Y F)
≡ F (F (Y F))
≡ ...
≡ F (F (F … (F (Y F)) …))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Y can be used to implement &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursion_(computer_science)&quot;&gt;recursion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Knights_of_the_Lambda_Calculus&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3c3b4cb86227_12489/390px-Knights_of_the_Lambda_Calculus.svg_3.png&quot; alt=&quot;390px-Knights_of_the_Lambda_Calculus.svg&quot; title=&quot;390px-Knights_of_the_Lambda_Calculus.svg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And this is Y in SKI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y2 := S (K (S I I)) (S (S (K S) K) (K (S I I)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or just in SK:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y3 := S S K (S (K (S S (S (S S K)))) K)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate Func&amp;lt;T, TResult&amp;gt; Recursion&amp;lt;T, TResult&amp;gt;(Recursion&amp;lt;T, TResult&amp;gt; f);

public static class YCombinator
{
    // Y = λf.(λx.f(x x)) (λx.f(x x))
    // Y = f =&amp;gt; (λx.f(x x)) (λx.f(x x))
    // Y = f =&amp;gt; (x =&amp;gt; f(x(x)))(x =&amp;gt; f(x(x)))
    // Y = (x =&amp;gt; arg =&amp;gt; f(x(x))(arg))(x =&amp;gt; arg =&amp;gt; f(x(x))(arg))
    public static Func&amp;lt;T, TResult&amp;gt; Y&amp;lt;T, TResult&amp;gt;
        (Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;, Func&amp;lt;T, TResult&amp;gt;&amp;gt; f) =&amp;gt; 
            new Recursion&amp;lt;T, TResult&amp;gt;(x =&amp;gt; arg =&amp;gt; f(x(x))(arg))(x =&amp;gt; arg =&amp;gt; f(x(x))(arg));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Recursion&lt;/h2&gt;
&lt;p&gt;As explaned in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;the part of Church numeral arithmetic&lt;/a&gt;, recursion cannot be implemented directly in lambda calculus.&lt;/p&gt;
&lt;h3&gt;Example - factorial&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Factorial&quot;&gt;factorial&lt;/a&gt; function can be intuitively implemented by recursion. In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;uint, uint&amp;gt; factorial = null; // Must have. So that factorial can recursively refer itself.
factorial = x =&amp;gt; x == 0U ? 1U : factorial(x - 1U);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But in lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λn.If (IsZero n) (λx.1) (λx.Self (Decrease n))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An anonymous function cannot directly refer itself by its name in the body.&lt;/p&gt;
&lt;p&gt;With Y, the solution is to create a helper to pass “the algorithm itself” as a parameter. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FactorialHelper := λf.λn.If (IsZero n) (λx.1) (λx.f (Decrease n))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Y can be applied with the helper:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y FactorialHelper n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Factorial := Y FactorialHelper
           ≡ Y (λf.λn.If (IsZero n) (λx.1) (λx.f (Decrease n)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C# lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // Factorial = factorial =&amp;gt; numeral =&amp;gt; If(numeral.IsZero())(_ =&amp;gt; One)(_ =&amp;gt; factorial(numeral.Decrease()));
    public static Func&amp;lt;_Numeral, _Numeral&amp;gt; Factorial
        (Func&amp;lt;_Numeral, _Numeral&amp;gt; factorial) =&amp;gt; numeral =&amp;gt;
            ChurchBoolean.If&amp;lt;_Numeral&amp;gt;(numeral.IsZero())
                (_ =&amp;gt; One)
                (_ =&amp;gt; factorial(numeral.Decrease()));

    public static _Numeral Factorial
        (this _Numeral numeral) =&amp;gt; YCombinator.Y&amp;lt;_Numeral, _Numeral&amp;gt;(Factorial)(numeral);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Example - Fibonacci&lt;/h3&gt;
&lt;p&gt;Another recursion example is &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;uint, uint&amp;gt; fibonacci = null; // Must have. So that fibonacci can recursively refer itself.
fibonacci = x =&amp;gt; x &amp;gt; 1U ? fibonacci(x - 1U) + fibonacci(x - 2U) : x;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The recursion cannot be done in anonymous function either:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λn.If (IsGreater n 1) (λx.Add (Self (Subtract n 1)) (Self (Subtract n 2))) (λx.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same solution can be used - create a helper to pass “the algorithm itself” as a parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FibonacciHelper := λf.λn.If (IsGreater n 1) (λx.Add (f (Subtract n 1)) (f (Subtract n 2))) (λx.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Application to Y will be the same way too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Y FibonacciHelper n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fibonacci := Y FibonacciHelper
           ≡ Y (λf.λn.If (IsGreater n 1) (λx.Add (f (Subtract n 1)) (f (Subtract n 2))) (λx.n))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // Fibonacci  = fibonacci  =&amp;gt; numeral =&amp;gt; If(numeral &amp;gt; One)(_ =&amp;gt; fibonacci(numeral - One) + fibonacci(numeral - One - One))(_ =&amp;gt; numeral);
    public static Func&amp;lt;_Numeral, _Numeral&amp;gt; Fibonacci
        (Func&amp;lt;_Numeral, _Numeral&amp;gt; fibonacci) =&amp;gt; numeral =&amp;gt;
            ChurchBoolean.If&amp;lt;_Numeral&amp;gt;(numeral &amp;gt; One)
                (_ =&amp;gt; fibonacci(numeral - One) + fibonacci(numeral - One - One))
                (_ =&amp;gt; numeral);

    public static _Numeral Fibonacci
        (this _Numeral numeral) =&amp;gt; YCombinator.Y&amp;lt;_Numeral, _Numeral&amp;gt;(Fibonacci)(numeral);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DivideBy&lt;/h2&gt;
&lt;p&gt;In the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;Church numeral arithmetic&lt;/a&gt;, this (cheating) recursive _DivideBy was temporarily used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_DivideBy := λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (_DivideBy (Subtract a b) b)) (λx.Zero)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, with Y, a real DivideBy in lambda calculus can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideByHelper := λf.λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (f (Subtract a b) b)) (λx.Zero)

DivideBy := Y DivideByHelper
          ≡ Y (λf.λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (f (Subtract a b) b)) (λx.Zero))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, just create a helper to pass itself as a parameter to implement recursion, as easy as Factorial and Fibonacci.&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // DivideBy = divideBy =&amp;gt; dividend =&amp;gt; divisor =&amp;gt; If(dividend &amp;gt;= divisor)(_ =&amp;gt; One + divideBy(dividend - divisor)(divisor))(_ =&amp;gt; Zero)
    public static Func&amp;lt;_Numeral, Func&amp;lt;_Numeral, _Numeral&amp;gt;&amp;gt; DivideBy
        (Func&amp;lt;_Numeral, Func&amp;lt;_Numeral, _Numeral&amp;gt;&amp;gt; divideBy) =&amp;gt; dividend =&amp;gt; divisor =&amp;gt;
            ChurchBoolean.If&amp;lt;_Numeral&amp;gt;(dividend &amp;gt;= divisor)
                (_ =&amp;gt; One + divideBy(dividend - divisor)(divisor))
                (_ =&amp;gt; Zero);

    public static _Numeral DivideBy
        (this _Numeral dividend, _Numeral divisor) =&amp;gt;
            YCombinator.Y&amp;lt;_Numeral, Func&amp;lt;_Numeral, _Numeral&amp;gt;&amp;gt;(DivideBy)(dividend)(divisor);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice a difference here: Factorial and Fibonacci both takes 1 parameter, but DivideBy takes 2 parameters - dividend, divisor. However, with &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;currying&lt;/a&gt;, Y&amp;lt;T, TResult&amp;gt; can just be closed type Y&amp;lt;X, Func&amp;lt;Y, Z&amp;gt;&amp;gt;, so that this difference is nicely and easily handled.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class _NumeralExtensionsTests
{
    [TestMethod()]
    public void FactorialTest()
    {
        Func&amp;lt;uint, uint&amp;gt; factorial = null; // Must have. So that factorial can recursively refer itself.
        factorial = x =&amp;gt; x == 0U ? 1U : factorial(x - 1U);

        Assert.IsTrue(factorial(0U) == 0U._Church().Factorial());
        Assert.IsTrue(factorial(1U) == 1U._Church().Factorial());
        Assert.IsTrue(factorial(2U) == 2U._Church().Factorial());
        Assert.IsTrue(factorial(3U) == 3U._Church().Factorial());
        Assert.IsTrue(factorial(10U) == 10U._Church().Factorial());
    }

    [TestMethod()]
    public void FibonacciTest()
    {
        Func&amp;lt;uint, uint&amp;gt; fibonacci = null; // Must have. So that fibonacci can recursively refer itself.
        fibonacci = x =&amp;gt; x &amp;gt; 1U ? fibonacci(x - 1U) + fibonacci(x - 2U) : x;

        Assert.IsTrue(fibonacci(0U) == 0U._Church().Fibonacci());
        Assert.IsTrue(fibonacci(1U) == 1U._Church().Fibonacci());
        Assert.IsTrue(fibonacci(2U) == 2U._Church().Fibonacci());
        Assert.IsTrue(fibonacci(3U) == 3U._Church().Fibonacci());
        Assert.IsTrue(fibonacci(10U) == 10U._Church().Fibonacci());
    }

    [TestMethod()]
    public void DivideByTest()
    {
        Assert.IsTrue(1U / 1U == (1U._Church().DivideBy(1U._Church())));
        Assert.IsTrue(1U / 2U == (1U._Church().DivideBy(2U._Church())));
        Assert.IsTrue(2U / 2U == (2U._Church().DivideBy(2U._Church())));
        Assert.IsTrue(2U / 1U == (2U._Church().DivideBy(1U._Church())));
        Assert.IsTrue(10U / 3U == (10U._Church().DivideBy(3U._Church())));
        Assert.IsTrue(3U / 10U == (3U._Church().DivideBy(10U._Church())));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (22) Iota Combinator and Jot Combinators</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-22-iota-combinator/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-22-iota-combinator/</guid><description>is an  with minimum elements but still [Turing-complete](ht</description><pubDate>Thu, 22 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-6-combinatory-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-6-combinatory-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Language with 1 element&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Iota_and_Jot&quot;&gt;Iota&lt;/a&gt; is an &lt;a href=&quot;http://en.wikipedia.org/wiki/Esoteric_programming_language&quot;&gt;esoteric programming language&lt;/a&gt; with minimum elements but still &lt;a href=&quot;http://en.wikipedia.org/wiki/Turing-complete&quot;&gt;Turing-complete&lt;/a&gt;. Iota&apos;s universal combinator is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ι := λf.f S K ≡ λf.f (λx.λy.λz.x z (y z)) (λx.λy.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s &lt;a href=&quot;https://web.archive.org/web/20150121065142/http://semarch.linguistics.fas.nyu.edu/barker/Iota/&quot;&gt;the whole language&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Completeness&lt;/h2&gt;
&lt;p&gt;In Iota, &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-21-ski-combinator-calculus&quot;&gt;SKI&lt;/a&gt; can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S := ι (ι (ι (ι ι)))
K := ι (ι (ι ι))
ι := ι ι
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ι ι x
≡ (λf.f S K) (λf.f S K) x
≡ (λf.f S K) S K x
≡ (S S K) K x
≡ S K (K K) x
≡ K x ((K K) x)
≡ x
≡ ι x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Iota is also Turing-complete as SKI.&lt;/p&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class IotaCombinator
{
    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        ι = f =&amp;gt; f
            (new Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y(z)))) // S
            (new Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; x)); // K

    public static Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;
        S = ι(ι(ι(ι(ι))));

    public static Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;
        K = ι(ι(ι(ι)));

    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        I = ι(ι);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class IotaCombinatorTests
{
    [TestMethod]
    public void SkiTests()
    {
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; x1 = a =&amp;gt; b =&amp;gt; a + b;
        Func&amp;lt;int, int&amp;gt; y1 = a =&amp;gt; a + 1;
        int z1 = 1;
        Assert.AreEqual((int)SkiCombinators.S(x1)(y1)(z1), (int)IotaCombinator.S(x1)(y1)(z1));
        Assert.AreEqual((Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)SkiCombinators.K(x1)(y1), (Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)IotaCombinator.K(x1)(y1));
        Assert.AreEqual((Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)SkiCombinators.I(x1), (Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)IotaCombinator.I(x1));
        Assert.AreEqual((Func&amp;lt;int, int&amp;gt;)SkiCombinators.I(y1), (Func&amp;lt;int, int&amp;gt;)IotaCombinator.I(y1));
        Assert.AreEqual((int)SkiCombinators.I(z1), (int)IotaCombinator.I(z1));

        string x2 = &quot;a&quot;;
        int y2 = 1;
        Assert.AreEqual((string)SkiCombinators.K(x2)(y2), (string)IotaCombinator.K(x2)(y2));
        Assert.AreEqual((string)SkiCombinators.I(x2), (string)IotaCombinator.I(x2));
        Assert.AreEqual((int)SkiCombinators.I(y2), (int)IotaCombinator.I(y2));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (21) SKI Combinator Calculus</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-21-ski-combinator-calculus/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-21-ski-combinator-calculus/</guid><description>The  shows SKI calculus is untyped and strongly typed C# implementation does not work. So here comes the SKI in untyped C#:</description><pubDate>Wed, 21 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-6-combinatory-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-6-combinatory-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-20-combinators&quot;&gt;previous part&lt;/a&gt; shows SKI calculus is untyped and strongly typed C# implementation does not work. So here comes the SKI in untyped C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;&amp;gt;
        S = x =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y(z));

    public static Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt;
        K = x =&amp;gt; _ =&amp;gt; x;

    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        I = x =&amp;gt; x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice closed types (Func&amp;lt;dynamic, …&amp;gt;) are used instead of open type (Func&amp;lt;T, …&amp;gt;) in previous part. So S, K and I do not have to be in the form of C# methods.&lt;/p&gt;
&lt;h2&gt;I Combinator&lt;/h2&gt;
&lt;p&gt;Actually I can be defined with S and K:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S K K x
≡ K x (K x)
≡ x

  S K S x
≡ K x (S x)
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I is merely &lt;a href=&quot;http://en.wikipedia.org/wiki/Syntactic_sugar&quot;&gt;syntactic sugar&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I2 := S K K
I3 := S K S
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        I2 = S(K)(K);
        
    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        I3 = S(K)(S);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;BCKW combinators&lt;/h2&gt;
&lt;p&gt;BCKW and SKI can define each other:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;B := S (K S) K
C := S (S (K (S (K S) K)) S) (K K)
K := K
W := S S (S K)

S := B (B (B W) C) (B B) ≡ B (B W) (B B C)
K := K
I := W K
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ω combinator&lt;/h2&gt;
&lt;p&gt;In SKI, the self application combinator ω is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ω := S I I
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is easy to understand:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S I I x
≡ I x (I x) 
≡ x x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ω := S I I (S I I) 
   ≡ I (S I I) (I (S I I)) 
   ≡ (S I I) (S I I) 
   ≡ S I I (S I I)
   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        ω = S(I)(I);

    public static Func&amp;lt;dynamic, dynamic&amp;gt;
        Ω = _ =&amp;gt; ω(ω); // Ω = ω(ω) throws exception.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Function composition&lt;/h2&gt;
&lt;p&gt;Remember function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f2 ∘ f1) x := f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SKI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S (K S) K f1 f2 x
≡ (K S) f1 (K f1) f2 x
≡ S (K f1) f2 x
≡ (K f1) x (f2 x)
≡ f1 (f2 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Compose := S (K S) K
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        Compose = S(K(S))(K);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Booleans&lt;/h2&gt;
&lt;p&gt;From previous part:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := K
False := S K
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Boolean
        True = new Boolean(K);
        
    public static Boolean
        False = new Boolean(S(K));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Numerals&lt;/h2&gt;
&lt;p&gt;Remember:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f x
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SKI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;K I f x
≡ I x
≡ x

  I f x
≡ f x

  S Compose I f x
≡ Compose f (I f) x
≡ Compose f f x
≡ f (f x)

  S Compose (S Compose I) f x
≡ Compose f (S Compose I f) x
≡ Compose f (Compose f f) x
≡ f (f (f x))

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := K I                     ≡ K I
1 := I                       ≡ I
2 := S Compose I             ≡ S (S (K S) K) I
3 := S Compose (S Compose I) ≡ S (S (K S) K) (S (S (K S) K) I)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        Zero = K(I);

    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        One = I;

    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        Two = S(Compose)(I);

    public static Func&amp;lt;dynamic, dynamic&amp;gt; 
        Three = S(Compose)(S(Compose)(I));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase := S Compose ≡ S (S (K S) K)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    public static Func&amp;lt;dynamic, Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt; 
        Increase = S(Compose);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The encoding can keep going, but this post stops here. Actually, S and K can be composed to combinators that are extensionally equal to any lambda term. The proof can be found here - &lt;a href=&quot;http://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis&quot;&gt;Completeness of the S-K basis&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class SkiCombinatorsTests
{
    [TestMethod]
    public void SkiTests()
    {
        Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; x1 = a =&amp;gt; b =&amp;gt; a + b;
        Func&amp;lt;int, int&amp;gt; y1 = a =&amp;gt; a + 1;
        int z1 = 1;
        Assert.AreEqual(x1(z1)(y1(z1)), (int)SkiCombinators.S(x1)(y1)(z1));
        Assert.AreEqual(x1, (Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)SkiCombinators.K(x1)(y1));
        Assert.AreEqual(x1, (Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;)SkiCombinators.I(x1));
        Assert.AreEqual(y1, (Func&amp;lt;int, int&amp;gt;)SkiCombinators.I(y1));
        Assert.AreEqual(z1, (int)SkiCombinators.I(z1));

        string x2 = &quot;a&quot;;
        int y2 = 1;
        Assert.AreEqual(x2, (string)SkiCombinators.K(x2)(y2));
        Assert.AreEqual(x2, (string)SkiCombinators.I(x2));
        Assert.AreEqual(y2, (int)SkiCombinators.I(y2));
    }

    [TestMethod]
    public void BooleanTests()
    {
        Assert.AreEqual(true, (bool)SkiCombinators.True(true)(false));
        Assert.AreEqual(false, (bool)SkiCombinators.False(new Func&amp;lt;dynamic, dynamic&amp;gt;(_ =&amp;gt; true))(false));
    }

    [TestMethod]
    public void NumeralTests()
    {
        Assert.AreEqual(0U, SkiCombinators._UnchurchNumeral(SkiCombinators.Zero));
        Assert.AreEqual(1U, SkiCombinators._UnchurchNumeral(SkiCombinators.One));
        Assert.AreEqual(2U, SkiCombinators._UnchurchNumeral(SkiCombinators.Two));
        Assert.AreEqual(3U, SkiCombinators._UnchurchNumeral(SkiCombinators.Three));
        Assert.AreEqual(4U, SkiCombinators._UnchurchNumeral(SkiCombinators.Increase(SkiCombinators.Three)));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (20) Combinators</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-20-combinators/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-20-combinators/</guid><description>As mentioned in , combinator is a special kind of lambda expression without free variables</description><pubDate>Tue, 20 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-6-combinatory-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-6-combinatory-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As mentioned in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-2-fundamentals-lambda-expression-variables-reductions&quot;&gt;a fundamental part&lt;/a&gt;, combinator is a special kind of lambda expression without free variables. So &lt;a href=&quot;http://en.wikipedia.org/wiki/Combinatory_logic&quot;&gt;combinatory logic&lt;/a&gt; (introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel&quot;&gt;Moses Schönfinkel&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;) can be viewed as a variant of lambda calculus.&lt;/p&gt;
&lt;h2&gt;I combinator&lt;/h2&gt;
&lt;p&gt;The following simplest lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I := λx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is an example of combinator. In combinatory logic, λx.x is called I (Id), because it just returns the parameter itself.&lt;/p&gt;
&lt;h2&gt;BCKW combinators&lt;/h2&gt;
&lt;p&gt;Also:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;B := λx.λy.λz.x (y z)
C := λx.λy.λz.x z y
K := λx.λy.   x
W := λx.λy.   x y y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;B composes x and y&lt;/li&gt;
&lt;li&gt;C swaps y and z&lt;/li&gt;
&lt;li&gt;K discards y&lt;/li&gt;
&lt;li&gt;W duplicates y&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Only bound variables appear in the body of the lambda expressions. So apparently these are combinators.&lt;/p&gt;
&lt;p&gt;C# version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class BckwCombinators
{
    // B = x =&amp;gt; =&amp;gt; z =&amp;gt; x(y(z))
    public static Func&amp;lt;Func&amp;lt;T1, T2&amp;gt;, Func&amp;lt;T1, TResult&amp;gt;&amp;gt; B&amp;lt;T1, T2, TResult&amp;gt;
        (Func&amp;lt;T2, TResult&amp;gt; x) =&amp;gt; y =&amp;gt; z =&amp;gt; x(y(z));

    // C = f =&amp;gt; x =&amp;gt; y =&amp;gt; f(y)(z)
    public static Func&amp;lt;T2, Func&amp;lt;T1, TResult&amp;gt;&amp;gt; C&amp;lt;T1, T2, TResult&amp;gt;
        (Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; x) =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y);

    // K = x =&amp;gt; _ =&amp;gt; x
    public static Func&amp;lt;T2, T1&amp;gt; K&amp;lt;T1, T2&amp;gt;
        (T1 x) =&amp;gt; _ =&amp;gt; x;

    // W = x =&amp;gt; y =&amp;gt; x(y)(y)
    public static Func&amp;lt;T, TResult&amp;gt; W&amp;lt;T, TResult&amp;gt;
        (Func&amp;lt;T, Func&amp;lt;T, TResult&amp;gt;&amp;gt; x) =&amp;gt; y =&amp;gt; x(y)(y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/B,C,K,W_system&quot;&gt;BCKW system&lt;/a&gt; is a variant of combinatory logic that takes the BCKW combinators as primitives.&lt;/p&gt;
&lt;h2&gt;ω combinator&lt;/h2&gt;
&lt;p&gt;ω is the self application combinator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ω := λx.x x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And Ω is to apply ω to itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ω := ω ω
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The interesting property of Ω is - it’s irreducible:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ω ω
≡ (λx.x x) (λx.x x)
≡ (λx.x x) (λx.x x)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate T ω&amp;lt;T&amp;gt;(ω&amp;lt;T&amp;gt; ω);

public static class OmegaCombinators
{
    // ω = x =&amp;gt; x(x)
    public static T ω&amp;lt;T&amp;gt;
        (ω&amp;lt;T&amp;gt; x) =&amp;gt; x(x);

    // Ω = ω(ω)
    public static T Ω&amp;lt;T&amp;gt;
        () =&amp;gt; ω&amp;lt;T&amp;gt;(ω); // Ω&amp;lt;T&amp;gt; = ω&amp;lt;T&amp;gt;(ω) throws exception.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, applying Ω will throw an exception:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;System.StackOverflowException was unhandled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;SKI combinators&lt;/h2&gt;
&lt;p&gt;The more interested combinators are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S := λx.λy.λz.x z (y z)
K := λx.λy.   x
I := λx.      x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;S (Slider) slides z to between x and y (In most materials S is called Substitution, but in &lt;a href=&quot;http://en.wikipedia.org/wiki/Dana_Scott&quot;&gt;Dana Scott&lt;/a&gt;’s &lt;a href=&quot;https://www.youtube.com/watch?v=7cPtCpyBPNI&quot;&gt;presentation&lt;/a&gt; he called it Slider)&lt;/li&gt;
&lt;li&gt;K (Killer) discards y (The same K in BCKW)&lt;/li&gt;
&lt;li&gt;I (Id) returns x&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Naturally, this is the C#, strongly typed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class SkiCombinators
{
    // S = x =&amp;gt; y =&amp;gt; z = x(z)(y(z))
    public static Func&amp;lt;Func&amp;lt;T1, T2&amp;gt;, Func&amp;lt;T1, TResult&amp;gt;&amp;gt; S&amp;lt;T1, T2, TResult&amp;gt;
        (Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; x) =&amp;gt; y =&amp;gt; z =&amp;gt; x(z)(y(z));

    // K = x =&amp;gt; _ =&amp;gt; x
    public static Func&amp;lt;T2, T1&amp;gt; K&amp;lt;T1, T2&amp;gt;
        (T1 x) =&amp;gt; _ =&amp;gt; x;

    // I = x =&amp;gt; x
    public static T I&amp;lt;T&amp;gt;
        (T x) =&amp;gt; x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like above BCKW system, the &lt;a href=&quot;http://en.wikipedia.org/wiki/SKI_combinator_calculus&quot;&gt;SKI combinator calculus&lt;/a&gt; takes the SKI combinators as primitives. It can be viewed as a reduced version of untyped &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt;, and an extremely simple &lt;a href=&quot;http://en.wikipedia.org/wiki/Turing_complete&quot;&gt;Turing complete&lt;/a&gt; language.&lt;/p&gt;
&lt;h3&gt;Boolean in SKI, and type issue&lt;/h3&gt;
&lt;p&gt;The same as lambda calculus, &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Boolean&lt;/a&gt; would be the simplest thing to try first. Remember in lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λt.λf.t
False := λt.λf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here with SKI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;K t f
≡ t

  S K t f
≡ K f (t f) 
≡ f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in SKI calculus, True and False can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := K
False := S K
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If above C# SKI is used to implement True and False:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// True = K
public static Func&amp;lt;object, object&amp;gt; True
    (object @true) =&amp;gt; K&amp;lt;object, object&amp;gt;(@true);

// Cannot be compiled.
// False = S(K)
public static Func&amp;lt;object, object&amp;gt; False
    (object /* Func&amp;lt;object, object&amp;gt; */ @true) =&amp;gt; @false =&amp;gt; 
        S&amp;lt;object, object, object&amp;gt;(K&amp;lt;object, object&amp;gt;)(/* Func&amp;lt;object, object&amp;gt; */ @true)(@false);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;False does not compile. Because in the strongly typed implementation, @true is expected to be a Func&amp;lt;object, object&amp;gt;, so that it can be applied to S as S’s second argument.&lt;/p&gt;
&lt;p&gt;Again, as fore mentioned, SKI calculus is untyped. To “make” the above code compile, something is needed to have C# compiler forget @true’s type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// False = S(K)
public static Func&amp;lt;object, object&amp;gt; False
    (dynamic @true) =&amp;gt; @false =&amp;gt; S&amp;lt;object, object, object&amp;gt;(K&amp;lt;object, object&amp;gt;)(@true)(@false);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd264741.aspx&quot;&gt;dynamic&lt;/a&gt; is the (untyped) way to &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-21-ski-combinator-calculus&quot;&gt;go&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (19) Church Encoding, And More</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-19-church-encoding-and-more/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-19-church-encoding-and-more/</guid><description>So far a ton has been encoded. Here is a summary.</description><pubDate>Mon, 19 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;p&gt;So far a ton has been encoded. Here is a summary.&lt;/p&gt;
&lt;h2&gt;Summary of church encoding&lt;/h2&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Boolean&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;True := λt.λf.t
False := λt.λf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;Boolean logic&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;And :=  λa.λb.a b False
Or :=  λa.λb.a True b
Not := λb.b False True
Xor := λa.λb.a (b False True) (b True False)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies&quot;&gt;If logic&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;If := λc.λt.λf.c t f (λx.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals&quot;&gt;Numeral&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;0 := λfx.x                  ≡ λf.λx.x                   ≡ λf.λx.f0 x
1 := λfx.f x                ≡ λf.λx.f x                 ≡ λf.λx.f1 x
2 := λfx.f (f x)            ≡ λf.λx.(f ∘ f) x           ≡ λf.λx.f2 x
3 := λfx.f (f (f x))        ≡ λf.λx.(f ∘ f ∘ f) x       ≡ λf.λx.f3 x
...
n := λfx.f (f ... (f x)...) ≡ λf.λx.(f ∘ f ∘ ... ∘ f) x ≡ λf.λx.fn x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;Arithmetic&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Increase := λn.λf.λx.f (n f x)
Increase2 := λn.λf.f ∘ (n f)

Add := λa.λb.λf.λx.a f (b f x)
Add2 := λa.λb.λf.fa ∘ fb ≡ λa.λb.λf.(a f) ∘ (b f)
Add3 := λa.λb.a Increase b

Decrease := λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u)
Decrease2 := λn.Item1 (n (Shift Increase) (CreateTuple 0 0))

Subtract := λa.λb.b Decrease a

Multiply := λa.λb.a (λx.Add b x) 0

_DivideBy := λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (_DivideBy (Subtract a b) b)) (λx.Zero)
DivideByIgnoreZero = λa.λb.If (IsZero b) (λx.0) (λx._DivideBy a b)

Pow := λm.λ e.e (λx.Multiply m x) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A better &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide&quot;&gt;DivideBy will be re-implemented after introducing Y combinator&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideBy := Y (λf.λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (f (Subtract a b) b)) (λx.Zero))
          ≡ (λf.(λx.f (x x)) (λx.f (x x))) (λf.λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (f (Subtract a b) b)) (λx.Zero))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So DivideByIgnoreZero can by redefined using DivideBy instead of _DivideBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideByIgnoreZero = λa.λb.If (IsZero b) (λx.0) (λx.DivideBy a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;Predicate&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;IsZero := λn.n (λx.False) True
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-12-church-numeral-comparison-operators&quot;&gt;Comparison&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;IsLessOrEqual := λa.λb.IsZero (Subtract a b)
IsGreaterOrEqual := λa.λb.IsZero (Subtract b a)

IsEqual := λa.λb.And (IsLessOrEqual a b) (IsGreaterOrEqual a b)

IsLess := λa.λb.Not (IsGreaterOrEqual a b)
IsGreater := λa.λb.Not (IsLessOrEqual a b)
IsNotEqual := λa.λb.Not (IsEqual a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Pair (2-tuple)&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CreateTuple := λx.λy.λf.f x y
Tuple := λf.f x y

Item1 := λt.t True
Item2 := λt.t False

Shift := λf.λt.CreateTuple (Item2 t) (f (Item1 t))
Swap := λt.CreateTuple (Item2 t) (Item1 t)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;List&lt;/h3&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-15-encoding-church-list-with-church-pair-and-null&quot;&gt;1 pair for each node, and null&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode := CreateTuple ≡ λv.λn.λf.f v n

Value := Item1 ≡ λl.l (λv.λn.v)
Next := Item2 ≡ λl.l (λv.λn.n)

Null := False
IsNull := λl.l (λv.λn.λx.False) True

Index := λl.λi.i Next l
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-16-encoding-church-list-with-2-church-pairs-as-a-node&quot;&gt;2 pairs for each node, and null&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode2 := λv.λn.CreateTuple False (CreateTuple v n)

Value2 := λl.Item1 (Item2 l)
Next2 := λl.If (IsNull2 l) (λx.l) (λx.(Item2 (Item2 l)))

Null2 := λf.True
IsNull2 := λl.(Item1 l)

Index2 := λl.λi.i Next2 l
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-17-encoding-church-list-with-fold-aggregate-function&quot;&gt;Fold (aggregate) function for each node, and null&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode3 := λv.λn.λf.λx.f v (n f x)

Value3 := λl.λx.l (λv.λy.v) x
Next3 := λl.Item2  (l (λv.λt.ShiftTuple (CreateListNode3 v)) (CreateTuple Null3 Null3))

Null3 := λf.λx.x
IsNull3 := λl.l (λv.λx.False) True

Index3 := λl.λi.i Next3 l
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number&quot;&gt;Signed number&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Signed := Tuple
ToSigned := λn.CreateTuple n 0
Negate := Swap

Positive := Item1
Negative := Item2

FormatWithZero := λs.If (IsEqual sp  sn) (λx.ToSigned 0) (λx.If (IsGreater sp sn) (λy.ToSigned (Subtract sp sn)) (λy.Negate (ToSigned (Subtract sn sp))))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Arithmetic&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;AddSigned := λa.λb.FormatWithZero (CreateTuple (Add ap bp) (Add an bn))

SubtractSigned := λa.λb.FormatWithZero (CreateTuple (Add ap bn) (Add an bp))

MultiplySigned := λa.λb.FormatWithZero (CreateTuple (Add (Multiply ap bp) (Multiply an bn)) (Add (Multiply ap bn) (Multiply an bp)))

DivideBySigned := λa.λb.FormatWithZero (CreateTuple (Add (DivideByIgnoreZero ap bp) + (DivideByIgnoreZero an bn)) (Add (DivideByIgnoreZero ap bn) (DivideByIgnoreZero an bp))))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Encode, encode, and encode&lt;/h2&gt;
&lt;h3&gt;From signed number to complex integer and rational number&lt;/h3&gt;
&lt;p&gt;With signed number, &lt;a href=&quot;http://en.wikipedia.org/wiki/Gaussian_integer&quot;&gt;complex integer&lt;/a&gt; can be &lt;a href=&quot;http://cs.stackexchange.com/questions/2272/representing-negative-and-complex-numbers-using-lambda-calculus&quot;&gt;encoded&lt;/a&gt; by a Church pair of signed numbers: (sreal, simaginary), which represents complex integer z = sreal + simaginary * i.&lt;/p&gt;
&lt;p&gt;With signed number, &lt;a href=&quot;http://en.wikipedia.org/wiki/Rational_number&quot;&gt;rational number&lt;/a&gt; can also be encoded by a Church pair of a signed number and a Church numeral: (snumerator, ndenominator), which represents rational number q = snumerator / (1 + ndenominator).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Dyadic_rational&quot;&gt;Dyadic rational number&lt;/a&gt; can be encoded by (snumerator, nexponent) as well, which represents d = snumerator / (2 ^ nexponent).&lt;/p&gt;
&lt;h3&gt;From rational number to real number and complex number&lt;/h3&gt;
&lt;p&gt;Then with rational number, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Real_number&quot;&gt;real number&lt;/a&gt; r can be &lt;a href=&quot;https://users.dimi.uniud.it/~pietro.digianantonio/papers/copy_pdf/thesis.pdf&quot;&gt;encoded&lt;/a&gt; in many different ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;r can be represented by a sequence of Church pair of 2 rational numbers p0 = (q0, q0’), p1 = (q1, q1’), p2 = (q2, q2’), …, such that:
&lt;ul&gt;
&lt;li&gt;pn represents a rational interval, since qn and qn’ are both rational numbers.&lt;/li&gt;
&lt;li&gt;pn + 1 ⊆ pn&lt;/li&gt;
&lt;li&gt;limn → ∞ qn’ − qn = 0&lt;/li&gt;
&lt;li&gt;r = ∩n ∈ N pn&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;r can be represented by a &lt;a href=&quot;http://en.wikipedia.org/wiki/Cauchy_sequence&quot;&gt;Cauchy sequence&lt;/a&gt; of rational numbers q0, q1, q2, …, and a function f of type Func&amp;lt;_Numeral, _Numeral&amp;gt;, defining the convergence rate of the Cauchy sequence such that:
&lt;ul&gt;
&lt;li&gt;∀i.j.k. | qf(i) + j - qf(i) + k | ≤ 2-i&lt;/li&gt;
&lt;li&gt;r = limn → ∞ qn&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;r can be represented by a Cauchy sequence of rational numbers q0, q1, q2, … with a fixed convergence rate, such that:
&lt;ul&gt;
&lt;li&gt;∀i.j. | qi - qi + j | ≤ 1 / i&lt;/li&gt;
&lt;li&gt;r = limn → ∞ qn&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.. An example in &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt; can be found &lt;a href=&quot;https://github.com/andrejbauer/marshall/blob/master/etc/haskell/Reals.hs&quot;&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With real number, &lt;a href=&quot;http://en.wikipedia.org/wiki/Complex_number&quot;&gt;complex number&lt;/a&gt; can be naturally encoded by a Church pair of 2 real numbers (rreal, rimaginary), which represents complex number z = rreal + rimaginary * i.&lt;/p&gt;
&lt;h3&gt;And much more&lt;/h3&gt;
&lt;p&gt;Church pair can encode more complex data structures, like tree.&lt;/p&gt;
&lt;p&gt;Church List can encode string.&lt;/p&gt;
&lt;p&gt;Church Tuple and Church List can encode more complex algebra types.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;Don’t worry. The encoding stops here. All the above data types and functions demonstrate that any data type or calculation may be encoded in lambda calculus. This is the &lt;a href=&quot;http://en.wikipedia.org/wiki/Church-Turing_thesis&quot;&gt;Church-Turing thesis&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (18) Encoding Signed Number</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number/</guid><description>In lambda calculus, a signed number (integer) can be represented by a  of [Chur</description><pubDate>Sun, 18 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In lambda calculus, a signed number (integer) can be represented by a &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pair (2-tuple)&lt;/a&gt; of &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals&quot;&gt;Church numerals&lt;/a&gt; (natural numbers):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the first Church number represents the positive part&lt;/li&gt;
&lt;li&gt;the second Church number represents the negative part&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Signed := Tuple
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a signed number (npositive, negative) ≡ Subtract npositive nnegative.&lt;/p&gt;
&lt;h2&gt;Create Signed number from Church numeral&lt;/h2&gt;
&lt;p&gt;Church numeral represents natural number and is always greater than or equal to 0. So Converting Church numeral to signed number is easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ToSigned := λn.CreateTuple n 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just need to append a negative part 0.&lt;/p&gt;
&lt;p&gt;To create a negative signed number, just swap the Church numeral and 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Negate := Swap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it is straightforward to get the positive part or negative part from a signed number:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Positive := Item1
Negative := Item2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// SignedNumeral is the alias of Tuple&amp;lt;_Numeral, _Numeral&amp;gt;
public delegate object SignedNumeral(Boolean&amp;lt;_Numeral, _Numeral&amp;gt; f);

public static partial class ChurchSignedNumeral
{
    public static _Numeral Zero { get; } = _Numeral.Zero;

    // Sign = numeral =&amp;gt; ChurchTuple.Create(numeral, Zero)
    public static SignedNumeral Sign
        (this _Numeral numeral) =&amp;gt; new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;(numeral)(Zero));

    // Negate = signed =&amp;gt; signed.Swap()
    public static SignedNumeral Negate
        (this SignedNumeral signed) =&amp;gt; new SignedNumeral(new Tuple&amp;lt;_Numeral, _Numeral&amp;gt;(signed).Swap());

    // Positive = signed =&amp;gt; signed.Item1()
    public static _Numeral Positive
        (this SignedNumeral signed) =&amp;gt; new Tuple&amp;lt;_Numeral, _Numeral&amp;gt;(signed).Item1();

    // Negative = signed =&amp;gt; signed.Item2()
    public static _Numeral Negative
        (this SignedNumeral signed) =&amp;gt; new Tuple&amp;lt;_Numeral, _Numeral&amp;gt;(signed).Item2();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Format with 0&lt;/h2&gt;
&lt;p&gt;In this way, one signed number can have many representations. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1  ≡ (1, 0) ≡ (2, 1) ≡ (3, 2) ≡ (4, 3) ≡ …
-1  ≡ (0, 1) ≡ (1, 2) ≡ (2, 3) ≡ (3, 4) ≡ …
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So for convenience a format function can be create to consistently represent a signed number in (positive, 0) or (0, negative):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FormatWithZero = λs.If (IsEqual sp  sn) (λx.ToSigned 0) (λx.If (IsGreater sp sn) (λy.ToSigned (Subtract sp sn)) (λy.Negate (ToSigned (Subtract sn sp))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sp ≡ Positive s
sn ≡ Negative s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// FormatWithZero = signed =&amp;gt; If(positive == negative)(_ =&amp;gt; Zero.Sign())(_ =&amp;gt; If(positive &amp;gt; negative)(__ =&amp;gt; (positive - negative).Sign())(__ =&amp;gt; (negative - positive).Sign().Negate()))
public static SignedNumeral FormatWithZero(this SignedNumeral signed)
{
    // Just to make the code shorter.
    _Numeral positive = signed.Positive();
    _Numeral negative = signed.Negative();

    return ChurchBoolean.If&amp;lt;SignedNumeral&amp;gt;(positive == negative)
        (_ =&amp;gt; Zero.Sign())
        (_ =&amp;gt; ChurchBoolean.If&amp;lt;SignedNumeral&amp;gt;(positive &amp;gt; negative)
            (__ =&amp;gt; (positive - negative).Sign())
            (__ =&amp;gt; (negative - positive).Sign().Negate()));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Arithmetic&lt;/h2&gt;
&lt;p&gt;Naturally, for signed numbers a, b:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a + b
≡ (ap, an) + (bp, bn)
≡ (ap - an) + (bp - bn)
≡ (ap + bp, an + bn)

  a - b
≡ (ap, an) - (bp, bn)
≡ (ap - an) - (bp - bn)
≡ (ap + bn, an + bp)

  a * b
≡ (ap, an) * (bp, bn)
≡ (ap - an) * (bp - bn)
≡ (ap * bp + an * bn, ap * bn + an * bp)

  a / b
≡ (ap, an) / (bp, bn)
≡ (ap - an) / (bp - bn)
≡ (ap / bp + an / bn, ap / bn + an / bp)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in lambda calculus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AddSigned := λa.λb.FormatWithZero (CreateTuple (Add ap bp) (Add an bn))

SubtractSigned := λa.λb.FormatWithZero (CreateTuple (Add ap bn) (Add an bp))

MultiplySigned := λa.λb.FormatWithZero (CreateTuple (Add (Multiply ap bp) (Multiply an bn)) (Add (Multiply ap bn) (Multiply an bp)))

DivideBySigned := λa.λb.FormatWithZero (CreateTuple (Add (DivideByIgnoreZero ap bp) + (DivideByIgnoreZero an bn)) (Add (DivideByIgnoreZero ap bn) (DivideByIgnoreZero an bp))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In DivideBySigned,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DivideByIgnoreZero = λa.λb.If (IsZero b) (λx.0) (λx._DivideBy a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a Church numeral a is divided by Church numeral 0, just returns 0.&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Add = a =&amp;gt; b =&amp;gt; ChurchTuple.Create(a.Positive() + b.Positive())(a.Negative() + b.Negative()).FormatWithZero()
public static SignedNumeral Add
    (this SignedNumeral a, SignedNumeral b) =&amp;gt; 
        new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;
            (a.Positive() + b.Positive())
            (a.Negative() + b.Negative()))
        .FormatWithZero();

// Subtract = a =&amp;gt; b =&amp;gt; ChurchTuple.Create(a.Positive() + b.Negative())(a.Negative() + b.Positive()).FormatWithZero()
public static SignedNumeral Subtract
    (this SignedNumeral a, SignedNumeral b) =&amp;gt; 
        new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;
            (a.Positive() + b.Negative())
            (a.Negative() + b.Positive()))
        .FormatWithZero();

// Multiply = a =&amp;gt; b =&amp;gt; ChurchTuple.Create(a.Positive() * b.Positive() + a.Negative() + b.Negative())(a.Positive() * b.Negative() + a.Negative() * b.Positive()).FormatWithZero()
public static SignedNumeral Multiply
    (this SignedNumeral a, SignedNumeral b) =&amp;gt; 
        new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;
            (a.Positive() * b.Positive() + a.Negative() * b.Negative())
            (a.Positive() * b.Negative() + a.Negative() * b.Positive()))
        .FormatWithZero();

// DivideBy = dividend =&amp;gt; divisor =&amp;gt; ChurchTuple.Create((dividend.Positive() | divisor.Positive()) + (dividend.Negative() | divisor.Negative()))((dividend.Positive() | divisor.Negative()) + (dividend.Negative() | divisor.Positive()))).FormatWithZero();
public static SignedNumeral DivideBy
    (this SignedNumeral dividend, SignedNumeral divisor) =&amp;gt; 
        new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;
            ((dividend.Positive() | divisor.Positive()) + (dividend.Negative() | divisor.Negative()))
            ((dividend.Positive() | divisor.Negative()) + (dividend.Negative() | divisor.Positive())))
        .FormatWithZero();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In DivideBy, operator | is DivideByIgnoreZero, since it looks like /:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // DivideByIgnoreZero = dividend =&amp;gt; divisor =&amp;gt; If(divisor.IsZero())(_ =&amp;gt; Zero)(_ =&amp;gt; dividend._DivideBy(divisor))
    public static _Numeral DivideByIgnoreZero
        (this _Numeral dividend, _Numeral divisor) =&amp;gt; 
            ChurchBoolean.If&amp;lt;_Numeral&amp;gt;(divisor.IsZero())
                (_ =&amp;gt; Zero)
                (_ =&amp;gt; dividend._DivideBy(divisor));
}

public partial class _Numeral
{
    public static _Numeral operator |
        (_Numeral dividend, _Numeral divisor) =&amp;gt; dividend.DivideByIgnoreZero(divisor);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchSignedNumeralTests
{
    [TestMethod()]
    public void SignNegatePositiveNegativeTest()
    {
        SignedNumeral signed = 0U._Church().Sign();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());

        signed = 1U._Church().Sign();
        Assert.IsTrue(1U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(1U == signed.Negative());

        signed = 2U._Church().Sign();
        Assert.IsTrue(2U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(2U == signed.Negative());

        signed = 123U._Church().Sign();
        Assert.IsTrue(123U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());
        signed = signed.Negate();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(123U == signed.Negative());

        signed = new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;(12U._Church())(23U._Church()));
        Assert.IsTrue(12U == signed.Positive());
        Assert.IsTrue(23U == signed.Negative());
        signed = signed.Negate();
        Assert.IsTrue(23U == signed.Positive());
        Assert.IsTrue(12U == signed.Negative());
    }

    [TestMethod()]
    public void FormatWithZeroTest()
    {
        SignedNumeral signed = new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;(12U._Church())(23U._Church()));
        signed = signed.FormatWithZero();
        Assert.IsTrue(0U == signed.Positive());
        Assert.IsTrue(11U == signed.Negative());

        signed = new SignedNumeral(ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;(23U._Church())(12U._Church()));
        signed = signed.FormatWithZero();
        Assert.IsTrue(11U == signed.Positive());
        Assert.IsTrue(0U == signed.Negative());
    }

    [TestMethod()]
    public void AddTest()
    {
        SignedNumeral a = 0U._Church().Sign();
        SignedNumeral b = 0U._Church().Sign();
        SignedNumeral result = a.Add(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 1U._Church().Sign();
        b = 1U._Church().Sign().Negate();
        result = a.Add(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 3U._Church().Sign();
        b = 5U._Church().Sign().Negate();
        result = a.Add(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(2U == result.Negative());
    }

    [TestMethod()]
    public void SubtractTest()
    {
        SignedNumeral a = 0U._Church().Sign();
        SignedNumeral b = 0U._Church().Sign();
        SignedNumeral result = a.Subtract(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 1U._Church().Sign();
        b = 1U._Church().Sign().Negate();
        result = a.Subtract(b);
        Assert.IsTrue(2U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 3U._Church().Sign();
        b = 5U._Church().Sign().Negate();
        result = a.Subtract(b);
        Assert.IsTrue(8U == result.Positive());
        Assert.IsTrue(0U == result.Negative());
    }

    [TestMethod()]
    public void MultiplyTest()
    {
        SignedNumeral a = 0U._Church().Sign();
        SignedNumeral b = 0U._Church().Sign();
        SignedNumeral result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 1U._Church().Sign();
        b = 1U._Church().Sign().Negate();
        result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(1U == result.Negative());

        a = 3U._Church().Sign();
        b = 5U._Church().Sign().Negate();
        result = a.Multiply(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(15U == result.Negative());
    }

    [TestMethod()]
    public void DivideByTest()
    {
        SignedNumeral a = 0U._Church().Sign();
        SignedNumeral b = 0U._Church().Sign();
        SignedNumeral result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(0U == result.Negative());

        a = 1U._Church().Sign();
        b = 1U._Church().Sign().Negate();
        result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(1U == result.Negative());

        a = 11U._Church().Sign();
        b = 5U._Church().Sign().Negate();
        result = a.DivideBy(b);
        Assert.IsTrue(0U == result.Positive());
        Assert.IsTrue(2U == result.Negative());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;An alternative way to encode signed number&lt;/h2&gt;
&lt;p&gt;More intuitively, signed number can also be encoded by a Church pair of a Church Boolean and a Church numeral: (sign, absolute-value). For example, +1 will be (True, 1), -2 will be (False, 2), etc.&lt;/p&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Signed2 := Tuple
Sign := Item1
Absolute := Item2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its arithmetic, for example, multiply, also becomes &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;intuitively&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MultiplySigned2 = λa.λb.CreateTuple (Xor (Sign a) (Sign b)) (Multiply (Absolute a) (Absolute b))
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (17) Encoding Church List with Fold (Aggregate) Function</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-17-encoding-church-list-with-fold-aggregate-function/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-17-encoding-church-list-with-fold-aggregate-function/</guid><description>A third way to encode Church list, is to use ) (also called [aggregate in C#/.NET](https://msdn.microsoft.com/en-us/library/v</description><pubDate>Sat, 17 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-5-list&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-5-list&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;A third way to encode Church list, is to use &lt;a href=&quot;http://en.wikipedia.org/wiki/Fold_(higher-order_function)&quot;&gt;fold function&lt;/a&gt; (also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/vstudio/bb549218.aspx&quot;&gt;aggregate in C#/.NET&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode3 = λv.λn.λf.λx.f v (n f x)
Null3 = λf.λx.x
IsNull3 = λl.l (λv.λx.False) True
Value3 = λl.λx.l (λv.λy.v) x
Next3 = λl.Item2 (l (λv.λt.Shift (CreateListNode3 v)) (CreateTuple Null3 Null3))
Index3 = λl.λi.i Next3 l
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ListNode and wrapper&lt;/h2&gt;
&lt;p&gt;According to the definition, this is the ListNode in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from TResult ListNode&amp;lt;out T, TResult&amp;gt;(Func&amp;lt;T, TResult, TResult&amp;gt; f, TResult x)
public delegate Func&amp;lt;TAccumulate, TAccumulate&amp;gt; ListNode&amp;lt;out T, TAccumulate&amp;gt;(Func&amp;lt;TAccumulate, Func&amp;lt;T, TAccumulate&amp;gt;&amp;gt; f);
// ListNode is the alias of: Func&amp;lt;Func&amp;lt;T, Func&amp;lt;TResult, TResult&amp;gt;&amp;gt;, Func&amp;lt;TResult, TResult&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;f is the fold/aggregate function. In .NET aggregate function is a Func&amp;lt;TAccumulate, T, TAccumulate&amp;gt;, here in &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; it is curried to Func&amp;lt;TAccumulate, Func&amp;lt;T, TAccumulate&amp;gt;.&lt;/p&gt;
&lt;p&gt;Just like the Church numeral wrapper _Numeral, a wrapper is needed to hide TAccumulate “inside”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _ListNode&amp;lt;T&amp;gt;
{
    private readonly T value;

    protected virtual _ListNode&amp;lt;T&amp;gt; Next { get; set; }

    public _ListNode(T value, _ListNode&amp;lt;T&amp;gt; next)
    {
        this.value = value;
        this.Next = next;
    }

    public virtual ListNode&amp;lt;T, TAccumulate&amp;gt; Node&amp;lt;TAccumulate&amp;gt;
        () =&amp;gt; 
            f =&amp;gt; x =&amp;gt; f(this.Next.Node&amp;lt;TAccumulate&amp;gt;()(f)(x))(this.value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, class name is tagged with underscore since class is C# specific.&lt;/p&gt;
&lt;p&gt;Null is a special case, so, exactly the same way how 0 is handled in Church numeral:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _ListNode&amp;lt;T&amp;gt;
{
    private _ListNode()
    {
    }

    private class _NullListNode : _ListNode&amp;lt;T&amp;gt;
    {
        protected override _ListNode&amp;lt;T&amp;gt; Next { get { return this; } set { } }

        public override ListNode&amp;lt;T, TAccumulate&amp;gt; Node&amp;lt;TAccumulate&amp;gt;
            () =&amp;gt; 
                f =&amp;gt; x =&amp;gt; x;
    }

    public static _ListNode&amp;lt;T&amp;gt; Null { get; } = new _NullListNode();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IsNull&lt;/h2&gt;
&lt;p&gt;Null is _ListNode&amp;lt;T&amp;gt;.Null, so IsNull function is easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _ListNodeExtensions
{
    // IsNull = node =&amp;gt; node(value =&amp;gt; _ =&amp;gt; ChurchBoolean.False)(ChurchBoolean.True)
    public static Boolean IsNull&amp;lt;T&amp;gt;
        (this _ListNode&amp;lt;T&amp;gt; node) =&amp;gt;
            node.Node&amp;lt;Boolean&amp;gt;()(value =&amp;gt; _ =&amp;gt; ChurchBoolean.False)(ChurchBoolean.True);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IsNull predicate is similar to the IsNull of Church list encoded with 1 tuple as each node.&lt;/p&gt;
&lt;h2&gt;Create, value and Next&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _ListNodeExtensions
{
    // Create = value =&amp;gt; next =&amp;gt; f =&amp;gt; x =&amp;gt; f(value)(next(f)(x))
    public static Func&amp;lt;_ListNode&amp;lt;T&amp;gt;, _ListNode&amp;lt;T&amp;gt;&amp;gt; Create&amp;lt;T&amp;gt;
        (T value) =&amp;gt; next =&amp;gt; new _ListNode&amp;lt;T&amp;gt;(value, next);
// Value = node =&amp;gt; anyValueToIgnore =&amp;gt; node(value =&amp;gt; _ =&amp;gt; value)(anyValueToIgnore)
    public static T Value&amp;lt;T&amp;gt;
        (this _ListNode&amp;lt;T&amp;gt; node, T anyValueToIgnore = default(T)) =&amp;gt;
            node.Node&amp;lt;T&amp;gt;()(_ =&amp;gt; value =&amp;gt; value)(anyValueToIgnore);

    // Next = node =&amp;gt; node(value =&amp;gt; tuple =&amp;gt; tuple.Shift(Create(value)))(ChurchTuple.Create(Null)(Null)).Item1()
    public static _ListNode&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;
        (this _ListNode&amp;lt;T&amp;gt; node) =&amp;gt;
            node.Node&amp;lt;Tuple&amp;lt;_ListNode&amp;lt;T&amp;gt;, _ListNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;()
                (tuple =&amp;gt; value =&amp;gt; tuple.Shift(Create(value)))
                (ChurchTuple.Create&amp;lt;_ListNode&amp;lt;T&amp;gt;, _ListNode&amp;lt;T&amp;gt;&amp;gt;(_ListNode&amp;lt;T&amp;gt;.Null)(_ListNode&amp;lt;T&amp;gt;.Null))
                .Item1();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next is tricky but the same way as Church numeral’s Decrease2, which version with shifting the tuple.&lt;/p&gt;
&lt;h2&gt;Index&lt;/h2&gt;
&lt;p&gt;The same as other list encodings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _ListNodeExtensions
{
    // Index = start =&amp;gt; index =&amp;gt; index(Next)(start)
    public static _ListNode&amp;lt;T&amp;gt; Index&amp;lt;T&amp;gt;
        (this _ListNode&amp;lt;T&amp;gt; start, _Numeral index) =&amp;gt; index.Numeral&amp;lt;_ListNode&amp;lt;T&amp;gt;&amp;gt;()(Next)(start);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class _ListNodeTests
{
    [TestMethod()]
    public void CreateValueNextTest()
    {
        _ListNode&amp;lt;int&amp;gt; node1 = _ListNodeExtensions.Create(1)(_ListNodeExtensions.GetNull&amp;lt;int&amp;gt;());
        _ListNode&amp;lt;int&amp;gt; node2 = _ListNodeExtensions.Create(2)(node1);
        _ListNode&amp;lt;int&amp;gt; node3 = _ListNodeExtensions.Create(3)(node2);
        Assert.AreEqual(1, node1.Value());
        Assert.AreEqual(_ListNodeExtensions.GetNull&amp;lt;int&amp;gt;(), node1.Next());
        Assert.AreEqual(2, node2.Value());
        Assert.AreEqual(node1.Value(), node2.Next().Value());
        Assert.AreEqual(3, node3.Value());
        Assert.AreEqual(node2.Value(), node3.Next().Value());
        Assert.IsTrue(_ListNodeExtensions.GetNull&amp;lt;object&amp;gt;().Next().IsNull()._Unchurch());
    }

    [TestMethod()]
    public void NullIsNullTest()
    {
        _ListNode&amp;lt;int&amp;gt; node = _ListNodeExtensions.Create(1)(_ListNodeExtensions.GetNull&amp;lt;int&amp;gt;());
        Assert.IsTrue(_ListNodeExtensions.GetNull&amp;lt;object&amp;gt;().IsNull()._Unchurch());
        Assert.IsFalse(node.IsNull()._Unchurch());
    }

    [TestMethod()]
    public void IndexTest()
    {
        _ListNode&amp;lt;int&amp;gt; node1 = _ListNodeExtensions.Create(1)(_ListNodeExtensions.GetNull&amp;lt;int&amp;gt;());
        _ListNode&amp;lt;int&amp;gt; node2 = _ListNodeExtensions.Create(2)(node1);
        _ListNode&amp;lt;int&amp;gt; node3 = _ListNodeExtensions.Create(3)(node2);
        Assert.AreEqual(node3.Value(), node3.Index(0U._Church()).Value());
        Assert.AreEqual(node2.Value(), node3.Index(1U._Church()).Value());
        Assert.AreEqual(node1.Value(), node3.Index(2U._Church()).Value());
        Assert.IsTrue(node3.Index(3U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(4U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(5U._Church()).IsNull()._Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (16) Encoding Church List with 2 Church Pairs as a Node</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-16-encoding-church-list-with-2-church-pairs-as-a-node/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-16-encoding-church-list-with-2-church-pairs-as-a-node/</guid><description>Previous part encoded Church list with one  (2-tuple) as a list node. An alternative way</description><pubDate>Fri, 16 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-5-list&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-5-list&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Previous part encoded Church list with one &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pair&lt;/a&gt; (2-tuple) as a list node. An alternative way is to use 2 tuples as a node, one wrapping the other.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Outer tuple’s Item1 will be the null flag (a Church Boolean value to indicate this node is null or not)&lt;/li&gt;
&lt;li&gt;Outer tuple’s Item2 is the inner tuple:
&lt;ul&gt;
&lt;li&gt;Inner tuple’s Item1 is the value of this node&lt;/li&gt;
&lt;li&gt;Inner tuple’s Item2 is the next node&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;IsNull and Null&lt;/h2&gt;
&lt;p&gt;Above definition can immediately have:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull2 = λl.(Item1 l)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Null is easy to be defined to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Null2 = λf.True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;just returns True no matter what, which also guarantees above IsNull works.&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ListNode2 is the alias of Tuple&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
public delegate object ListNode2&amp;lt;out T&amp;gt;(Boolean&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt; f);

public static partial class ChurchList2
{
    // Null = f =&amp;gt; ChurchBoolean.True
    public static object Null&amp;lt;T&amp;gt;
        (Boolean&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt; f) =&amp;gt; new Boolean(ChurchBoolean.True);

    // IsNull = node =&amp;gt; node.Item1()
    public static Boolean IsNull&amp;lt;T&amp;gt;
        (this ListNode2&amp;lt;T&amp;gt; node) =&amp;gt; new Tuple&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt;(node).Item1();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Create, Value, and Next&lt;/h2&gt;
&lt;p&gt;Again from to above definitions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode2 = λv.λn.CreateTuple False (CreateTuple v n)
Value2 = λl.Item1 (Item2 l)
Next2 = λl.If (IsNull2 l) (λx.l) (λx.(Item2 (Item2 l)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next uses If again to return Null as its next node, the same as previous Church list implemented by 1 Church pair for each node.&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchList2
{
    // Create = value =&amp;gt; next =&amp;gt; ChurchTuple.Create(ChurchBoolean.False)(ChurchTuple.Create(value)(next))
    public static Func&amp;lt;ListNode2&amp;lt;T&amp;gt;, ListNode2&amp;lt;T&amp;gt;&amp;gt; Create&amp;lt;T&amp;gt;
        (T value) =&amp;gt; next =&amp;gt;
            new ListNode2&amp;lt;T&amp;gt;(ChurchTuple.Create&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
                (ChurchBoolean.False)
                (ChurchTuple.Create&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;(value)(next)));

    // Value = node =&amp;gt; node.Item2().Item1()
    public static T Value&amp;lt;T&amp;gt;
        (this ListNode2&amp;lt;T&amp;gt; node) =&amp;gt; new Tuple&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt;(node).Item2().Item1();

    // Next = node =&amp;gt; ChurchBoolean.If(node.IsNull())(_ =&amp;gt; node)(_ =&amp;gt; node.Item2().Item2())
    public static ListNode2&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;
        (this ListNode2&amp;lt;T&amp;gt; node) =&amp;gt;
            ChurchBoolean.If&amp;lt;ListNode2&amp;lt;T&amp;gt;&amp;gt;(node.IsNull())
                (_ =&amp;gt; node)
                (_ =&amp;gt; new Tuple&amp;lt;Boolean, Tuple&amp;lt;T, ListNode2&amp;lt;T&amp;gt;&amp;gt;&amp;gt;(node).Item2().Item2());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Index&lt;/h2&gt;
&lt;p&gt;The same as previous part as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index2 = λl.λi.i Next2 l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchList2
{
    // Index = start =&amp;gt; index = index(Next)(start)
    public static ListNode2&amp;lt;T&amp;gt; Index&amp;lt;T&amp;gt;
        (this ListNode2&amp;lt;T&amp;gt; start, _Numeral index) =&amp;gt; index.Numeral&amp;lt;ListNode2&amp;lt;T&amp;gt;&amp;gt;()(Next)(start);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;Again, the same thing as previous part:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchList2Tests
{
    [TestMethod()]
    public void CreateValueNextTest()
    {
        ListNode2&amp;lt;int&amp;gt; node1 = ChurchList2.Create(1)(ChurchList2.Null);
        ListNode2&amp;lt;int&amp;gt; node2 = ChurchList2.Create(2)(node1);
        ListNode2&amp;lt;int&amp;gt; node3 = ChurchList2.Create(3)(node2);
        Assert.AreEqual(1, node1.Value());
        Assert.AreEqual(ChurchList2.Null, node1.Next());
        Assert.AreEqual(2, node2.Value());
        Assert.AreEqual(node1, node2.Next());
        Assert.AreEqual(3, node3.Value());
        Assert.AreEqual(node2, node3.Next());
        Assert.IsTrue(new ListNode2&amp;lt;object&amp;gt;(ChurchList2.Null).Next().IsNull()._Unchurch());
    }

    [TestMethod()]
    public void NullIsNullTest()
    {
        ListNode2&amp;lt;int&amp;gt; node = ChurchList2.Create(1)(ChurchList2.Null);
        Assert.IsTrue(ChurchList2.IsNull&amp;lt;object&amp;gt;(ChurchList2.Null)._Unchurch());
        Assert.IsFalse(node.IsNull()._Unchurch());
    }

    [TestMethod()]
    public void IndexTest()
    {
        ListNode2&amp;lt;int&amp;gt; node1 = ChurchList2.Create(1)(ChurchList2.Null);
        ListNode2&amp;lt;int&amp;gt; node2 = ChurchList2.Create(2)(node1);
        ListNode2&amp;lt;int&amp;gt; node3 = ChurchList2.Create(3)(node2);
        Assert.AreEqual(node3, node3.Index(0U._Church()));
        Assert.AreEqual(node2, node3.Index(1U._Church()));
        Assert.AreEqual(node1, node3.Index(2U._Church()));
        Assert.IsTrue(node3.Index(3U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(4U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(5U._Church()).IsNull()._Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (15) Encoding Church List with Church Pair, And Null</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-15-encoding-church-list-with-church-pair-and-null/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-15-encoding-church-list-with-church-pair-and-null/</guid><description>This part will demonstrate how to use lambda expressions to encode another data structure - list (Church list in  or [LinkedList&lt;T&gt;](http</description><pubDate>Thu, 15 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-5-list&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-5-list&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This part will demonstrate how to use lambda expressions to encode another data structure - list (Church list in &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; or &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/he2s3bh7.aspx&quot;&gt;LinkedList&amp;lt;T&amp;gt;&lt;/a&gt; in .NET).&lt;/p&gt;
&lt;p&gt;It is straightforward to represent a Church list node (or &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ahf4c754.aspx&quot;&gt;LinkedListNode&amp;lt;T&amp;gt;&lt;/a&gt; in .NET) with Church pair (2-tuple)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tuple’s Item1 will be the value of current node&lt;/li&gt;
&lt;li&gt;tuple’s Item2 will be the next node, which is also another tuple of course.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Church pair as a Church list node&lt;/h2&gt;
&lt;p&gt;Remember Church pair (called tuple here in order to align with .NET):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateTuple := λx.λy.λf.f x y
Tuple := λf.f x y
Item1 := λt.t (λx.λy.x)
Item2 := λt.t (λx.λy.y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Directly for Church list node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateListNode := CreateTuple ≡ λv.λn.λf.f v n
ListNode := Tuple ≡ λf.f v n
Value := Item1 ≡ λl.l (λv.λn.v)
Next := Item2 ≡ λl.l (λv.λn.n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# code will be direct applications of the tuple’s functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ListNode&amp;lt;T&amp;gt; is alias of Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;
public delegate object ListNode&amp;lt;out T&amp;gt;(Boolean&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt; f);

public static class ChurchList
{
    // Create = value =&amp;gt; next =&amp;gt; ChurchTuple.Create(value)(next)
    public static Func&amp;lt;ListNode&amp;lt;T&amp;gt;, ListNode&amp;lt;T&amp;gt;&amp;gt; Create&amp;lt;T&amp;gt;
        (T value) =&amp;gt; next =&amp;gt; new ListNode&amp;lt;T&amp;gt;(ChurchTuple.Create&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(value)(next));

    // Value = node =&amp;gt; node.Item1()
    public static T Value&amp;lt;T&amp;gt;
        (this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; new Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(node).Item1();

    // Next = node =&amp;gt; node.Item2()
    public static ListNode&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;
        (this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; new Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(node).Item2();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Encoding Null, and IsNull predicate&lt;/h2&gt;
&lt;p&gt;If a list has a end node, what’s its Next node, or as a tuple what’s its Item2? In C#/.NET, a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ahf4c754.aspx&quot;&gt;LinkedListNode&amp;lt;T&amp;gt;&lt;/a&gt;’s Next property can be null to indicate the current node is the last element (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms132188.aspx&quot;&gt;Last&lt;/a&gt;) of the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/he2s3bh7.aspx&quot;&gt;LinkedList&amp;lt;T&amp;gt;&lt;/a&gt;. In lambda calculus, Null and IsNull predicate for list node can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Null := λf.λx.x
IsNull := λl.l (λv.λn.λx.False) True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When IsNull is applied with a null node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull Null
≡ (λl.l (λv.λn.λx.False) True) (λf.λx.x)
≡ (λf.λx.x) (λv.λn.λx.False) True
≡ (λx.x) True
≡ True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And when IsNull is applied with a non-null node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsNull (CreateListNode 0 Null)
≡ IsNull (λf.f 0 Null)
≡ (λl.l (λv.λn.λx.False) True) (λf.f 0 Null)
≡ (λf.f 0 Null) (λv.λn.λx.False) True
≡ (λv.λn.λx.False) 0 Null True
≡ (λn.λx.False) Null True
≡ (λx.False) True
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# implementation is noisy because a lot of type information has to be provided. This is Null:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Null = f =&amp;gt; _ =&amp;gt; _;
public static object Null&amp;lt;T&amp;gt;
    (Boolean&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt; f) =&amp;gt; new Func&amp;lt;Boolean, Boolean&amp;gt;(_ =&amp;gt; _);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and IsNull:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// IsNull = node(value =&amp;gt; next =&amp;gt; _ =&amp;gt; ChurchBoolean.False)(ChurchBoolean.True)
public static Boolean IsNull&amp;lt;T&amp;gt;
    (this ListNode&amp;lt;T&amp;gt; node) =&amp;gt;
        ((Func&amp;lt;Boolean, Boolean&amp;gt;)node(value =&amp;gt; next =&amp;gt;
            new Func&amp;lt;Boolean, Boolean&amp;gt;(_ =&amp;gt; ChurchBoolean.False)))(ChurchBoolean.True);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Church Boolean as Null&lt;/h3&gt;
&lt;p&gt;Actually, the definition of Null (λf.λx.x) is exactly the same as &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;False&lt;/a&gt; (λf.λx.x) according to alpha-conversion, so it can be redefined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Null := False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Null = ChurchBoolean.False;
public static ListNode&amp;lt;T&amp;gt; GetNull&amp;lt;T&amp;gt;
    () =&amp;gt; ChurchBoolean.False&amp;lt;Boolean&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;, Boolean&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a function GetNull has to be created, because C# does not support generic property.&lt;/p&gt;
&lt;p&gt;And IsNull needs to be refactored too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// IsNull = node =&amp;gt; node(value =&amp;gt; next =&amp;gt; _ =&amp;gt; ChurchBoolean.False)(ChurchBoolean.True)
public static Boolean IsNull&amp;lt;T&amp;gt;
    (this ListNode&amp;lt;T&amp;gt; node) =&amp;gt; 
        (Boolean)((Func&amp;lt;Boolean, object&amp;gt;)node(value =&amp;gt; next =&amp;gt; 
            new Func&amp;lt;Boolean, object&amp;gt;(_ =&amp;gt; 
                new Boolean(ChurchBoolean.False))))(ChurchBoolean.True);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here object in the code does not mean that System.Object is introduced to implement IsNull. It is just used to satisfy c# compiler. So with the help of &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pair&lt;/a&gt; and &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Church Boolean&lt;/a&gt;, the Church list has been encoded with functions in lambda calculus, as well as null and IsNull predicate.&lt;/p&gt;
&lt;h2&gt;The improved Next&lt;/h2&gt;
&lt;p&gt;Since Null is introduced, Next need to be redefined, so that a Null node’s next node will still be itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ListNodeNext := λl.If (IsNull l) (λx.l) (λx.(Item2 l))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Refactored C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Next = node =&amp;gt; If(node.IsNull())(_ =&amp;gt; Null)(_ =&amp;gt; node.Item2())
public static ListNode&amp;lt;T&amp;gt; Next&amp;lt;T&amp;gt;
    (this ListNode&amp;lt;T&amp;gt; node) =&amp;gt;
        ChurchBoolean.If&amp;lt;ListNode&amp;lt;T&amp;gt;&amp;gt;(node.IsNull())
            (_ =&amp;gt; node)
            (_ =&amp;gt; new Tuple&amp;lt;T, ListNode&amp;lt;T&amp;gt;&amp;gt;(node).Item2());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the same way as Church numerals, Decrease 0 is still 0.&lt;/p&gt;
&lt;h2&gt;Index&lt;/h2&gt;
&lt;p&gt;With the improved Next, the Index function can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index = λl.λi.i Next l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get the node of index I, just means to do “Next” I times, starting with the specified node.&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Index = start =&amp;gt; index =&amp;gt; index(Next)(start)
public static ListNode&amp;lt;T&amp;gt; Index&amp;lt;T&amp;gt;
    (this ListNode&amp;lt;T&amp;gt; start, _Numeral index) =&amp;gt; index.Numeral&amp;lt;ListNode&amp;lt;T&amp;gt;&amp;gt;()(Next)(start);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;The following unit tests also shows how to use Church list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchListTests
{
    [TestMethod()]
    public void CreateValueNextTest()
    {
        ListNode&amp;lt;int&amp;gt; node1 = ChurchList.Create(1)(ChurchList.Null);
        ListNode&amp;lt;int&amp;gt; node2 = ChurchList.Create(2)(node1);
        ListNode&amp;lt;int&amp;gt; node3 = ChurchList.Create(3)(node2);
        Assert.AreEqual(1, node1.Value());
        Assert.AreEqual(ChurchList.Null, node1.Next());
        Assert.AreEqual(2, node2.Value());
        Assert.AreEqual(node1, node2.Next());
        Assert.AreEqual(3, node3.Value());
        Assert.AreEqual(node2, node3.Next());
        Assert.IsTrue(ChurchList.GetNull&amp;lt;object&amp;gt;().Next().IsNull()._Unchurch());
    }

    [TestMethod()]
    public void NullIsNullTest()
    {
        ListNode&amp;lt;int&amp;gt; node = ChurchList.Create(1)(ChurchList.Null);
        Assert.IsTrue(ChurchList.IsNull&amp;lt;object&amp;gt;(ChurchList.Null)._Unchurch());
        Assert.IsTrue(ChurchList.GetNull&amp;lt;object&amp;gt;().IsNull()._Unchurch());
        Assert.IsTrue(new ListNode&amp;lt;object&amp;gt;(ChurchBoolean.False&amp;lt;Boolean&amp;lt;object, ListNode&amp;lt;object&amp;gt;&amp;gt;, Boolean&amp;gt;).IsNull()._Unchurch());
        Assert.IsFalse(node.IsNull()._Unchurch());
    }

    [TestMethod()]
    public void IndexTest()
    {
        ListNode&amp;lt;int&amp;gt; node1 = ChurchList.Create(1)(ChurchList.Null);
        ListNode&amp;lt;int&amp;gt; node2 = ChurchList.Create(2)(node1);
        ListNode&amp;lt;int&amp;gt; node3 = ChurchList.Create(3)(node2);
        Assert.AreEqual(node3, node3.Index(0U._Church()));
        Assert.AreEqual(node2, node3.Index(1U._Church()));
        Assert.AreEqual(node1, node3.Index(2U._Church()));
        Assert.IsTrue(node3.Index(3U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(4U._Church()).IsNull()._Unchurch());
        Assert.IsTrue(node3.Index(5U._Church()).IsNull()._Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (14) Church Pair (2-Tuple) and Church Numeral Decrease</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-14-church-pair-2-tuple-and-church-numeral-decrease/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-14-church-pair-2-tuple-and-church-numeral-decrease/</guid><description>In the  part, the Decrease was defined as:</description><pubDate>Wed, 14 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;Church numeral arithmetic&lt;/a&gt; part, the Decrease was defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease := λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is complex. Now with Church pair (called tuple here to align to C# terms), Decrease can be defined in a easier way.&lt;/p&gt;
&lt;h2&gt;Shift a Church Pair (2-Tuple)&lt;/h2&gt;
&lt;p&gt;First, a function is needed to shift a tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shift = λf.λt.CreateTuple (Item2 t) (f (Item1 t))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It takes a tuple (x, y) and a function f, then returns a new tuple (y, f y).&lt;/p&gt;
&lt;p&gt;C# implementation is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// (x, y) -&amp;gt; (y, f(y))
// Shift = tuple =&amp;gt; f =&amp;gt; Create(tuple.Item2())(f(tuple.Item1()))
public static Tuple&amp;lt;T, T&amp;gt; Shift&amp;lt;T&amp;gt;
    (this Tuple&amp;lt;T, T&amp;gt; tuple, Func&amp;lt;T, T&amp;gt; f) =&amp;gt; Create&amp;lt;T, T&amp;gt;(tuple.Item2())(f(tuple.Item2()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the implementation is uncurried extension method for convenience of application, and readability.&lt;/p&gt;
&lt;h2&gt;Decrease a Church numeral&lt;/h2&gt;
&lt;p&gt;Remember a Church numeral n can be considered to do “Increase” n times from 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n Increase Zero
≡ n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What if doing “Shift” n times base on (0, 0)?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3 (Shift Increase) (0, 0)
≡ (Shift Increase) ∘ (Shift Increase) ∘ (Shift Increase) (0, 0)
≡ (Shift Increase) ∘ (Shift Increase) (0, Increase 0)
≡ (Shift Increase) ∘ (Shift Increase) (0, 1)
≡ (Shift Increase) ∘ (1, Increase 1)
≡ (Shift Increase) ∘ (1, 2)
≡ (2, Increase 2)
≡ (2, 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n (Shift Increase (0, 0))
≡ (n - 1, n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This turns out a way to get the predecessor of n. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease2 := λn.Item1 (n (Shift Increase) (CreateTuple 0 0))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // Decrease2 = n =&amp;gt; n(tuple =&amp;gt; tuple.Shift(Increase))(ChurchTuple.Create(Zero)(Zero)).Item1();
    public static _Numeral Decrease2
        (this _Numeral numeral) =&amp;gt; 
            numeral.Numeral&amp;lt;Tuple&amp;lt;_Numeral, _Numeral&amp;gt;&amp;gt;()
                (tuple =&amp;gt; tuple.Shift(Increase)) // (x, y) -&amp;gt; (y, y + 1)
                (ChurchTuple.Create&amp;lt;_Numeral, _Numeral&amp;gt;(Zero)(Zero))
            .Item1();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;The following unit tests also shows how to apply the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;uncurried&lt;/a&gt; methods Swap, Shift, _Create:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchTupleTests
{
    [TestMethod()]
    public void CreateItem1Item2Test()
    {
        Tuple&amp;lt;int, string&amp;gt; tuple1 = ChurchTuple.Create&amp;lt;int, string&amp;gt;(1)(&quot;a&quot;);
        Assert.AreEqual(1, tuple1.Item1());
        Assert.AreEqual(&quot;a&quot;, tuple1.Item2());
        Tuple&amp;lt;string, int&amp;gt; tuple2 = ChurchTuple.Create&amp;lt;string, int&amp;gt;(&quot;a&quot;)(1);
        Assert.AreEqual(&quot;a&quot;, tuple2.Item1());
        Assert.AreEqual(1, tuple2.Item2());
        object @object = new object();
        Tuple&amp;lt;object, int&amp;gt; tuple3 = ChurchTuple.Create&amp;lt;object, int&amp;gt;(@object)(1);
        Assert.AreEqual(@object, tuple3.Item1());
        Assert.AreEqual(1, tuple3.Item2());
    }

    [TestMethod()]
    public void ShiftTest()
    {
        Tuple&amp;lt;int, int&amp;gt; tuple1 = ChurchTuple.Create&amp;lt;int, int&amp;gt;(1)(2).Shift(_ =&amp;gt; _);
        Assert.AreEqual(2, tuple1.Item1());
        Assert.AreEqual(2, tuple1.Item2());
        Tuple&amp;lt;int, int&amp;gt; tuple2 = ChurchTuple.Create&amp;lt;int, int&amp;gt;(2)(3).Shift(value =&amp;gt; value * 2);
        Assert.AreEqual(3, tuple2.Item1());
        Assert.AreEqual(6, tuple2.Item2());
        Tuple&amp;lt;string, string&amp;gt; tuple3 = ChurchTuple.Create&amp;lt;string, string&amp;gt;(&quot;a&quot;)(&quot;b&quot;).Shift(value =&amp;gt; value + &quot;c&quot;);
        Assert.AreEqual(&quot;b&quot;, tuple3.Item1());
        Assert.AreEqual(&quot;bc&quot;, tuple3.Item2());
    }

    [TestMethod()]
    public void SwapTest()
    {
        Tuple&amp;lt;int, string&amp;gt; tuple1 = ChurchTuple.Create&amp;lt;string, int&amp;gt;(&quot;a&quot;)(1).Swap();
        Assert.AreEqual(1, tuple1.Item1());
        Assert.AreEqual(&quot;a&quot;, tuple1.Item2());
        Tuple&amp;lt;string, int&amp;gt; tuple2 = ChurchTuple.Create&amp;lt;int, string&amp;gt;(1)(&quot;a&quot;).Swap();
        Assert.AreEqual(&quot;a&quot;, tuple2.Item1());
        Assert.AreEqual(1, tuple2.Item2());
        object @object = new object();
        Tuple&amp;lt;object, int&amp;gt; tuple3 = ChurchTuple.Create&amp;lt;int, object&amp;gt;(1)(@object).Swap();
        Assert.AreEqual(@object, tuple3.Item1());
        Assert.AreEqual(1, tuple3.Item2());
    }

    [TestMethod()]
    public void _CreateTest()
    {
        Tuple&amp;lt;int, string&amp;gt; tuple1 = ChurchTuple._Create(1, &quot;a&quot;);
        Assert.AreEqual(1, tuple1.Item1());
        Assert.AreEqual(&quot;a&quot;, tuple1.Item2());
        Tuple&amp;lt;string, int&amp;gt; tuple2 = ChurchTuple._Create(&quot;a&quot;, 1);
        Assert.AreEqual(&quot;a&quot;, tuple2.Item1());
        Assert.AreEqual(1, tuple2.Item2());
        object @object = new object();
        Tuple&amp;lt;object, int&amp;gt; tuple3 = ChurchTuple._Create(@object, 1);
        Assert.AreEqual(@object, tuple3.Item1());
        Assert.AreEqual(1, tuple3.Item2());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (13) Encoding Church Pairs (2-Tuples) and Generic Church Booleans</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans/</guid><description>is the Church encoding of the  type, aka 2-</description><pubDate>Tue, 13 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-4-tuple-and-signed-numeral&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding#Church_pairs&quot;&gt;Church pair&lt;/a&gt; is the Church encoding of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Cons&quot;&gt;pair&lt;/a&gt; type, aka 2-&lt;a href=&quot;http://en.wikipedia.org/wiki/Tuple&quot;&gt;tuple&lt;/a&gt;. Unlike the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd268536.aspx&quot;&gt;Tuple&amp;lt;T1, T2&amp;gt;&lt;/a&gt; class in .NET, in lambda calculus Church pair will be represented by lambda expression. To avoid 2 naming systems, here in all the code, Church pair will be called tuple.&lt;/p&gt;
&lt;h2&gt;Church pair (2-tuple)&lt;/h2&gt;
&lt;p&gt;A Church pair can be constructed with 2 values x y:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CreateTuple := λx.λy.λf.f x y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it return a tuple - another lambda expression (λf.f x y). So tuple is a higher order function that takes a function and apply it with x and y.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuple := λf.f x y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tuple is a closure of x and y&lt;/li&gt;
&lt;li&gt;f is supposed to be in the format of λx.λy.E&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, to get the first item x, a f like λx.λy.x can be applied to a tuple.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 := λt.t (λx.λy.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Item1 takes a tuple as parameter, applies it with a (λx.λy.x), and returns the first item x. This is how Item1 works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 (CreateTuple x y)
≡ Item1 (λf.f x y)
≡ (λt.t (λx.λy.x)) (λf.f x y)
≡ (λf.f x y) (λx.λy.x)
≡ (λx.λy.x) x y
≡ (λy.x) y
≡ x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So to get the second item y, a tuple can be applied with a f of λx.λy.y:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item2 := λt.t (λx.λy.y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And just like Item1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item2 (CreateTuple x y)
≡ Item2 (λf.f x y)
≡ (λt.t (λx.λy.y)) (λf.f x y)
≡ (λf.f x y) (λx.λy.y)
≡ (λx.λy.y) x y
≡ (λy.y) y
≡ y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Based on above definitions, here is the C# implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Tuple = f =&amp;gt; f(item1)(item1)
public delegate object Tuple&amp;lt;out T1, out T2&amp;gt;(Func&amp;lt;T1, Func&amp;lt;T2, object&amp;gt;&amp;gt; f);
// Tuple is an alias of Func&amp;lt;Func&amp;lt;T1, Func&amp;lt;T2, object&amp;gt;&amp;gt;, object&amp;gt;

public static class ChurchTuple
{
    // CreateTuple = item1 =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2)
    public static Func&amp;lt;T2, Tuple&amp;lt;T1, T2&amp;gt;&amp;gt; Create&amp;lt;T1, T2&amp;gt;
        (T1 item1) =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2);

    // Item1 =&amp;gt; tuple =&amp;gt; tuple(x =&amp;gt; y =&amp;gt; x)
    public static T1 Item1&amp;lt;T1, T2&amp;gt;
        (this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; (T1)tuple(x =&amp;gt; y =&amp;gt; x);

    // Item2 =&amp;gt; tuple =&amp;gt; tuple(x =&amp;gt; y =&amp;gt; y)
    public static T2 Item2&amp;lt;T1, T2&amp;gt;
        (this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; (T2)tuple(x =&amp;gt; y =&amp;gt; y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tuple’s Item1 is of type T1, Item2 is of type T2. And, f is λx.λy.E, so its type is Func&amp;lt;T1, Func&amp;lt;T2, object&amp;gt;&amp;gt;. Again, just like the object in Church Boolean Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;, object here does not mean System.Object is introduced. It just mean λx.λy.E can return any type. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;in function Item1, f is λx.λy.x or x =&amp;gt; y =&amp;gt; x, so f returns a T1&lt;/li&gt;
&lt;li&gt;in function Item2, f is λx.λy.y or x =&amp;gt; y =&amp;gt; y, so f returns a T2&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Generic Church Booleans&lt;/h2&gt;
&lt;p&gt;If observing above definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 := λt.t (λx.λy.x)
Item2 := λt.t (λx.λy.y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Item1 f is actually True, and in Item2 f becomes False. So above definition can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Item1 := λt.t True
Item2 := λt.t False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C# more work need to be done for this substitution. As fore mentioned, f is Func&amp;lt;T1, Func&amp;lt;T2, object&amp;gt;&amp;gt; but currently implemented &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Church Boolean&lt;/a&gt; is Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;. So a more specific Church Boolean is needed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from: object Boolean(TTrue @true, TFalse @TFalse)
public delegate Func&amp;lt;TFalse, object&amp;gt; Boolean&amp;lt;in TTrue, in TFalse&amp;gt;(TTrue @true);
// Boolean is alias of Func&amp;lt;TTrue, Func&amp;lt;TFalse, object&amp;gt;&amp;gt;

public static partial class ChurchBoolean
{
    // True = @true =&amp;gt; @false =&amp;gt; @true
    public static Func&amp;lt;TFalse, object&amp;gt; True&amp;lt;TTrue, TFalse&amp;gt;
        (TTrue @true) =&amp;gt; @false =&amp;gt; @true;

    // False = @true =&amp;gt; @false =&amp;gt; @false
    public static Func&amp;lt;TFalse, object&amp;gt; False&amp;lt;TTrue, TFalse&amp;gt;
        (TTrue @true) =&amp;gt; @false =&amp;gt; @false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this generic version of Church Booleans, above Church tuple can be re-implemented:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate object Tuple&amp;lt;out T1, out T2&amp;gt;(Boolean&amp;lt;T1, T2&amp;gt; f);

public static partial class ChurchTuple
{
    // CreateTuple = item1 =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2)
    public static Func&amp;lt;T2, Tuple&amp;lt;T1, T2&amp;gt;&amp;gt; Create&amp;lt;T1, T2&amp;gt;
        (T1 item1) =&amp;gt; item2 =&amp;gt; f =&amp;gt; f(item1)(item2);

    // Item1 = tuple =&amp;gt; tuple(x =&amp;gt; y =&amp;gt; x)
    public static T1 Item1&amp;lt;T1, T2&amp;gt;
        (this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; (T1)tuple(ChurchBoolean.True&amp;lt;T1, T2&amp;gt;);

    // Item2 = tuple =&amp;gt; tuple(x =&amp;gt; y =&amp;gt; y)
    public static T2 Item2&amp;lt;T1, T2&amp;gt;
        (this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; (T2)tuple(ChurchBoolean.False&amp;lt;T1, T2&amp;gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Back to Church Boolean - why not using generic Church Booleans from the beginning?&lt;/h3&gt;
&lt;p&gt;If the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;Boolean logic&lt;/a&gt; is implemented with this generic version of Church Booleans, then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    // And = a =&amp;gt; b =&amp;gt; a(b)(False)
    public static Boolean&amp;lt;TTrue, TFalse&amp;gt; And&amp;lt;TTrue, TFalse&amp;gt;
        (this Boolean&amp;lt;Boolean&amp;lt;TTrue, TFalse&amp;gt;, Boolean&amp;lt;TTrue, TFalse&amp;gt;&amp;gt; a, Boolean&amp;lt;TTrue, TFalse&amp;gt; b) =&amp;gt; 
            (Boolean&amp;lt;TTrue, TFalse&amp;gt;)a(b)(False&amp;lt;TTrue, TFalse&amp;gt;);

    // Or = a =&amp;gt; b =&amp;gt; a(True)(b)
    public static Boolean&amp;lt;TTrue, TFalse&amp;gt; Or&amp;lt;TTrue, TFalse&amp;gt;
        (this Boolean&amp;lt;Boolean&amp;lt;TTrue, TFalse&amp;gt;, Boolean&amp;lt;TTrue, TFalse&amp;gt;&amp;gt; a, Boolean&amp;lt;TTrue, TFalse&amp;gt; b) =&amp;gt; 
            (Boolean&amp;lt;TTrue, TFalse&amp;gt;)a(True&amp;lt;TTrue, TFalse&amp;gt;)(b);

    // Not = boolean =&amp;gt; boolean(False)(True)
    public static Boolean&amp;lt;TTrue, TFalse&amp;gt; Not&amp;lt;TTrue, TFalse&amp;gt;
        (this Boolean&amp;lt;Boolean&amp;lt;TTrue, TFalse&amp;gt;, Boolean&amp;lt;TTrue, TFalse&amp;gt;&amp;gt; boolean) =&amp;gt; 
            (Boolean&amp;lt;TTrue, TFalse&amp;gt;)boolean(False&amp;lt;TTrue, TFalse&amp;gt;)(True&amp;lt;TTrue, TFalse&amp;gt;);

    // Xor = a =&amp;gt; b =&amp;gt; a(b(False)(True))(b(True)(False))
    public static Boolean&amp;lt;TTrue, TFalse&amp;gt; Xor&amp;lt;TTrue, TFalse&amp;gt;
        (this Boolean&amp;lt;Boolean&amp;lt;TTrue, TFalse&amp;gt;, Boolean&amp;lt;TTrue, TFalse&amp;gt;&amp;gt; a, Boolean&amp;lt;Boolean&amp;lt;TTrue, TFalse&amp;gt;, Boolean&amp;lt;TTrue, TFalse&amp;gt;&amp;gt; b) =&amp;gt; 
            (Boolean&amp;lt;TTrue, TFalse&amp;gt;)a((Boolean&amp;lt;TTrue, TFalse&amp;gt;)b(False&amp;lt;TTrue, TFalse&amp;gt;)(True&amp;lt;TTrue, TFalse&amp;gt;))((Boolean&amp;lt;TTrue, TFalse&amp;gt;)b(True&amp;lt;TTrue, TFalse&amp;gt;)(False&amp;lt;TTrue, TFalse&amp;gt;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type parameter becomes too noisy. It is difficult to read or use these functions.&lt;/p&gt;
&lt;h2&gt;Currying and type inference&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;part of currying&lt;/a&gt; mentioned currying may cause some noise for &lt;a href=&quot;/posts/understanding-csharp-3-0-features-3-type-inference&quot;&gt;type inference in C#&lt;/a&gt;. Here is an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Swap = λt.CreateTuple (Item2 t) (Item1 t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# logic is simple, but the type information has to be given so it is noisy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Swap = tuple =&amp;gt; Create(tuple.Item2())(tuple.Item1())
public static Tuple&amp;lt;T2, T1&amp;gt; Swap&amp;lt;T1, T2&amp;gt;
    (this Tuple&amp;lt;T1, T2&amp;gt; tuple) =&amp;gt; Create&amp;lt;T2, T1&amp;gt;(tuple.Item2())(tuple.Item1());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When invoking the curried Create function, the type arguments cannot be omitted. This is signature of Create:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T2, Tuple&amp;lt;T1, T2&amp;gt;&amp;gt; Create&amp;lt;T1, T2&amp;gt;(T1 item1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After currying, T2’s appearances are all relocated to Create’s returned type. So during the 2 applications of Create(item1)(item2), C# compiler does not even know how to compile first application Create(item1). It cannot infer what return type is wanted. The application code will always end up as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ChurchTuple.Create&amp;lt;int, string&amp;gt;(1)(&quot;a&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, only for convenience of C# coding and less noise for readability, this &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application&quot;&gt;uncurried&lt;/a&gt; helper method can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Tuple&amp;lt;T1, T2&amp;gt; _Create&amp;lt;T1, T2&amp;gt;
    (T1 item1, T2 item2) =&amp;gt; Create&amp;lt;T1, T2&amp;gt;(item1)(item2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now T2 is relocated back to parameter, so type arguments are not mandatory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ChurchTuple._Create(1, &quot;a&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Much less noise. _Create is also tagged with underscore since its uncurrying is for adapting C# type inference feature.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (12) Church Numeral Comparison Operators</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-12-church-numeral-comparison-operators/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-12-church-numeral-comparison-operators/</guid><description>With the predicates defined in , operators can be defined in [ Numeral class](/posts/lambda-calculus-via-c-sharp-9-wrapping</description><pubDate>Mon, 12 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Church Numeral Comparison Operators&lt;/h2&gt;
&lt;p&gt;With the predicates defined in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;previous part&lt;/a&gt;, operators can be defined in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;_Numeral class&lt;/a&gt;. Once again, class does not exist in lambda calculus, but C# class provides a place to define operators, which greatly improve the readability.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public static Boolean operator &amp;lt;=
        (_Numeral a, _Numeral b) =&amp;gt; a.IsLessOrEqual(b);

    public static Boolean operator &amp;gt;=
        (_Numeral a, _Numeral b) =&amp;gt; a.IsGreaterOrEqual(b);

    public static Boolean operator &amp;lt;
        (_Numeral a, _Numeral b) =&amp;gt; a.IsLess(b);

    public static Boolean operator &amp;gt;
        (_Numeral a, _Numeral b) =&amp;gt; a.IsGreater(b);

    public static Boolean operator ==
        (_Numeral a, _Numeral b) =&amp;gt; a.AreEqual(b);

    public static Boolean operator !=
        (_Numeral a, _Numeral b) =&amp;gt; a.AreNotEqual(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;C# object equality&lt;/h3&gt;
&lt;p&gt;This has nothing to do with lambda calculus and Church encoding. In C#, since == and != are customized, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bsc2ak47.aspx&quot;&gt;Object.Equals&lt;/a&gt; and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx&quot;&gt;Object.GetHashCode&lt;/a&gt; are required to be overridden too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public override int GetHashCode
        () =&amp;gt; this._Unchurch().GetHashCode();

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        _Numeral numeral = obj as _Numeral;
        if ((object)numeral == null)
        {
            return false;
        }

        return this.AreEqual(numeral)._Unchurch();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These code are all C# specific requirement:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GetHashCode just returns current Church Numeral’s corresponding System.UInt32’s hash code&lt;/li&gt;
&lt;li&gt;Equals just applies the AreEqual predicate, and coverts the returned &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Church Boolean&lt;/a&gt; into &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.boolean.aspx&quot;&gt;System.Boolean&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;In the same (tedious) way as arithmetic operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchPredicatesTests
{
    private static readonly _Numeral Zero = _Numeral.Zero;

    [TestMethod()]
    public void IsZeroTest()
    {
        Assert.AreEqual(0U == 0U, Zero.IsZero()._Unchurch());
        Assert.AreEqual(1U == 0U, 1U._Church().IsZero()._Unchurch());
        Assert.AreEqual(2U == 0U, 2U._Church().IsZero()._Unchurch());
        Assert.AreEqual(123U == 0U, 123U._Church().IsZero()._Unchurch());
    }

    [TestMethod()]
    public void IsLessOrEqualTest()
    {
        Assert.AreEqual(0U &amp;lt;= 0U, (Zero &amp;lt;= Zero)._Unchurch());
        Assert.AreEqual(1U &amp;lt;= 0U, (1U._Church() &amp;lt;= Zero)._Unchurch());
        Assert.AreEqual(2U &amp;lt;= 0U, (2U._Church() &amp;lt;= Zero)._Unchurch());
        Assert.AreEqual(123U &amp;lt;= 0U, (123U._Church() &amp;lt;= Zero)._Unchurch());
        Assert.AreEqual(0U &amp;lt;= 2U, (Zero &amp;lt;= 2U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;lt;= 2U, (1U._Church() &amp;lt;= 2U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;lt;= 2U, (2U._Church() &amp;lt;= 2U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;lt;= 2U, (123U._Church() &amp;lt;= 2U._Church())._Unchurch());
        Assert.AreEqual(0U &amp;lt;= 124U, (Zero &amp;lt;= 124U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;lt;= 124U, (1U._Church() &amp;lt;= 124U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;lt;= 124U, (2U._Church() &amp;lt;= 124U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;lt;= 124U, (123U._Church() &amp;lt;= 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsGreaterOrEqualTest()
    {
        Assert.AreEqual(0U &amp;gt;= 0U, (Zero &amp;gt;= Zero)._Unchurch());
        Assert.AreEqual(1U &amp;gt;= 0U, (1U._Church() &amp;gt;= Zero)._Unchurch());
        Assert.AreEqual(2U &amp;gt;= 0U, (2U._Church() &amp;gt;= Zero)._Unchurch());
        Assert.AreEqual(123U &amp;gt;= 0U, (123U._Church() &amp;gt;= Zero)._Unchurch());
        Assert.AreEqual(0U &amp;gt;= 2U, (Zero &amp;gt;= 2U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;gt;= 2U, (1U._Church() &amp;gt;= 2U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;gt;= 2U, (2U._Church() &amp;gt;= 2U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;gt;= 2U, (123U._Church() &amp;gt;= 2U._Church())._Unchurch());
        Assert.AreEqual(0U &amp;gt;= 124U, (Zero &amp;gt;= 124U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;gt;= 124U, (1U._Church() &amp;gt;= 124U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;gt;= 124U, (2U._Church() &amp;gt;= 124U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;gt;= 124U, (123U._Church() &amp;gt;= 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsLessTest()
    {
        Assert.AreEqual(0U &amp;lt; 0U, (Zero &amp;lt; Zero)._Unchurch());
        Assert.AreEqual(1U &amp;lt; 0U, (1U._Church() &amp;lt; Zero)._Unchurch());
        Assert.AreEqual(2U &amp;lt; 0U, (2U._Church() &amp;lt; Zero)._Unchurch());
        Assert.AreEqual(123U &amp;lt; 0U, (123U._Church() &amp;lt; Zero)._Unchurch());
        Assert.AreEqual(0U &amp;lt; 2U, (Zero &amp;lt; 2U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;lt; 2U, (1U._Church() &amp;lt; 2U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;lt; 2U, (2U._Church() &amp;lt; 2U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;lt; 2U, (123U._Church() &amp;lt; 2U._Church())._Unchurch());
        Assert.AreEqual(0U &amp;lt; 124U, (Zero &amp;lt; 124U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;lt; 124U, (1U._Church() &amp;lt; 124U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;lt; 124U, (2U._Church() &amp;lt; 124U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;lt; 124U, (123U._Church() &amp;lt; 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsGreaterTest()
    {
        Assert.AreEqual(0U &amp;gt; 0U, (Zero &amp;gt; Zero)._Unchurch());
        Assert.AreEqual(1U &amp;gt; 0U, (1U._Church() &amp;gt; Zero)._Unchurch());
        Assert.AreEqual(2U &amp;gt; 0U, (2U._Church() &amp;gt; Zero)._Unchurch());
        Assert.AreEqual(123U &amp;gt; 0U, (123U._Church() &amp;gt; Zero)._Unchurch());
        Assert.AreEqual(0U &amp;gt; 2U, (Zero &amp;gt; 2U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;gt; 2U, (1U._Church() &amp;gt; 2U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;gt; 2U, (2U._Church() &amp;gt; 2U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;gt; 2U, (123U._Church() &amp;gt; 2U._Church())._Unchurch());
        Assert.AreEqual(0U &amp;gt; 124U, (Zero &amp;gt; 124U._Church())._Unchurch());
        Assert.AreEqual(1U &amp;gt; 124U, (1U._Church() &amp;gt; 124U._Church())._Unchurch());
        Assert.AreEqual(2U &amp;gt; 124U, (2U._Church() &amp;gt; 124U._Church())._Unchurch());
        Assert.AreEqual(123U &amp;gt; 124U, (123U._Church() &amp;gt; 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsEqualTest()
    {
        Assert.AreEqual(0U == 0U, (Zero == Zero)._Unchurch());
        Assert.AreEqual(1U == 0U, (1U._Church() == Zero)._Unchurch());
        Assert.AreEqual(2U == 0U, (2U._Church() == Zero)._Unchurch());
        Assert.AreEqual(123U == 0U, (123U._Church() == Zero)._Unchurch());
        Assert.AreEqual(0U == 2U, (Zero == 2U._Church())._Unchurch());
        Assert.AreEqual(1U == 2U, (1U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(2U == 2U, (2U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(123U == 2U, (123U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(0U == 124U, (Zero == 124U._Church())._Unchurch());
        Assert.AreEqual(1U == 124U, (1U._Church() == 124U._Church())._Unchurch());
        Assert.AreEqual(2U == 124U, (2U._Church() == 124U._Church())._Unchurch());
        Assert.AreEqual(123U == 124U, (123U._Church() == 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsNotEqualTest()
    {
        Assert.AreEqual(0U != 0U, (Zero != Zero)._Unchurch());
        Assert.AreEqual(1U != 0U, (1U._Church() != Zero)._Unchurch());
        Assert.AreEqual(2U != 0U, (2U._Church() != Zero)._Unchurch());
        Assert.AreEqual(123U != 0U, (123U._Church() != Zero)._Unchurch());
        Assert.AreEqual(0U != 2U, (Zero != 2U._Church())._Unchurch());
        Assert.AreEqual(1U != 2U, (1U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(2U != 2U, (2U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(123U != 2U, (123U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(0U != 124U, (Zero != 124U._Church())._Unchurch());
        Assert.AreEqual(1U != 124U, (1U._Church() != 124U._Church())._Unchurch());
        Assert.AreEqual(2U != 124U, (2U._Church() != 124U._Church())._Unchurch());
        Assert.AreEqual(123U != 124U, (123U._Church() != 124U._Church())._Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (11) Predicates, And Divide</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide/</guid><description>A  is a function that returns a Boolean value. In Church encoding of lambda calculus, a predicate is a lambda expression that return</description><pubDate>Sun, 11 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding#Predicates&quot;&gt;predicate&lt;/a&gt; is a function that returns a Boolean value. In Church encoding of lambda calculus, a predicate is a lambda expression that returns a Church Boolean.&lt;/p&gt;
&lt;h2&gt;Predicates&lt;/h2&gt;
&lt;p&gt;The is the most fundamental predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsZero := λn.n (λx.False) True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When it is applied, it will do (λx.False) n times based on True:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When n is 0, it will “apply (λx.False)” 0 time and just returns True&lt;/li&gt;
&lt;li&gt;When n is not 0, it will “apply (λx.False)” 1 or more times, so returns False&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchPredicates
{
    // IsZero = n =&amp;gt; n(_ =&amp;gt; False)(True)
    public static Boolean IsZero
        (this _Numeral numeral) =&amp;gt;
            numeral.Numeral&amp;lt;Boolean&amp;gt;()(_ =&amp;gt; ChurchBoolean.False)(ChurchBoolean.True);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With IsZero, it will be easy to define other predicates for Church numeral:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsLessOrEqual := λa.λb.IsZero (Subtract a b)
IsGreaterOrEqual := λa.λb.IsZero (Subtract b a)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are very simple and speak for themselves.&lt;/p&gt;
&lt;p&gt;Then these 2 predicates lead to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AreEqual := λa.λb.And (IsLessOrEqual a b) (IsGreaterOrEqual a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their oppositions will be just applications of Not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsLess := λa.λb.Not (IsGreaterOrEqual a b)
IsGreater := λa.λb.Not (IsLessOrEqual a b)
AreNotEqual := λa.λb.Not (AreEqual a b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the C# implementation of these 6 predicates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchPredicates
{
    // IsLessOrEqual = a =&amp;gt; b =&amp;gt; a.Subtract(b).IsZero()
    public static Boolean IsLessOrEqual
        (this _Numeral a, _Numeral b) =&amp;gt; a.Subtract(b).IsZero();

    // IsGreaterOrEqual = a =&amp;gt; b =&amp;gt; b.Subtract(a).IsZero()
    public static Boolean IsGreaterOrEqual
        (this _Numeral a, _Numeral b) =&amp;gt; b.Subtract(a).IsZero();

    // IsLess = a =&amp;gt; b =&amp;gt; a.IsGreaterOrEqual(b).Not()
    public static Boolean IsLess
        (this _Numeral a, _Numeral b) =&amp;gt; a.IsGreaterOrEqual(b).Not();

    // IsGreater = a =&amp;gt; b =&amp;gt; a.IsLessOrEqual(b).Not()
    public static Boolean IsGreater
        (this _Numeral a, _Numeral b) =&amp;gt; a.IsLessOrEqual(b).Not();

    // AreEqual = a =&amp;gt; b =&amp;gt; a.Subtract(b).IsZero().And(a.Subtract(b).IsZero())
    // Or:
    // AreEqual = a =&amp;gt; b =&amp;gt; a.IsLessOrEqual(b).And(a.IsGreaterOrEqual(b))
    public static Boolean AreEqual
        (this _Numeral a, _Numeral b) =&amp;gt; a.IsLessOrEqual(b).And(a.IsGreaterOrEqual(b));

    // AreNotEqual = a =&amp;gt; b =&amp;gt; a.AreEqual(b).Not()
    public static Boolean AreNotEqual
        (this _Numeral a, _Numeral b) =&amp;gt; a.AreEqual(b).Not();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Divide&lt;/h2&gt;
&lt;p&gt;With IsZero, now Divide can be finally defined.&lt;/p&gt;
&lt;p&gt;The division of natural numbers can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a/b := If a &amp;gt;= b then 1+ (a-b)/b else 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So maybe Divide can be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_DivideBy := λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (_DivideBy (Subtract a b) b)) (λx.Zero)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the problem: This above 2 definitions are both &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursion&quot;&gt;recursive&lt;/a&gt;. Each uses itself in the definition.&lt;/p&gt;
&lt;p&gt;In lambda calculus, lambda expressions are anonymous functions without names. And so far in all parts, all the other names are just shortcuts for readability. For example, IsZero use the function name of True and False - to make IsZero shorter and more readable; And it is totally ok not to use those names:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IsZero := λn.n (λx.False) True
        ≡ λn.n (λx.λt.λf.f) (λt.λf.t)

  IsZero 5
≡ (λn.n (λx.λt.λf.f) (λt.λf.t)) 5
≡ ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast to _DivideBy - for example, _DivideBy 10 3:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(λa.λb.If (IsGreaterOrEqual a b) (λx.Add One (Self (Subtract a b) b)) (λx.Zero)) 10 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a underscore is tagged to the name. _DivideBy seems more C# specific rather than lambda calculus. But the corresponding C# function below will be temporarily used from now on, since it is very easy to understand. So here comes the recursive C# function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // _DivideBy = dividend =&amp;gt; divisor =&amp;gt; 
    // If(dividend.IsGreaterOrEqual(divisor))
    //    (_ =&amp;gt; One + (dividend - divisor)._DivideBy(divisor))
    //    (_ =&amp;gt; Zero);
    public static _Numeral _DivideBy
        (this _Numeral dividend, _Numeral divisor) =&amp;gt; 
            ChurchBoolean.If&amp;lt;_Numeral&amp;gt;(dividend &amp;gt;= divisor)
                (_ =&amp;gt; One + (dividend - divisor)._DivideBy(divisor))
                (_ =&amp;gt; Zero);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the / operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public static _Numeral operator /
        (_Numeral a, _Numeral b) =&amp;gt; a._DivideBy(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Divide will be revisited in a &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide&quot;&gt;later part&lt;/a&gt;, after introducing Y combinator for recursion.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (10) Church Numeral Arithmetic Operators</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-10-church-numeral-arithmetic-operators/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-10-church-numeral-arithmetic-operators/</guid><description>Another benefits of introducing (cheating with)  into lambda calculus is - it provides a place to define</description><pubDate>Sat, 10 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;Operators&lt;/h2&gt;
&lt;p&gt;Another benefits of introducing (cheating with) &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;_Numeral class&lt;/a&gt; into lambda calculus is - it provides a place to define custom operators.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public static _Numeral operator +
        (_Numeral a, _Numeral b) =&amp;gt; a.Add(b);

    public static _Numeral operator -
        (_Numeral a, _Numeral b) =&amp;gt; a.Subtract(b);

    public static _Numeral operator *
        (_Numeral a, _Numeral b) =&amp;gt; a.Multiply(b);

    public static _Numeral operator ^
        (_Numeral a, _Numeral b) =&amp;gt; a.Pow(b);

    public static _Numeral operator ++
        (_Numeral numeral) =&amp;gt; numeral.Increase();

    public static _Numeral operator --
        (_Numeral numeral) =&amp;gt; numeral.Decrease();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This cannot be done to delegate type Numeral&amp;lt;T&amp;gt;. In C#, custom operators cannot be defined for delegates/functions/lambda expressions.&lt;/p&gt;
&lt;p&gt;Now Church numerals and arithmetic operations are all implemented in C#. Now it’s time for testing.&lt;/p&gt;
&lt;h2&gt;Conversion between Church numeral (now _Numeral) and System.UInt32&lt;/h2&gt;
&lt;p&gt;Similar to Church Boolean &amp;lt;-&amp;gt; System.Boolean, some conversion helper methods can be created between _Numeral and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.uint32.aspx&quot;&gt;System.UInt32&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchEncoding
{
    public static _Numeral _Church
        (this uint n) =&amp;gt; n &amp;gt; 0 ? new _Numeral(_Church(n - 1)) : _Numeral.Zero;

    public static uint _Unchurch
        (this _Numeral numeral) =&amp;gt; numeral.Numeral&amp;lt;uint&amp;gt;()(x =&amp;gt; x + 1)(0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, these 2 methods are tagged with underscore because unit is C# specific.&lt;/p&gt;
&lt;p&gt;In _Unchurch, a Church numeral (now a _Numeral) n is converted to natural number by “applying add 1” n times on 0.&lt;/p&gt;
&lt;p&gt;Similarly to _Unchurch, _Numeral can be converted to string too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchEncoding
{
    public static string _Visualize(this _Numeral numeral)
    {
        return numeral.Numeral&amp;lt;string&amp;gt;()(x =&amp;gt; string.Concat(x, &quot;#&quot;))(string.Empty);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;0 will be converted to empty string, 1 will be “#”, 2 will be “##”, etc.&lt;/p&gt;
&lt;h2&gt;Compare _Numeral and System.UInt32&lt;/h2&gt;
&lt;p&gt;Similar to above operators, == and != can be defined between Church numeral and System.UInt32:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public static bool operator ==
        (_Numeral a, uint b) =&amp;gt; a._Unchurch() == b;

    public static bool operator ==
        (uint a, _Numeral b) =&amp;gt; a == b._Unchurch();

    public static bool operator !=
        (_Numeral a, uint b) =&amp;gt; a._Unchurch() != b;

    public static bool operator !=
        (uint a, _Numeral b) =&amp;gt; a != b._Unchurch();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;bool and uint - these are totally C# specific, and will be only used for unit tests.&lt;/p&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;The last function needed is a Pow function for uint, because .NET only has a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.math.pow.aspx&quot;&gt;Math.Pow&lt;/a&gt; function for double.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class UInt32Extensions
{
    public static uint Pow(this uint mantissa, uint exponent)
    {
        uint result = 1;
        for (int i = 0; i &amp;lt; exponent; i++)
        {
            result *= mantissa;
        }
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same way as &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;Church Boolean tests&lt;/a&gt;, Church numeral and arithmetic operation can be unit tested by directly comparing results with System.UInt32’s arithmetic operation results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class _NumeralExtensionsTests
{
    [TestMethod()]
    public void IncreaseTest()
    {
        _Numeral numeral = 0U._Church();
        Assert.IsTrue(0U + 1U == ++numeral);
        Assert.IsTrue(1U + 1U == ++numeral);
        Assert.IsTrue(2U + 1U == ++numeral);
        Assert.IsTrue(3U + 1U == ++numeral);
        numeral = 123U._Church();
        Assert.IsTrue(123U + 1U == ++numeral);
    }

    [TestMethod()]
    public void AddTest()
    {
        Assert.IsTrue(0U + 0U == 0U._Church() + 0U._Church());
        Assert.IsTrue(0U + 1U == 0U._Church() + 1U._Church());
        Assert.IsTrue(10U + 0U == 10U._Church() + 0U._Church());
        Assert.IsTrue(0U + 10U == 0U._Church() + 10U._Church());
        Assert.IsTrue(1U + 1U == 1U._Church() + 1U._Church());
        Assert.IsTrue(10U + 1U == 10U._Church() + 1U._Church());
        Assert.IsTrue(1U + 10U == 1U._Church() + 10U._Church());
        Assert.IsTrue(3U + 5U == 3U._Church() + 5U._Church());
        Assert.IsTrue(123U + 345U == 123U._Church() + 345U._Church());
    }

    [TestMethod()]
    public void DecreaseTest()
    {
        _Numeral numeral = 3U._Church();
        Assert.IsTrue(3U - 1U == --numeral);
        Assert.IsTrue(2U - 1U == --numeral);
        Assert.IsTrue(1U - 1U == --numeral);
        Assert.IsTrue(0U == --numeral);
        numeral = 123U._Church();
        Assert.IsTrue(123U - 1U == --numeral);
    }

    [TestMethod()]
    public void SubtractTest()
    {
        Assert.IsTrue(0U - 0U == 0U._Church() - 0U._Church());
        Assert.IsTrue(0U == 0U._Church() - 1U._Church());
        Assert.IsTrue(10U - 0U == 10U._Church() - 0U._Church());
        Assert.IsTrue(0U == 0U._Church() - 10U._Church());
        Assert.IsTrue(1U - 1U == 1U._Church() - 1U._Church());
        Assert.IsTrue(10U - 1U == 10U._Church() - 1U._Church());
        Assert.IsTrue(0U == 1U._Church() - 10U._Church());
        Assert.IsTrue(0U == 3U._Church() - 5U._Church());
        Assert.IsTrue(0U == 123U._Church() - 345U._Church());
    }

    [TestMethod()]
    public void MultiplyTest()
    {
        Assert.IsTrue(0U * 0U == 0U._Church() * 0U._Church());
        Assert.IsTrue(0U * 1U == 0U._Church() * 1U._Church());
        Assert.IsTrue(10U * 0U == 10U._Church() * 0U._Church());
        Assert.IsTrue(0U * 10U == 0U._Church() * 10U._Church());
        Assert.IsTrue(1U * 1U == 1U._Church() * 1U._Church());
        Assert.IsTrue(10U * 1U == 10U._Church() * 1U._Church());
        Assert.IsTrue(1U * 10U == 1U._Church() * 10U._Church());
        Assert.IsTrue(3U * 5U == 3U._Church() * 5U._Church());
        Assert.IsTrue(12U * 23U == 12U._Church() * 23U._Church());
    }

    [TestMethod()]
    public void PowTest()
    {
        Assert.IsTrue(0U.Pow(1U) == (0U._Church() ^ 1U._Church()));
        Assert.IsTrue(10U.Pow(0U) == (10U._Church() ^ 0U._Church()));
        Assert.IsTrue(0U.Pow(10U) == (0U._Church() ^ 10U._Church()));
        Assert.IsTrue(1U.Pow(1U) == (1U._Church() ^ 1U._Church()));
        Assert.IsTrue(10U.Pow(1U) == (10U._Church() ^ 1U._Church()));
        Assert.IsTrue(1U.Pow(10U) == (1U._Church() ^ 10U._Church()));
        Assert.IsTrue(3U.Pow(5U) == (3U._Church() ^ 5U._Church()));
        Assert.IsTrue(5U.Pow(3U) == (5U._Church() ^ 3U._Church()));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (9) Wrapping Church Numerals And Arithmetic</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic/</guid><description>In , the Decrease function was a Func&lt;Numeral&lt;Func&lt;Func&lt;T, T&gt;, T&gt;&gt;, Numeral&lt;T&gt;&gt;:</description><pubDate>Fri, 09 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals&quot;&gt;previous part&lt;/a&gt;, the Decrease function was a Func&amp;lt;Numeral&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt;, Numeral&amp;lt;T&amp;gt;&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Decrease = n =&amp;gt; f =&amp;gt; x =&amp;gt; n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _)
public static Numeral&amp;lt;T&amp;gt; Decrease&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt; numeral) =&amp;gt; 
            f =&amp;gt; x =&amp;gt; numeral(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is ok because in the definition of Numeral&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate Func&amp;lt;T, T&amp;gt; Numeral&amp;lt;T&amp;gt;(Func&amp;lt;T, T&amp;gt; f);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;T can be anything. But on another hand, Decrease can be more useful, if its parameter and return value are exactly the same type. This can be done if in the definition of Numeral&amp;lt;T&amp;gt;, the type parameter can be hidden, so that Decrease can be something like a Func&amp;lt;Numeral, Numeral&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Non-generic wrapper for Numeral&amp;lt;T&amp;gt;, and Increase&lt;/h2&gt;
&lt;p&gt;One possible solution (inspired by &lt;a href=&quot;https://wiki.haskell.org/Keywords#forall&quot;&gt;forall&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt;) is to create a non-generic wrapper class without type parameter, and have Numeral&amp;lt;T&amp;gt; to be on that class’s member:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public virtual Numeral&amp;lt;T&amp;gt; Numeral&amp;lt;T&amp;gt;()
    {
        …
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, a underscore prefixes the class name to indicate this is cheating, because class exists in C# but not in &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; at all.&lt;/p&gt;
&lt;p&gt;But how this class can be implemented? Remember:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase2 := λn.λf.f ∘ (n f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the _Numeral class can be implemented from its previous Church numeral:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public _Numeral(_Numeral predecessor)
    {
        this.Predecessor = predecessor;
    }

    protected virtual _Numeral Predecessor { get; set; }

    public virtual Numeral&amp;lt;T&amp;gt; Numeral&amp;lt;T&amp;gt;
        () =&amp;gt; 
            f =&amp;gt; f.o(this.Predecessor.Numeral&amp;lt;T&amp;gt;()(f));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So an increased _Numeral is constructed by using current _Numeral as the predecessor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    public _Numeral Increase
        () =&amp;gt; new _Numeral(this);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a special case, 0 does not apply f at all. It can be implemented as a sub class of _Numeral so that the behavior can be overridden:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class _Numeral
{
    private _Numeral()
    {
    }

    private class _ZeroNumeral : _Numeral
    {
        protected override _Numeral Predecessor { get { return this; } set { } }

        public override Numeral&amp;lt;T&amp;gt; Numeral&amp;lt;T&amp;gt;
            () =&amp;gt; 
                f =&amp;gt; x =&amp;gt; x;
    }

    public static _Numeral Zero { get; } = new _ZeroNumeral();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that’s it. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;OOP&lt;/a&gt; pollution for Church numerals (of lambda calculus) won’t go any further. Notice 0 does not have a previous Church numeral, so its predecessor is itself. A &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number&quot;&gt;later part&lt;/a&gt; will implement signed church numerals.&lt;/p&gt;
&lt;h2&gt;Add&lt;/h2&gt;
&lt;p&gt;The other operators in previous part need to be refactored too. Naturally, Add will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // Increase = n =&amp;gt; n.Increase()
    private static _Numeral Increase
        (_Numeral numeral) =&amp;gt; numeral.Increase();

    // Add = a =&amp;gt; b =&amp;gt; a(Increase)(b)
    public static _Numeral Add
        (this _Numeral a, _Numeral b) =&amp;gt; a.Numeral&amp;lt;_Numeral&amp;gt;()(Increase)(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Decrease and Subtract&lt;/h2&gt;
&lt;p&gt;Finally, Decrease and Subtract can be done nicely, because now Decrease is a Func&amp;lt;_Numeral, _Numeral&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    public static _Numeral Zero { get; } = _Numeral.Zero;

    public static _Numeral One { get; } = _Numeral.Zero.Increase();

    // ...

    // Decrease = n =&amp;gt; f =&amp;gt; x =&amp;gt; n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _)
    public static _Numeral Decrease
        (this _Numeral numeral) =&amp;gt;
            new Numeral&amp;lt;_Numeral&amp;gt;(f =&amp;gt; x =&amp;gt;
                numeral.Numeral&amp;lt;Func&amp;lt;Func&amp;lt;_Numeral, _Numeral&amp;gt;, _Numeral&amp;gt;&amp;gt;()(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _))
                (Increase)(Zero);

    // Subtract = a =&amp;gt; b =&amp;gt; b(Decrease)(a)
    public static _Numeral Subtract
        (this _Numeral a, _Numeral b) =&amp;gt; b.Numeral&amp;lt;_Numeral&amp;gt;()(Decrease)(a);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Multiply and Pow&lt;/h2&gt;
&lt;p&gt;Similar to Add and Subtract, Multiply and Power can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Multiply := λa.λb.a (λx.Add b x) 0
Pow := λm.λe.e (λx.Multiply m x) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Multiply a b) means just to do “add b” a times on top of 0. (Power m e) is to do “multiply m” e times starting on 1.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class _NumeralExtensions
{
    // Multiply = a =&amp;gt; b =&amp;gt; a(x =&amp;gt; b.Add(x))(Zero)
    public static _Numeral Multiply
            (this _Numeral a, _Numeral b) =&amp;gt; a.Numeral&amp;lt;_Numeral&amp;gt;()(b.Add)(Zero);

    // Power = m =&amp;gt; e =&amp;gt; e(x =&amp;gt; m.Multiply(x))(1)
    public static _Numeral Pow
        (this _Numeral mantissa, _Numeral exponent) =&amp;gt; exponent.Numeral&amp;lt;_Numeral&amp;gt;()(mantissa.Multiply)(One);  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Divide?&lt;/h2&gt;
&lt;p&gt;Divide will implemented in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-11-predicates-and-divide&quot;&gt;another part&lt;/a&gt;, after implementing predicates. And a &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-23-y-combinator-and-divide&quot;&gt;better version&lt;/a&gt; will be implemented after introducing Y combinator.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (8) Church Numeral Arithmetic</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-8-church-numeral-arithmetic/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-8-church-numeral-arithmetic/</guid><description>The previous part defined Church numerals in  and implemented 0, 1, 2, 3 in 2 different ways. By observing the definition and code, there are some pat</description><pubDate>Thu, 08 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The previous part defined Church numerals in &lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;lambda calculus&lt;/a&gt; and implemented 0, 1, 2, 3 in 2 different ways. By observing the definition and code, there are some patterns when the Church numeral increases from 0 to 3.&lt;/p&gt;
&lt;h2&gt;Increase&lt;/h2&gt;
&lt;p&gt;In the definitions of Church numerals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f (x)
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The underlined parts can be substituted by the following underlined parts in the applications:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f x ≡ x
1 f x ≡ f x
2 f x ≡ f (f x)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then Church numerals’ definition become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λf.λx.x
1 := λf.λx.f (0 f x)
2 := λf.λx.f (1 f x)
3 := λf.λx.f (2 f x)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which shows how the the Church numerals increases. Generally, for a Church numeral n, the next numeral will be λf.λx.f (n f x). So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase := λn.λf.λx.f (n f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# implementation is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Increase = n =&amp;gt; f =&amp;gt; x =&amp;gt; f(n(f)(x))
public static Numeral&amp;lt;T&amp;gt; Increase&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;T&amp;gt; numeral) =&amp;gt; f =&amp;gt; x =&amp;gt; f(numeral(f)(x));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the other way, Church numeral N can be read as do something N times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n f ≡ fn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So increasing n means to do something one more time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Increase2 := λn.λf.f ∘ fn ≡ λn.λf.f ∘ (n f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Increase2 = n =&amp;gt; f =&amp;gt; f ^ (n + 1)
public static Numeral&amp;lt;T&amp;gt; Increase2&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;T&amp;gt; numeral) =&amp;gt; f =&amp;gt; f.o(numeral(f));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;previous part of Church Boolean operators&lt;/a&gt;, here extension methods are used for convenience and readability, e.g.: n.Increase().&lt;/p&gt;
&lt;h2&gt;Add&lt;/h2&gt;
&lt;p&gt;Again, from the definition, Church numeral a adding b means to “apply f” b times then “apply f” a times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add := λa.λb.λf.λx.a f (b f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also it means to do something a times then b times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add2 := λa.λb.λf.fa ∘ fb ≡ λa.λb.λf.(a f) ∘ (b f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Add = a =&amp;gt; b =&amp;gt; f =&amp;gt; x =&amp;gt; a(f)(b(f)(x))
public static Numeral&amp;lt;T&amp;gt; Add&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;T&amp;gt; a, Numeral&amp;lt;T&amp;gt; b) =&amp;gt; f =&amp;gt; x =&amp;gt; a(f)(b(f)(x));

// Add2 = a =&amp;gt; b =&amp;gt; f =&amp;gt; f ^ (a + b)
public static Numeral&amp;lt;T&amp;gt; Add2&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;T&amp;gt; a, Numeral&amp;lt;T&amp;gt; b) =&amp;gt; f =&amp;gt; a(f).o(b(f));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is also a third way to understand a adding b - “apply Increase” a times based on b:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add3 := λa.λb.a Increase b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Add3 = a =&amp;gt; b =&amp;gt; a(Increase)(b)
public static Numeral&amp;lt;T&amp;gt; Add3&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;Numeral&amp;lt;T&amp;gt;&amp;gt; a, Numeral&amp;lt;T&amp;gt; b) =&amp;gt; a(Increase)(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Decrease and subtract&lt;/h2&gt;
&lt;p&gt;Similarly, once Decrease is defined, Subtract can be defined easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Decrease := λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u)
Subtract := λa.λb.b Decrease a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This definition of Decrease is complex and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding#Derivation_of_predecessor_function&quot;&gt;explanation&lt;/a&gt; will be skipped. Later after defining &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pairs (2-tuples)&lt;/a&gt;, a &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-14-church-pair-2-tuple-and-church-numeral-decrease&quot;&gt;more intuitive version&lt;/a&gt; will be defined.&lt;/p&gt;
&lt;p&gt;C# code will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Decrease = n =&amp;gt; f =&amp;gt; x =&amp;gt; n(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _)
public static Numeral&amp;lt;T&amp;gt; Decrease&amp;lt;T&amp;gt;
    (this Numeral&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt; numeral) =&amp;gt; 
            f =&amp;gt; x =&amp;gt; numeral(g =&amp;gt; h =&amp;gt; h(g(f)))(_ =&amp;gt; x)(_ =&amp;gt; _);

// Cannot be compiled.
// Subtract = a =&amp;gt; b =&amp;gt; b(Decrease)(a)
public static Numeral&amp;lt;T&amp;gt; Subtract&amp;lt;T&amp;gt;
    (Numeral&amp;lt;T&amp;gt; a, Numeral&amp;lt;Numeral&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;&amp;gt;&amp;gt; b) =&amp;gt; b(Decrease)(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, Subtract cannot be compiled. The reason is, as a Church numeral, b requires the first parameter to be Func&amp;lt;TSomething, TSomething&amp;gt;, but Decrease becomes Func&amp;lt;TSomething, TSomethingElse&amp;gt;. &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-9-wrapping-church-numerals-and-arithmetic&quot;&gt;The next part&lt;/a&gt; will show how to work with this paradox in C#.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (7) Encoding Church Numerals</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-7-encoding-church-numerals/</guid><description>Previous parts showed that , , and [if logic](/posts/l</description><pubDate>Wed, 07 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Previous parts showed that &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Boolean values&lt;/a&gt;, &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-5-boolean-logic&quot;&gt;Boolean logic&lt;/a&gt;, and &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies&quot;&gt;if logic&lt;/a&gt; can all be encoded by lambda expressions. This and next few articles will focus on &lt;a href=&quot;http://en.wikipedia.org/wiki/Natural_number&quot;&gt;natural numbers&lt;/a&gt;. &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-18-encoding-signed-number&quot;&gt;Signed number&lt;/a&gt; will be encoded after introducing &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pairs (2-tuples)&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Church numerals&lt;/h2&gt;
&lt;p&gt;Church numerals are representations of natural numbers with lambda expressions under Church encoding. Church numerals are defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λfx.x                  ≡ λf.λx.x
1 := λfx.f x                ≡ λf.λx.f x
2 := λfx.f (f x)            ≡ λf.λx.f (f x)
3 := λfx.f (f (f x))        ≡ λf.λx.f (f (f x))
...
n := λfx.f (f ... (f x)...) ≡ λf.λx.f (f ... (f x)...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a Church numeral n is a &lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;higher order function&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It takes a function f and x&lt;/li&gt;
&lt;li&gt;then it applies f n times by starting with x, and returns the result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When applying f and x to Church numeral, which is a function just like other lambda expressions, there are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f x ≡ x
1 f x ≡ f x
2 f x ≡ f (f x)
3 f x ≡ f (f (f x))
...
n f x ≡ f (f (... (f x)...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to the definition of function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f (f x) 
≡ (f ∘ f) x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So above definition becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 := λfx.x                  ≡ λf.λx.x                   ≡ λf.λx.f0 x
1 := λfx.f x                ≡ λf.λx.f x                 ≡ λf.λx.f1 x
2 := λfx.f (f x)            ≡ λf.λx.(f ∘ f) x           ≡ λf.λx.f2 x
3 := λfx.f (f (f x))        ≡ λf.λx.(f ∘ f ∘ f) x       ≡ λf.λx.f3 x
...
n := λfx.f (f ... (f x)...) ≡ λf.λx.(f ∘ f ∘ ... ∘ f) x ≡ λf.λx.fn x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The partial application will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 f ≡ f0
1 f ≡ f1
2 f ≡ f2
3 f ≡ f3
...
n f ≡ fn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Church numeral n can be simply read as - do “something” n times.&lt;/p&gt;
&lt;h2&gt;C# Implementation - starting from 0&lt;/h2&gt;
&lt;p&gt;Similar to the C# implementation of Church Boolean, first a shortcut will be useful:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from: T Numeral&amp;lt;T&amp;gt;(Func&amp;lt;T, T&amp;gt; f, T x)
public delegate Func&amp;lt;T, T&amp;gt; Numeral&amp;lt;T&amp;gt;(Func&amp;lt;T, T&amp;gt; f);
// Numeral&amp;lt;T&amp;gt; is just an alias of Func&amp;lt;Func&amp;lt;T, T&amp;gt;, Func&amp;lt;T, T&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Based on the definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchNumeral
{
    // Zero = f =&amp;gt; x =&amp;gt; x
    public static Func&amp;lt;T, T&amp;gt; Zero&amp;lt;T&amp;gt;
        (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; x =&amp;gt; x;

    // One = f =&amp;gt; x =&amp;gt; f(x)
    public static Func&amp;lt;T, T&amp;gt; One&amp;lt;T&amp;gt;
        (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; x =&amp;gt; f(x);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also since 1 f ≡ f1, One can be also implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// One2 = f =&amp;gt; f ^ 1
public static Func&amp;lt;T, T&amp;gt; One2&amp;lt;T&amp;gt;
    (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; f;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here are 2 and 3 in the same ways:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Two = f =&amp;gt; x =&amp;gt; f(f(x))
public static Func&amp;lt;T, T&amp;gt; Two&amp;lt;T&amp;gt;
    (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; x =&amp;gt; f(f(x));

// Two2 = f =&amp;gt; f ^ 2
public static Func&amp;lt;T, T&amp;gt; Two2&amp;lt;T&amp;gt;
    (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; f.o(f);

// Three = f =&amp;gt; x =&amp;gt; f(f(f(x)))
public static Func&amp;lt;T, T&amp;gt; Three&amp;lt;T&amp;gt;
    (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; x =&amp;gt; f(f(f(x)));

// Three2 = f =&amp;gt; f ^ 3
public static Func&amp;lt;T, T&amp;gt; Three2&amp;lt;T&amp;gt;
    (Func&amp;lt;T, T&amp;gt; f) =&amp;gt; f.o(f).o(f);

// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the o function is the compose extension method defined in previous part.&lt;/p&gt;
&lt;p&gt;Four, Five, … can be defined in these 2 ways too. This part will stop here. The next several parts will try to create arithmetic operators, and use them to construct any other numbers.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (6) If Logic, And Reduction Strategies</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies/</guid><description>The if logic is already built in .</description><pubDate>Tue, 06 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-2-boolean-and-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-2-boolean-and-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The if logic is already built in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans&quot;&gt;Church Booleans&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The first If&lt;/h2&gt;
&lt;p&gt;So naturedly, This is the first implementation of if based on Church Boolean:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    // If1 = condition =&amp;gt; then =&amp;gt; @else =&amp;gt; condition(then, @else)
    public static Func&amp;lt;T, Func&amp;lt;T, T&amp;gt;&amp;gt; If1&amp;lt;T&amp;gt;
        (Boolean condition) =&amp;gt; then =&amp;gt; @else =&amp;gt;
            (T)condition
                (then)
                (@else);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Straightforward:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When condition is True, if returns then&lt;/li&gt;
&lt;li&gt;When condition is False, If returns @else.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It can be applied like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ChurchBoolean
    .If1&amp;lt;Boolean&amp;gt;(True)
        (True.And(True))
        (True.Or(False));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running this code will show a problem - And and Or are both triggered. However, when condition is either True or False, only one branch is expected to trigger. Here it is True.And(False) to be triggered, since condition is True.&lt;/p&gt;
&lt;h2&gt;Reduction strategies&lt;/h2&gt;
&lt;p&gt;How does If work? There are 3 arguments to be applied: If(arg1)(arg2)(arg3).&lt;/p&gt;
&lt;p&gt;The first application will be a beta-reduction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If (arg1) (arg2) (arg3)
≡ (condition =&amp;gt; then =&amp;gt; @else =&amp;gt; condition (then) (@else)) (True) (arg2) (arg3)
≡ (then =&amp;gt; @else =&amp;gt; True (then) (@else)) (arg2) (arg3)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the second reduction, &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Reduction_strategies&quot;&gt;it becomes tricky&lt;/a&gt;. Because now both lambda expression and arg2 can be reduced.&lt;/p&gt;
&lt;h3&gt;Normal order&lt;/h3&gt;
&lt;p&gt;If the lambda expression is reduced before the arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(then =&amp;gt; @else =&amp;gt; True (then) (@else)) (arg2) (arg3)
≡ (then =&amp;gt; @else =&amp;gt; then) (arg2) (arg3).
≡ (@else =&amp;gt; arg2) (arg3)
≡ arg2
≡ True.And(False)
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eventually only arg2 need to be reduced. This is called normal order. The unreduced arguments are used for function reduction.&lt;/p&gt;
&lt;h3&gt;Applicative order&lt;/h3&gt;
&lt;p&gt;However, C# has a different reduction strategy called applicative order. C# always first reduces a function&apos;s arguments, then use those reduced arguments to reduces the function itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(then =&amp;gt; @else =&amp;gt; True (then) (@else)) (arg2) (arg3)
≡ (then =&amp;gt; @else =&amp;gt; True (then) (@else)) (True.And(False)) (arg3)
≡ (then =&amp;gt; @else =&amp;gt; True (then) (@else)) (False) (arg3)
≡ (@else =&amp;gt; True (False) (@else)) (arg3)
≡ (@else =&amp;gt; True (False) (@else)) (True.Or(False))
≡ (@else =&amp;gt; True (False) (@else)) (True)
≡ True (False) (True)
≡ False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is why both And and Or are triggered. This is an example that reduction order &lt;a href=&quot;http://en.wikipedia.org/wiki/Evaluation_strategy&quot;&gt;matters&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Make If lazy&lt;/h2&gt;
&lt;p&gt;Under the C# reduction order, can If function be lazy, and works just like the first reduction order above? In the above version of If, both then and @else are of type T. In C# the easiest to think about is, changing both parameters from T into a function - the simplest will be Func&amp;lt;T&amp;gt;, so that after the condition returns one of those 2 functions, then the returned Func&amp;lt;T&amp;gt; function can be applied to return a T value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    // If2 = condition =&amp;gt; then =&amp;gt; @else =&amp;gt; condition(then, @else)()
    public static Func&amp;lt;Func&amp;lt;T&amp;gt;, Func&amp;lt;Func&amp;lt;T&amp;gt;, T&amp;gt;&amp;gt; If2&amp;lt;T&amp;gt;
        (Boolean condition) =&amp;gt; then =&amp;gt; @else =&amp;gt;
            ((Func&amp;lt;T&amp;gt;)condition
                (then)
                (@else))();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The application becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ChurchBoolean
    .If2&amp;lt;Boolean&amp;gt;(False)
        (() =&amp;gt; True.And(True))
        (() =&amp;gt; True.Or(False));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now in If, only 1 “branch” will be applied. However, in lambda calculus, a lambda expression without variable - λ.E (corresponding to Func&amp;lt;T&amp;gt;) - does not exist. This is easy to resolve - just make up a variable for lambda expression/a parameter for C# function. So If can be refactored to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    public static Func&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;, Func&amp;lt;Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;, T&amp;gt;&amp;gt; If&amp;lt;T&amp;gt;
        (Boolean condition) =&amp;gt; then =&amp;gt; @else =&amp;gt; 
            ((Func&amp;lt;Func&amp;lt;T, T&amp;gt;, T&amp;gt;)condition
                (then)
                (@else))(_ =&amp;gt; _);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the application is almost the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ChurchBoolean
    .If&amp;lt;Boolean&amp;gt;(True)
        (_ =&amp;gt; True.And(True))
        (_ =&amp;gt; True.Or(False));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In lambda calculus, If is much cleaner without type information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If := λc.λt.λf.c t f (λx.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unit tests&lt;/h2&gt;
&lt;p&gt;The following unit test verifies If’s correctness and laziness:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod()]
public void IfTest()
{
    Assert.AreEqual(
        true ? true &amp;amp;&amp;amp; false : true || false,
        ChurchBoolean.If&amp;lt;Boolean&amp;gt;(True)(_ =&amp;gt; True.And(False))(_ =&amp;gt; True.Or(False))._Unchurch());
    Assert.AreEqual(
        false ? true &amp;amp;&amp;amp; false : true || false,
        ChurchBoolean.If&amp;lt;Boolean&amp;gt;(False)(_ =&amp;gt; True.And(False))(_ =&amp;gt; True.Or(False))._Unchurch());

    bool isTrueBranchExecuted = false;
    bool isFalseBranchExecuted = false;
    ChurchBoolean.If&amp;lt;object&amp;gt;(True)
                    (_ =&amp;gt; { isTrueBranchExecuted = true; return null; })
                    (_ =&amp;gt; { isFalseBranchExecuted = true; return null; });
    Assert.IsTrue(isTrueBranchExecuted);
    Assert.IsFalse(isFalseBranchExecuted);

    isTrueBranchExecuted = false;
    isFalseBranchExecuted = false;
    ChurchBoolean.If&amp;lt;object&amp;gt;(False)
                    (_ =&amp;gt; { isTrueBranchExecuted = true; return null; })
                    (_ =&amp;gt; { isFalseBranchExecuted = true; return null; });
    Assert.IsFalse(isTrueBranchExecuted);
    Assert.IsTrue(isFalseBranchExecuted);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, If is successfully encoded in lambda calculus, and it’s C# implementation is as lazy as real “if”.&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (5) Boolean Logic</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-5-boolean-logic/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-5-boolean-logic/</guid><description>After defining Boolean values True and False with functions, now the Boolean logics can be encoded, by functions too.</description><pubDate>Mon, 05 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-2-boolean-and-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-2-boolean-and-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;After defining Boolean values True and False with functions, now the Boolean logics can be encoded, by functions too.&lt;/p&gt;
&lt;h2&gt;And&lt;/h2&gt;
&lt;p&gt;And can be defined by the following lambda:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;And :=  λab.a b False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is easy to understand. It is a function of 2 arity a and b and return a result:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a is True, (True b False) returns True’s first argument b. This is correct, since in Boolean logic (And True b) ≡ b&lt;/li&gt;
&lt;li&gt;When a is False, (False b False) returns False’s second argument False, This is also correct, since in Boolean logic, (And False b) ≡ False&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The C# implementation will be a function of type Func&amp;lt;Boolean, Boolean, Boolean&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    // And = a =&amp;gt; b =&amp;gt; a(b)(False)
    public static Boolean And
        (this Boolean a, Boolean b) =&amp;gt;
            // The casting to Boolean is safe, because b and False are both of type Boolean.
            (Boolean)a(b)(new Boolean(False));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows why the Boolean shortcut was created in previous part. Without this shortcut, above function declaration becomes more difficult to read: Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt; And(this Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;n a, Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt; b).&lt;/p&gt;
&lt;p&gt;This also uses the name of the function False, for readability too. Otherwise the code becomes return (Boolean)a(b)(new Boolean(True =&amp;gt; False =&amp;gt; False));&lt;/p&gt;
&lt;p&gt;Please also notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is a extension method without currying, so the application can be more readable: a.And(b). The same style will be followed for the other of operators.&lt;/li&gt;
&lt;li&gt;Function a’s application result is of type object, by definition. Here both arguments are Boolean, so the returned value will be guaranteed to be Boolean at runtime. This casting just tells the truth and does not introduce anything, so this is not cheating.&lt;/li&gt;
&lt;li&gt;The constructor application new Boolean(…) is just a syntax for the compiler, it just tells the truth as well, and does not introduce anything.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Or&lt;/h2&gt;
&lt;p&gt;Definition of Or is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Or :=  λab.a True b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Proof:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a is True, (Or True b) ≡ True&lt;/li&gt;
&lt;li&gt;When a is False, (False True b) ≡ b&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Or = a =&amp;gt; b =&amp;gt; a(True)(b)
public static Boolean Or
    (this Boolean a, Boolean b) =&amp;gt; (Boolean)a(new Boolean(True))(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Not&lt;/h2&gt;
&lt;p&gt;Definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Not := λb.b False True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Proof:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When b is True, (True False True) ≡ False&lt;/li&gt;
&lt;li&gt;When b is False, (False False True) ≡ True&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Not = boolean =&amp;gt; boolean(False)(True)
public static Boolean Not
    (this Boolean boolean) =&amp;gt; (Boolean)boolean(new Boolean(False))(new Boolean(True));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Xor&lt;/h2&gt;
&lt;p&gt;Definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Xor := λa.λb.a (b False True) (b True False)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Proof:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a is True, (True (b False True) (b True False)) ≡ (b False True)
&lt;ul&gt;
&lt;li&gt;When b is True, (True False True) ≡ False&lt;/li&gt;
&lt;li&gt;When b is False, (False False True) ≡ True&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When a is False, (False (b False True) (b True False)) ≡ (b True False)
&lt;ul&gt;
&lt;li&gt;When b is True, (True True False) ≡ True&lt;/li&gt;
&lt;li&gt;When b is False, (False True False) ≡ False&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Xor = a =&amp;gt; b =&amp;gt; a(b(False)(True))(b(True)(False))
public static Boolean Xor
    (this Boolean a, Boolean b) =&amp;gt;
        (Boolean)a
            (b(new Boolean(False))(new Boolean(True)))
            (b(new Boolean(True))(new Boolean(False)));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conversion between Church Boolean and System.Boolean&lt;/h2&gt;
&lt;p&gt;The unit test can be easier if the Church Boolean can be directly compared with C#’s &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.boolean.aspx&quot;&gt;Boolean&lt;/a&gt;. To achieve this, 2 conversion methods can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchEncoding
{
    // System.Boolean to Boolean
    public static Boolean _Church
        (this bool boolean) =&amp;gt; boolean ? new Boolean(True) : False;

    // Boolean to System.Boolean
    public static bool _Unchurch
        (this Boolean boolean) =&amp;gt; (bool)boolean(true)(false);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A underscore is used at the beginning of each method to highlight these are not part of the lambda calculus or Church encoding. They are C# specific.&lt;/p&gt;
&lt;p&gt;A generic version of Church Boolean and its Boolean logic will be introduced later in the &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-13-encoding-church-pairs-2-tuples-and-generic-church-booleans&quot;&gt;Church pair part&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Unit Tests&lt;/h2&gt;
&lt;p&gt;With the above 2 helper methods, the unit tests become extremely easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ChurchBooleanTests
{
    private static readonly Boolean True = ChurchBoolean.True;

    private static readonly Boolean False = ChurchBoolean.False;

    [TestMethod()]
    public void NotTest()
    {
        Assert.AreEqual(!true, True.Not()._Unchurch());
        Assert.AreEqual(!false, False.Not()._Unchurch());
    }

    [TestMethod()]
    public void AndTest()
    {
        Assert.AreEqual(true &amp;amp;&amp;amp; true, True.And(True)._Unchurch());
        Assert.AreEqual(true &amp;amp;&amp;amp; false, True.And(False)._Unchurch());
        Assert.AreEqual(false &amp;amp;&amp;amp; true, False.And(True)._Unchurch());
        Assert.AreEqual(false &amp;amp;&amp;amp; false, False.And(False)._Unchurch());
    }

    [TestMethod()]
    public void OrTest()
    {
        Assert.AreEqual(true || true, True.Or(True)._Unchurch());
        Assert.AreEqual(true || false, True.Or(False)._Unchurch());
        Assert.AreEqual(false || true, False.Or(True)._Unchurch());
        Assert.AreEqual(false || false, False.Or(False)._Unchurch());
    }

    [TestMethod()]
    public void XorTest()
    {
        Assert.AreEqual(true ^ true, True.Xor(True)._Unchurch());
        Assert.AreEqual(true ^ false, True.Xor(False)._Unchurch());
        Assert.AreEqual(false ^ true, False.Xor(True)._Unchurch());
        Assert.AreEqual(false ^ false, False.Xor(False)._Unchurch());
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (4) Encoding Church Booleans</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-4-encoding-church-booleans/</guid><description>After clarifying the concepts and terms, a lot of implementation coding starts from this part.</description><pubDate>Sun, 04 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-2-boolean-and-logic&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-2-boolean-and-logic&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;After clarifying the concepts and terms, a lot of implementation coding starts from this part.&lt;/p&gt;
&lt;h2&gt;Church encoding&lt;/h2&gt;
&lt;p&gt;The following several parts will look at &lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding&quot;&gt;Church encoding&lt;/a&gt;. Church encoding is an approach to represent data structures and operators just with lambdas, so that those data structures and operators form a mathematical structure embedded in the lambda calculus. Church is the last name of &lt;a href=&quot;http://en.wikipedia.org/wiki/Alonzo_Church&quot;&gt;Alonzo Church&lt;/a&gt; who was mentioned in part 1. He first encoded data structures with lambdas. Also, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Church-Turing_thesis&quot;&gt;Church-Turing thesis&lt;/a&gt; asserts that any computable operator (and its operands) can be represented under Church encoding.&lt;/p&gt;
&lt;p&gt;This and the next few articles will demonstrate how to us one primitive, lambda, to construct:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;other data structures like Boolean, unsigned integer. signed integer, pairs (tuples in C#), lists, etc.&lt;/li&gt;
&lt;li&gt;operators like if, predicates, arithmetic, etc..&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Church Booleans - True and False&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding#Church_Booleans&quot;&gt;Church Booleans&lt;/a&gt; are the Church encoding of the Boolean values true and false. Again, lambda is the only primitive here in &lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;lambda calculus&lt;/a&gt; and church encoding. So how the true and false can be represented by functions?&lt;/p&gt;
&lt;p&gt;The story starts with the most familiar if-then-else logic:&lt;/p&gt;
&lt;p&gt;if (Boolean)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;then (this branch is executed when Boolean is true)&lt;/li&gt;
&lt;li&gt;else (this branch is executed when Boolean is false)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So True and False can be presented in similar way, but in form of functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λtf.t
False := λtf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are both functions with 2 parameters.&lt;/p&gt;
&lt;p&gt;So when a Boolean function is applied with 2 arguments, t and f:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the first parameter t is returned, when this function represents the Boolean value of true&lt;/li&gt;
&lt;li&gt;the second parameter f is returned, when this function represents the Boolean value of false&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Straightforward. But remember, in lambda calculus, functions are curried, so True and False become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;True := λt.λf.t
False := λt.λf.f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# implementation is easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Curried from: object Boolean(object @true, object @false)
public delegate Func&amp;lt;object, object&amp;gt; Boolean(object @true);
// Boolean is just an alias for Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;

public static partial class ChurchBoolean
{
    public static Boolean True = 
        @true =&amp;gt; @false =&amp;gt; @true;

    public static Boolean False = 
        @true =&amp;gt; @false =&amp;gt; @false;

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Several things need to be noticed here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Object is used.
&lt;ul&gt;
&lt;li&gt;It is emphasized function, or lambda expression, is the only primitive type. So, in strong-typing language C#, what should be the type of t and f of lambda expression λt.λf.t? Here object is used. It does not mean cheating by introducing another primitive System.Object. It means “do not care” - t and f can be anything.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;C# delegate is used too.
&lt;ul&gt;
&lt;li&gt;This is not cheating either. Since t and f will be of type object, then λtf.t and λt.λf.f will be of type Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;. the only purpose of delegate type Boolean is to be a shortcut for improving readability, so that Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt; won’t be repeating everywhere.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Names are used.
&lt;ul&gt;
&lt;li&gt;It was also emphasized lambda expression is anonymous function. Above lambda expressions are named as True and False also for shortcut and reuse, so that later when they are used, new Func&amp;lt;object, Func&amp;lt;object, object&amp;gt;&amp;gt;(@true =&amp;gt; @false =&amp;gt; @true) won’t be repeating everywhere.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also in C#, function/lambda expressions cannot be created globally. So here they have to stay as a member of a class. In F#, this is allowed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let True t f = t
let False t f = f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No noise and automatically curried. Then this will compile to IL code similar to above C# structure (static member of a class).&lt;/p&gt;
&lt;p&gt;And finally, to highlight True and False are functions, here and following parts will stick with the tradition C# function declaration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ChurchBoolean
{
    public static Func&amp;lt;object, object&amp;gt; True
        (object @true) =&amp;gt; @false =&amp;gt; @true;

    public static Func&amp;lt;object, object&amp;gt; False
        (object @true) =&amp;gt; @false =&amp;gt; @false;

    // Not preferred:
    [Obsolete] public static Boolean False2 =
        @true =&amp;gt; @false =&amp;gt; @false;

    [Obsolete] public static Boolean True2 =
        @true =&amp;gt; @false =&amp;gt; @true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A generic version of Church Boolean will be introduced later in the Church pair part.&lt;/p&gt;
&lt;h2&gt;Unit test&lt;/h2&gt;
&lt;p&gt;True and False are just 2 C# functions. They can be verified in unit tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass()]
public class ChurchBooleanTests
{
    [TestMethod()]
    public void TrueTest()
    {
        Assert.AreEqual(1, ChurchBoolean.True(1)(&quot;2&quot;));
        Assert.AreEqual(&quot;a&quot;, ChurchBoolean.True(&quot;a&quot;)(null));
        Assert.AreEqual(null, ChurchBoolean.True(null)(1));
        object @object = new object();
        Assert.AreEqual(@object, ChurchBoolean.True(@object)(null));
    }

    [TestMethod()]
    public void FalseTest()
    {
        Assert.AreEqual(1, ChurchBoolean.False(&quot;2&quot;)(1));
        Assert.AreEqual(&quot;a&quot;, ChurchBoolean.False(null)(&quot;a&quot;));
        Assert.AreEqual(null, ChurchBoolean.False(1)(null));
        object @object = new object();
        Assert.AreEqual(@object, ChurchBoolean.False(null)(@object));
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (3) Fundamentals - Function composition</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-3-fundamentals-function-composition/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-3-fundamentals-function-composition/</guid><description>It may not be the best place to discuss function composition in the lambda calculus series. However, function composition will be used a lot in later articles, so here is a brief introduction.</description><pubDate>Sat, 03 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-1-fundamentals&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-1-fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;It may not be the best place to discuss function composition in the lambda calculus series. However, function composition will be used a lot in later articles, so here is a brief introduction.&lt;/p&gt;
&lt;h2&gt;Function composition&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Function_composition_(computer_science)&quot;&gt;Function composition&lt;/a&gt; means to combine simple functions into a more complicated function. The composition of f1 and f2 is defined as: f2 ∘ f1. This new function’s application is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f2 ∘ f1) x := f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the function names f1 and f2 imply the order of being applied. f2 ∘ f1 can also be read as f2 after f1.&lt;/p&gt;
&lt;p&gt;Again, it is &lt;a href=&quot;http://www.bbc.co.uk/films/2003/08/08/american_pie_the_wedding_2003_review.shtml&quot;&gt;perfectly nature normal thing&lt;/a&gt; to chain 2 function application together, by using the first function’s output as the second function’s input:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;double x = 1;
double y = Math.Sqrt(Math.Abs(x));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is a more complicated function, combined by 2 simple functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;double, double&amp;gt; absAndSqrt = x =&amp;gt; Math.Sqrt(Math.Abs(x));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So absAndSqrt is a composition of &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.math.abs.aspx&quot;&gt;Math.Abs&lt;/a&gt; and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.math.sqrt.aspx&quot;&gt;Math.Sqrt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Generally, a function of type Func&amp;lt;T1, T2&amp;gt; and a function of type Func&amp;lt;T2, T3&amp;gt; can be composed to a new function of type Func&amp;lt;T1, T3&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static Func&amp;lt;T1, T3&amp;gt; o&amp;lt;T1, T2, T3&amp;gt;
        (this Func&amp;lt;T2, T3&amp;gt; function2, Func&amp;lt;T1, T2&amp;gt; function1) =&amp;gt; 
            arg =&amp;gt; function2(function1(arg));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, in C# there is no place to define custom function operators, so extension method has to be used. This method is named o to mimic the ∘ operator. Also, in lambda calculus, functions are curried, so this one extension method is good enough.&lt;/p&gt;
&lt;h3&gt;Built-in operator in other languages&lt;/h3&gt;
&lt;p&gt;It is common for other functional language to have a built in function composition operator. In Haskell, ∘ is just &lt;a href=&quot;https://wiki.haskell.org/Function_composition&quot;&gt;dot (.):&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(.) :: (b -&amp;gt; c) -&amp;gt; (a -&amp;gt; b) -&amp;gt; a -&amp;gt; c
f2 . f1 = \x -&amp;gt; f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And F# has &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd233228.aspx&quot;&gt;&amp;gt;&amp;gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let inline (&amp;gt;&amp;gt;) f1 f2 x = f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is called forward composition. So there is also a backward composition operator &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd233228.aspx&quot;&gt;&amp;lt;&amp;lt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let inline (&amp;lt;&amp;lt;) f2 f1 x = f2 (f1 x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Properties&lt;/h2&gt;
&lt;p&gt;Function composition has 2 important properties&lt;/p&gt;
&lt;h3&gt;Associativity&lt;/h3&gt;
&lt;p&gt;Function composition is &lt;a href=&quot;http://en.wikipedia.org/wiki/Associative&quot;&gt;associative&lt;/a&gt;. That means (f3 ∘ f2) ∘ f1 and f3 ∘ (f2 ∘ f1) are the same.&lt;/p&gt;
&lt;p&gt;When applying x to (f3 ∘ f2) ∘ f1, according to the definition of ∘:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;((f3 ∘ f2) ∘ f1) (x)
≡ (f3 ∘ f2) (f1 (x))
≡ f3 (f2 (f1 (x)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And when applying x to f3 ∘ (f2 ∘ f1):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f3 ∘ (f2 ∘ f1)
≡ f3 ∘ (f2 (f1 (x)))
≡ f3 (f2 (f1 (x)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So they lead to identical result. In C#, this means f3.o(f2).o(f1) and f3.o(f2.o(f1)) are the same.&lt;/p&gt;
&lt;h3&gt;Unit&lt;/h3&gt;
&lt;p&gt;There is a unit function for function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Id := λx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f ∘ Id ≡ f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Id ∘ f ≡ f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, Id is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static T Id&amp;lt;T&amp;gt;
        (T value) =&amp;gt; value;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (2) Fundamentals - Lambda Expression, Variables, Reductions</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-2-fundamentals-lambda-expression-variables-reductions/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-2-fundamentals-lambda-expression-variables-reductions/</guid><description>The C# lambda expression . This post will explain lambda expression and other concepts in lambda calculus.</description><pubDate>Fri, 02 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-1-fundamentals&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-1-fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The C# lambda expression &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;has been discussed in detail&lt;/a&gt;. This post will explain lambda expression and other concepts in lambda calculus.&lt;/p&gt;
&lt;h2&gt;Lambda expression&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;lambda calculus&lt;/a&gt;, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Definition&quot;&gt;syntax&lt;/a&gt; of lambda expressions are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variables v1, v2, …, vN&lt;/li&gt;
&lt;li&gt;The abstraction symbols lambda (λ) and dot (.)
&lt;ul&gt;
&lt;li&gt;For example, the C# lambda expression x =&amp;gt; x + 1 will be λx.x + 1 in lambda calculus, except the C# specific type system (Int32, Int 64, …) does not exist in λx.x + 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Parentheses (), meaning higher precedence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In lambda calculus, the set of lambda expressions Λ, can be &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursive_definition&quot;&gt;defined recursively&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If x is a variable, then x ∈ Λ&lt;/li&gt;
&lt;li&gt;If x is a variable and E ∈ Λ, then (λx.E) ∈ Λ (called a lambda abstraction, which defines a anonymous function)
&lt;ul&gt;
&lt;li&gt;As fore-mentioned, λx.E is like x =&amp;gt; E in C#&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If M, N ∈ Λ, then (E1 E2) ∈ Λ (called an application)
&lt;ul&gt;
&lt;li&gt;The bigger difference is, while in lambda calculus, function application does not require parentheses () for parameter, it is just E1 E2; In C# it must be E1(E2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In lambda calculus, there are the &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Notation&quot;&gt;conventions&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Outermost parentheses are dropped: E1 E2 instead of (E1 E2)&lt;/li&gt;
&lt;li&gt;Applications are left associative: E1 E2 P may be written instead of ((E1 E2) P)
&lt;ul&gt;
&lt;li&gt;Again, E1 E2 P or ((E1 E2) P) will be E1(E2)(P) in C#&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The body of an abstraction extends &lt;a href=&quot;http://en.wikipedia.org/wiki/Regular_expression#Lazy_quantification&quot;&gt;as far right as possible&lt;/a&gt;: λx.E1 E2 means λx.(E1 E2) and not (λx.E1) E2
&lt;ul&gt;
&lt;li&gt;Here λx.E1 E2 will be x =&amp;gt; E1(E2) in C#&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A sequence of abstractions is contracted: λx.λy.λz.E is abbreviated as λxyz.E
&lt;ul&gt;
&lt;li&gt;λx.λy.λz.E is x =&amp;gt; y =&amp;gt; z =&amp;gt; E in C#&lt;/li&gt;
&lt;li&gt;λxyz.E is (x, y, z) =&amp;gt; E in C#&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bound and free variables&lt;/h2&gt;
&lt;p&gt;In lambda expression, λ or =&amp;gt; means to bind its variable wherever it occurs in the body. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variables within the scope of an abstraction are &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Free_and_bound_variables&quot;&gt;bound variables&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;All other variables are &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Free_and_bound_variables&quot;&gt;free variables&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, in the lambda expression from part 1 - λx.x + y or x =&amp;gt; x + y, x is bound variable and y is free variable.&lt;/p&gt;
&lt;p&gt;A variable is bound by its &quot;nearest&quot; abstraction. For example, in λx.y (λx.z x):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The single occurrence of x in the expression is bound by the second lambda.&lt;/li&gt;
&lt;li&gt;In C#, x =&amp;gt; y(x =&amp;gt; z(x)) does not compile, because the outer x variable conflicts with the inner x variable. This lambda expression must be rewritten as x =&amp;gt; y(a =&amp;gt; z(a)). now clearly the single occurrence of xx is bound by the second lambda. Here alpha-conversion is used, which will be explained later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lambda expression without free variables are called closed lambda expression, or combinator, which will be discussed later.&lt;/p&gt;
&lt;h2&gt;Reductions&lt;/h2&gt;
&lt;p&gt;In lambda calculus, there are 3 ways that lambda expressions can be &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Reduction&quot;&gt;reduced&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;α-conversion / alpha-conversion&lt;/h3&gt;
&lt;p&gt;In lambda calculus, lambda expression’s bound variables can be renamed. This is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B1-conversion&quot;&gt;alpha-conversion, or alpha-renaming&lt;/a&gt;. This is also a &lt;a href=&quot;http://www.bbc.co.uk/films/2003/08/08/american_pie_the_wedding_2003_review.shtml&quot;&gt;perfectly nature normal thing&lt;/a&gt;, just like in C# function or lambda expression’s parameter can be renamed freely.&lt;/p&gt;
&lt;p&gt;In the above example of λx.y (λx.z x), the inner lambda expression λx.z x can be alpha-converted to λa.z a. Apparently it has nothing to do with the outer x.&lt;/p&gt;
&lt;h3&gt;β-reduction / beta-reduction&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B2-reduction&quot;&gt;Beta-reduction&lt;/a&gt; of ((λV.E) R) is E[V := R], which means to &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Substitution&quot;&gt;substitute&lt;/a&gt; all free occurrences of the variable V in the expression E with expression R. It is just function application. For example, in C#, when applying this function x =&amp;gt; x + 1 with argument 2:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First parameter name x and the =&amp;gt; operator are ditched.&lt;/li&gt;
&lt;li&gt;Then in the body x + 1, x will be replaced by 2. So the result of function application is 2 + 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;η-conversion / eta-conversion&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-conversion&quot;&gt;Eta-conversion&lt;/a&gt; means 2 functions are the same &lt;a href=&quot;http://en.wikipedia.org/wiki/If_and_only_if&quot;&gt;if and only if&lt;/a&gt; they give the same result for all arguments. It converts between λx.(f x) and f whenever x does not appear free in f. Here is an example in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isEven = x =&amp;gt; x % 2 == 0;
Enumerable.Range(0, 5).Where(x =&amp;gt; isEven(x)).ForEach(x =&amp;gt; Console.WriteLine(x));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be reduced to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Enumerable.Range(0, 5).Where(isEven).ForEach(Console.WriteLine);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here x =&amp;gt; isEven(x) and isEven are the same, and x =&amp;gt; Console.WriteLine(x) and Console.WriteLine are the same too (C# compiler will pickup the right overload - Console.WriteLine(int value)).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus#Reduction_strategies&quot;&gt;Different reduction order&lt;/a&gt; can be applied to the same lambda expression and have &lt;a href=&quot;http://en.wikipedia.org/wiki/Evaluation_strategy&quot;&gt;different impact&lt;/a&gt;. This will be demonstrated in &lt;a href=&quot;/posts/lambda-calculus-via-c-sharp-6-if-logic-and-reduction-strategies&quot;&gt;a later part&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/52298759@N04/4889071497&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-1-Fundamental---Cl_1274C/4889071497_7ee9f43a08_b_3.jpg&quot; alt=&quot;4889071497_7ee9f43a08_b&quot; title=&quot;4889071497_7ee9f43a08_b&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Lambda Calculus via C# (1) Fundamentals - Closure, Currying and Partial Application</title><link>https://dixin.github.io/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application/</link><guid isPermaLink="true">https://dixin.github.io/posts/lambda-calculus-via-c-sharp-1-fundamentals-closure-currying-and-partial-application/</guid><description>C#  is discussed in detail used everywhere in the . This post and the follo</description><pubDate>Thu, 01 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Lambda%20Calculus&quot;&gt;Lambda Calculus via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/lambda-calculus-via-c-1-fundamentals&quot;&gt;https://weblogs.asp.net/dixin/lambda-calculus-via-c-1-fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;C# &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;lambda expression&lt;/a&gt; is discussed in detail used everywhere in the &lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;. This post and the following few posts will focus on functions and disregard lambda expression for &lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;expression tree&lt;/a&gt;. These articles will be a deeper dive about &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;lambda expression&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; - how it comes, what it does, and &lt;a href=&quot;http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf&quot;&gt;why it matters&lt;/a&gt;. And - functions and anonymous functions will always be the only primitive.&lt;/p&gt;
&lt;h2&gt;About lambda calculus (λ-calculus)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.spreadshirt.com/lambda-calculus-college-t-shirt-C3376A5017163#/detail/5017163T812A231PC121706255PA1663&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-1_CA43/Lambda-Calculus_3.png&quot; alt=&quot;Lambda-Calculus&quot; title=&quot;Lambda-Calculus&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;Lambda calculus&lt;/a&gt; is a formal system to use functions and function application to express computation. Lambda calculus is &lt;a href=&quot;http://en.wikipedia.org/wiki/Turing_completeness&quot;&gt;Turing complete&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In C#, lambda is a fancy feature introduced in 3.0. Actually it is introduced as early as 1930s by &lt;a href=&quot;http://en.wikipedia.org/wiki/Alonzo_Church&quot;&gt;Alonzo Church&lt;/a&gt;, the doctoral advisor of &lt;a href=&quot;http://en.wikipedia.org/wiki/Alan_Turing&quot;&gt;Alan Turing&lt;/a&gt;. Later Alan Turing showed Turing machines equated the lambda calculus in expressiveness. This series will try to use C# functions to demonstrate how lambda expressions model the computation.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/52298759@N04/4889071497&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Lambda-Calculus-via-C-1-Fundamental---Cl_1274C/4889071497_7ee9f43a08_b_3.jpg&quot; alt=&quot;4889071497_7ee9f43a08_b&quot; title=&quot;4889071497_7ee9f43a08_b&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Closure&lt;/h2&gt;
&lt;p&gt;All stories can start with a simple concept, &lt;a href=&quot;http://en.wikipedia.org/wiki/Closure_(computer_programming)&quot;&gt;closure&lt;/a&gt;. Closure has been explained when discussing C# features in a previous chapter. It is actually a general concept that, in lambda calculus, any function can reference a &lt;a href=&quot;https://en.wikipedia.org/wiki/Non-local_variable&quot;&gt;non-local variable&lt;/a&gt;,&lt;/p&gt;
&lt;h2&gt;Currying and partial application&lt;/h2&gt;
&lt;p&gt;Looking at this simple function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int&amp;gt; add = 
    (x, y) =&amp;gt; x + y;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Straightforward. It represents an algorithm to add 2 integers. In C#, it is a function of type Func&amp;lt;int, int, int&amp;gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The function takes 2 integer parameters as input (on the left side of =&amp;gt;)&lt;/li&gt;
&lt;li&gt;The function returns the sum of those 2 integers as output (on the right side of =&amp;gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since C# supports closure and higher-order function, above function can be tweaked a little bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd =
    x =&amp;gt; new Func&amp;lt;int, int&amp;gt;(y =&amp;gt; x + y);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It represents an algorithm which eventually still adds 2 integers. The different is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The function takes 1 integer parameter as input (on the left side of first =&amp;gt;)&lt;/li&gt;
&lt;li&gt;The function returns a function as output (on the right side of first =&amp;gt;).
&lt;ul&gt;
&lt;li&gt;The returned function takes 1 integer parameter as input (on the left side of second =&amp;gt;)&lt;/li&gt;
&lt;li&gt;The returned function the sum of those 2 integers as output (on the left side of second =&amp;gt;). Here x + y uses closure to reference x, which is out of the returned function (y =&amp;gt; x + y).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C# the returned function’s type declaration, new Func&amp;lt;int, int&amp;gt;(…), can be inferred by compiler. So it can be written cleaner:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd =
    x =&amp;gt; y =&amp;gt; x + y;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The add function’s application is also straightforward :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = add(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or just keep the code in lambda style - function should be anonymous without name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;result = new Func&amp;lt;int, int, int&amp;gt;((x, y) =&amp;gt; x + y)(1, 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second function’s application is different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int&amp;gt; add1 = curriedAdd(1); // Or: new Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;(x =&amp;gt; y =&amp;gt; x + y)(1);
// Now add1 is s closure: y =&amp;gt; 1 + y.
result = add1(2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So after the function transforming, the function application add(1, 2) becomes curriedAdd(1)(2). This approach, to transform a function with 2 parameters into a sequence of 2 functions where each function has 1 parameter, is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Currying&quot;&gt;currying&lt;/a&gt;. The application of one argument to a curried function, is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Partial_application&quot;&gt;partial application&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, the following function with 3 parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; add = (x, y, z) =&amp;gt; x + y + z;
int result = add(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be curried as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd = x =&amp;gt; y =&amp;gt; z =&amp;gt; x + y + z;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the curried function can be partially applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; add1 = curriedAdd(1); // add1 is a closure: y =&amp;gt; z =&amp;gt; 1 + y + z
Func&amp;lt;int, int&amp;gt; add3 = add1(2); // add3 is a closure: z =&amp;gt; 1 + 2 + z
result = add3(3);
// Or just:
result = curriedAdd(1)(2)(3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More generally, any function with N parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, T2, …, TN, TResult&amp;gt; function = (arg1, arg2, …, argN) =&amp;gt; result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be curried into a function sequence of N functions, and each function has 1 parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, Func&amp;lt;T2, …, Func&amp;lt;TN, TResult&amp;gt;…&amp;gt;&amp;gt; curriedFunction = arg1 =&amp;gt; arg2 =&amp;gt; … =&amp;gt; argN =&amp;gt; result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be implemented with some Curry() extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    // from arg =&amp;gt; result
    // to () =&amp;gt; arg =&amp;gt; result
    public static Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt; Curry&amp;lt;T, TResult&amp;gt;
        (this Func&amp;lt;T, TResult&amp;gt; function) =&amp;gt; 
            () =&amp;gt; arg =&amp;gt; function(arg);

    // from (arg1, arg2) =&amp;gt; result
    // to arg1 =&amp;gt; arg2 =&amp;gt; result
    public static Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, TResult&amp;gt; function) =&amp;gt; 
            arg1 =&amp;gt; arg2 =&amp;gt; function(arg1, arg2);

    // from (arg1, arg2, arg3) =&amp;gt; result
    // to arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; result
    public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function) =&amp;gt; 
            arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; function(arg1, arg2, arg3);

    // from (arg1, arg2, arg3, arg4) =&amp;gt; result
    // to arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; arg4 =&amp;gt; result
    public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;
        (this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function) =&amp;gt; 
            arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; arg4 =&amp;gt; function(arg1, arg2, arg3, arg4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the same idea as currying, we can also partially apply a function with multiple parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static Func&amp;lt;TResult&amp;gt; Partial&amp;lt;T, TResult&amp;gt;(
        this Func&amp;lt;T, TResult&amp;gt; function, T arg)
    {
        return () =&amp;gt; function(arg);
    }

    public static Func&amp;lt;T2, TResult&amp;gt; Partial&amp;lt;T1, T2, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, TResult&amp;gt; function, T1 arg1)
    {
        return arg2 =&amp;gt; function(arg1, arg2);
    }

    public static Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function, T1 arg1)
    {
        return arg2 =&amp;gt; arg3 =&amp;gt; function(arg1, arg2, arg3);
    }

    public static Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function, T1 arg1)
    {
        return arg2 =&amp;gt; arg3 =&amp;gt; arg4 =&amp;gt; function(arg1, arg2, arg3, arg4);
    }

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, int, int, int&amp;gt; add = (x, y, z) =&amp;gt; x + y + z;
var add4 = add.Partial(4); // add4 is a closure: y =&amp;gt; z =&amp;gt; 4 + y + z
int result = add.Partial(1)(2)(3);
// is a short cut of:
result = add.Curry()(1)(2)(3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The name &quot;currying&quot; is introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Christopher_Strachey&quot;&gt;Christopher Strachey&lt;/a&gt; in 1967. It is the last name of &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All the later parts of lambda calculus will focus on curried functions (1 parameter function or function sequence). Currying may cause some noise for &lt;a href=&quot;/posts/understanding-csharp-3-0-features-3-type-inference&quot;&gt;type inference in C#&lt;/a&gt;, which will be demonstrated in a later part of Church pair (2-tuple).&lt;/p&gt;
&lt;h2&gt;Uncurry&lt;/h2&gt;
&lt;p&gt;Just for fun purpose - a sequence of 1 parameter functions can also be uncurried to a function with multiple parameters too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    // from () =&amp;gt; arg =&amp;gt; result
    // to arg =&amp;gt; result
    public static Func&amp;lt;T, TResult&amp;gt; Uncurry&amp;lt;T, TResult&amp;gt;
        (this Func&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt; function) =&amp;gt; 
            arg =&amp;gt; function()(arg);

    // from arg1 =&amp;gt; arg2 =&amp;gt; result
    // to (arg1, arg2) =&amp;gt; result
    public static Func&amp;lt;T1, T2, TResult&amp;gt; Uncurry&amp;lt;T1, T2, TResult&amp;gt;
        (this Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; function) =&amp;gt; 
            (arg1, arg2) =&amp;gt; function(arg1)(arg2);

    // from arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; result
    // to (arg1, arg2, arg3) =&amp;gt; result
    public static Func&amp;lt;T1, T2, T3, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, TResult&amp;gt;
        (this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt; 
            (arg1, arg2, arg3) =&amp;gt; function(arg1)(arg2)(arg3);

    // from arg1 =&amp;gt; arg2 =&amp;gt; arg3 =&amp;gt; arg4 =&amp;gt; result
    // to (arg1, arg2, arg3, arg4) =&amp;gt; result
    public static Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;
        (this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt; 
            (arg1, arg2, arg3, arg4) =&amp;gt; function(arg1)(arg2)(arg3)(arg4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;=&amp;gt; associativity&lt;/h2&gt;
&lt;p&gt;From above code, the C# lambda operator (=&amp;gt;) is apparently &lt;a href=&quot;http://en.wikipedia.org/w/index.php?title=Right-associative&amp;amp;redirect=no&quot;&gt;right-associative&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;x =&amp;gt; y =&amp;gt; x + y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is identical to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;x =&amp;gt; (y =&amp;gt; x + y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or generally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, Func&amp;lt;T2, …, Func&amp;lt;TN, TResult&amp;gt;…&amp;gt;&amp;gt; curriedFunction = arg1 =&amp;gt; arg2 =&amp;gt; … =&amp;gt; argN =&amp;gt; result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is identical to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;T1, Func&amp;lt;T2, …, Func&amp;lt;TN, TResult&amp;gt;…&amp;gt;&amp;gt; curriedFunction = arg1 =&amp;gt; (arg2 =&amp;gt; … =&amp;gt; (argN =&amp;gt; result)…);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the same associativity as the &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_constructor&quot;&gt;type constructor →&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Simply_typed_lambda_calculus&quot;&gt;typed lambda calculus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In some functional languages, functions are curried by default, like F#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let f1: int -&amp;gt; int -&amp;gt; int = fun x y -&amp;gt; x + y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fun x y -&amp;gt; … looks like a function definition with multiple parameters, but it is curried as int -&amp;gt; int -&amp;gt; int. This function works similar as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let f2: int -&amp;gt; (int -&amp;gt; int) = fun x -&amp;gt; fun y -&amp;gt; x + y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how to create an uncurried function with multiple parameters in F#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let f3: int * int -&amp;gt; int = fun (x, y) -&amp;gt; x + y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here multiple parameters are implemented with a tuple of int and int.&lt;/p&gt;
&lt;p&gt;In other functional languages, like &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt; (that is the first name of &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;), functions are always curried.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework Core and LINQ to Entities (9) Performance</title><link>https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-9-performance/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-core-and-linq-to-entities-9-performance/</guid><description>The previous parts has discussed some aspects that can impact the performance of EF/Core and LINQ to Entities, and here is a summary:</description><pubDate>Tue, 30 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;EF version of this article: &lt;a href=&quot;/posts/entity-framework-and-linq-to-entities-10-performance&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-and-linq-to-entities-10-performance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous parts has discussed some aspects that can impact the performance of EF/Core and LINQ to Entities, and here is a summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remote LINQ to Entities query can have better performance than local or hybrid query. An intuitive example is Last query for a table data source, which could query the entire table, load data to local, and query the last result locally. It is better to just have a remote query and only load the specific result.&lt;/li&gt;
&lt;li&gt;Using Select to only query the data can have better performance than querying full entity.&lt;/li&gt;
&lt;li&gt;Disabling entity tracking can improve the performance.&lt;/li&gt;
&lt;li&gt;Disabling automatic change detection can improve the performance.&lt;/li&gt;
&lt;li&gt;When adding a sequence of entities to repository, DbSet&amp;lt;T&amp;gt;.AddRange/DbSet&amp;lt;T&amp;gt;.RemoveRange call can have better performance than many DbSet&amp;lt;T&amp;gt;.Add/DbSet&amp;lt;T&amp;gt;.Remove calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;And, in EF, with lazy loading, accessing an entity’s navigation property can cause additional database query round trips (the N + 1 queries problem). Eager loading can improve the performance by read all needed data with 1 single database query.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This part continues the discussion of performance.&lt;/p&gt;
&lt;h2&gt;Initialization&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;EF dies a lot of initialization work before the first database query is executed.&lt;/p&gt;
&lt;p&gt;The following example simply pulls categories from the repository, with one LINQ to Entities query:’&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Performance
{
    internal static void Initialize()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories;
            categories.WriteLines(category =&amp;gt; category.Name);
            // select cast(serverproperty(&apos;EngineEdition&apos;) as int)

            // SELECT Count(*)
            // FROM INFORMATION_SCHEMA.TABLES AS t
            // WHERE t.TABLE_SCHEMA + &apos;.&apos; + t.TABLE_NAME IN (&apos;HumanResources.Employee&apos;,&apos;Person.Person&apos;,&apos;Production.ProductCategory&apos;,&apos;Production.ProductSubcategory&apos;,&apos;Production.Product&apos;,&apos;Production.ProductProductPhoto&apos;,&apos;Production.ProductPhoto&apos;,&apos;Production.TransactionHistory&apos;,&apos;HumanResources.vEmployee&apos;) 
            //    OR t.TABLE_NAME = &apos;EdmMetadata&apos;
            // exec sp_executesql N&apos;SELECT 
            //    [GroupBy1].[A1] AS [C1]
            //    FROM ( SELECT 
            //        COUNT(1) AS [A1]
            //        FROM [dbo].[__MigrationHistory] AS [Extent1]
            //        WHERE [Extent1].[ContextKey] = @p__linq__0
            //    )  AS [GroupBy1]&apos;,N&apos;@p__linq__0 nvarchar(4000)&apos;,@p__linq__0=N&apos;AdventureWorks&apos;
            // SELECT 
            //    [GroupBy1].[A1] AS [C1]
            //    FROM ( SELECT 
            //        COUNT(1) AS [A1]
            //        FROM [dbo].[__MigrationHistory] AS [Extent1]
            //    )  AS [GroupBy1]
            // SELECT TOP (1) 
            //    [Extent1].[Id] AS [Id], 
            //    [Extent1].[ModelHash] AS [ModelHash]
            //    FROM [dbo].[EdmMetadata] AS [Extent1]
            //    ORDER BY [Extent1].[Id] DESC
            // SELECT 
            //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
            //    [Extent1].[Name] AS [Name]
            //    FROM [Production].[ProductCategory] AS [Extent1]
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing above code, a bunch of SQL queries can be traced. And only the last SELECT query is the expected LINQ to Entities query translation. Actually, before a database’s first operation at runtime (e.g., querying Production.ProductCategory table here), EF does a lot of work to initialize its object-relational mapping:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize provider manifest&lt;/li&gt;
&lt;li&gt;Initialize the entity data model. EF automatically builds the object models (CLR models, not above entities), conceptual models, storage models, object-conceptual model mappings, conceptual-storage model mappings, etc..&lt;/li&gt;
&lt;li&gt;Initialize the database, if needed.&lt;/li&gt;
&lt;li&gt;Initialize mapping views, which are the mapping information for entity sets.&lt;/li&gt;
&lt;li&gt;Initialize a dynamic assembly &quot;EntityFrameworkDynamicProxies-{OriginalAssemblyName}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot;, and define proxy types in it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above initialization steps executes only once at runtime, and their performance can be improved from the default behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Provider initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;As fore mentioned, EF implements the provider model to work with different kinds of data stores, and it need to get the basic information of current data store. For SQL database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The SQL database server’s version is detected by calling DbConnection.ServerVersion&lt;/li&gt;
&lt;li&gt;The engine edition is queried by above &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms174396.aspx&quot;&gt;SERVERPROPERTY&lt;/a&gt; metadata function, to determine whether it is a on premise database (SQL Server) or cloud database (SQL Azure, aka Azure SQL Database).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For SQL database, the supported provider manifest tokens are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer
{
    internal class SqlProviderManifest : DbXmlEnabledProviderManifest
    {
        internal const string TokenSql8 = &quot;2000&quot;;

        internal const string TokenSql9 = &quot;2005&quot;;

        internal const string TokenSql10 = &quot;2008&quot;;

        internal const string TokenSql11 = &quot;2012&quot;;

        internal const string TokenAzure11 = &quot;2012.Azure&quot;;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For any on premise SQL database later than 11.0, just use “2012”. For cloud SQL database, use “2012.Azure”. In this tutorial, the server version and engine edition is known. So these information can be provided to EF via System.Data.Entity.Infrastructure.IManifestTokenResolver:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SqlConfiguration : DbConfiguration
{
    public SqlConfiguration() =&amp;gt;
            this.SetManifestTokenResolver(new SqlManifestTokenResolver());
}

public class SqlManifestTokenResolver : IManifestTokenResolver
{
    public string ResolveManifestToken(DbConnection connection) =&amp;gt; &quot;2012.Azure&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then engine edition query is not executed during initialization. Notice EF only support defining a single type derived from DbConfiguration. In the object-relational mapping part, there us already a RetryConfiguration type defined to specify the retry strategy. The logic in both types must be merged intto one type, otherwise EF throws exception during initialization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Database initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The database initialization work is represented by System.Data.Entity.IDatabaseInitializer&amp;lt;TContext&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public interface IDatabaseInitializer&amp;lt;in TContext&amp;gt; where TContext : DbContext
    {
        void InitializeDatabase(TContext context);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF provides several built-in initializers under System.Data.Entity namespace:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NullDatabaseInitializer&amp;lt;TContext&amp;gt;: Do nothing for initialization&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseAlways&amp;lt;TContext&amp;gt;: Always drop the database and create again&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseIfModelChanges&amp;lt;TContext&amp;gt;: Drop and create database when the code mapping mismatches database schema.&lt;/li&gt;
&lt;li&gt;MigrateDatabaseToLatestVersion&amp;lt;TContext, TMigrationsConfiguration&amp;gt;: Use the specified code to update the database to the latest version.&lt;/li&gt;
&lt;li&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: Create database if not exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: is the default initializer, so it is executed here too. As a result, EF attempts to &lt;a href=&quot;https://romiller.com/2014/06/10/reducing-code-first-database-chatter/&quot;&gt;query the existence of the mapped tables and views, database migration history, and entity data model info, etc&lt;/a&gt;. Apparently, here AdventureWorks database does not have the migration and entity data model info; recreating database is not needed as well. So the database initialization can be turned off, by setting the initializer to NullDatabaseInitializer&amp;lt;TContext&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    static AdventureWorks()
    {
        Database.SetInitializer(new NullDatabaseInitializer&amp;lt;AdventureWorks&amp;gt;()); // Call once.
        // Equivalent to: Database.SetInitializer&amp;lt;AdventureWorks&amp;gt;(null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where NullDatabaseInitializer&amp;lt;TContext&amp;gt; provide empty operation that does nothing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class NullDatabaseInitializer&amp;lt;TContext&amp;gt; : IDatabaseInitializer&amp;lt;TContext&amp;gt; where TContext : DbContext
    {
        public virtual void InitializeDatabase(TContext context)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all the additional database queries for initialization are turned off.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Mapping views initialization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, mapping views are not the views inside the database. They are System.Data.Entity.Infrastructure.MappingViews.DbMappingView instances, representing the mapping information for entity sets. Instead of generate these instances at runtime, pre-generate them at design time can improve the performance. Microsoft provides a Visual Studio extension, EF Power Tools, to generate these code. It needs to be &lt;a href=&quot;http://thedatafarm.com/data-access/installing-ef-power-tools-into-vs2015/&quot;&gt;modified&lt;/a&gt; to installed with the latest Visual Studio. After the installation, just right click the code file containing the database mapping (the class derived from DbContext), and in the menu click EF =&amp;gt; Generate Views, it generates a file, containing the code to create the DbMappingView instances.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Cache&lt;/h2&gt;
&lt;p&gt;After the object-relational mapping metadata is initialized, they are cached, so that the initialization only happens once for the AppDomain. EF/Core also implement cache for entities and query translation.&lt;/p&gt;
&lt;h3&gt;Entity cache&lt;/h3&gt;
&lt;p&gt;As fore mentioned, by default, the entities queried from repository are cached and tracked. This behavior can be demonstrated by the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CachedEntity(AdventureWorks adventureWorks)
{
    ProductCategory categoryCopy1 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
    categoryCopy1.Name = &quot;Cache&quot;;

    ProductCategory categoryCopy2 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
    categoryCopy2.Name.WriteLine(); // Cache
    object.ReferenceEquals(categoryCopy1, categoryCopy2).WriteLine(); // True

    ProductCategory categoryCopy3 = adventureWorks.ProductCategories
#if EF
        .SqlQuery(
#else
        .FromSql(
#endif
            @&quot;SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy3).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the first query reads data from the repository and materialize the data to a category entity, and update its Name. Then the repository is queried again by Name. After reading the data, EF/Core find the primary key is the same as the cached entity, so EF/Core do not materialize the data just read, it reuses the previous category entity. Performance can be improved by skipping the materialization, but tricky result can happen. The second query reads entity with Name “Bikes”, but the query result entity has Name “Cache”. This is not only LINQ to Entities queries’ behavior, When DbSet&amp;lt;T&amp;gt; directly executes SQL query in the repository, EF/Core still uses cached entities.&lt;/p&gt;
&lt;p&gt;Entity is not cached when tracking is turned off, or entity is not queried from the repository. Each of the following queries materializes a new entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UncachedEntity(AdventureWorks adventureWorks)
{
    ProductCategory categoryCopy1 = adventureWorks.ProductCategories
        .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
    categoryCopy1.Name = &quot;Cache&quot;;

    ProductCategory categoryCopy2 = adventureWorks.ProductCategories
        .AsNoTracking().Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
    categoryCopy2.Name.WriteLine(); // Bikes
    object.ReferenceEquals(categoryCopy1, categoryCopy2).WriteLine(); // False

    ProductCategory categoryCopy3 = adventureWorks.ProductCategories
#if EF
        .SqlQuery(
#else
        .FromSql(
#endif
            @&quot;SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .AsNoTracking()
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy3).WriteLine(); // False

#if EF
    ProductCategory categoryCopy4 = adventureWorks.Database
        .SqlQuery&amp;lt;ProductCategory&amp;gt;(@&quot;
            SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
            FROM [Production].[ProductCategory]
            ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
        .Single();
    object.ReferenceEquals(categoryCopy1, categoryCopy4).WriteLine(); // False
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbSet.Find accept the primary keys and returns an entity. Calling Find can improve the performance, because it looks up cache before querying the repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Find(AdventureWorks adventureWorks)
{
    Product[] products = adventureWorks.Products
        .Where(entity =&amp;gt; entity.Name.StartsWith(&quot;Road&quot;)).ToArray(); // Execute query.
    Product product = adventureWorks.Products.Find(999); // No database query.
    object.ReferenceEquals(products.Last(), product).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here when Find is called, entity with the specified primary key is already queries, cached and tracked, so Find directly returns the cached entity, without repository query or data materialization.&lt;/p&gt;
&lt;h3&gt;LINQ query translation cache&lt;/h3&gt;
&lt;p&gt;As discussed in the query translation part, EF/Core translate a LINQ to Entities query in 2 steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compile LINQ expression tree to database expression tree&lt;/li&gt;
&lt;li&gt;Generate SQL from database expression tree&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To improve the performance, EF Core caches the query translations in a Microsoft.Extensions.Caching.Memory.MemoryCache. Before processing a LINQ query, EF Core computes the cache key, and looks up the cache. If the translation is found, then it reuses the translation; if not, it translates the query, and add the translation to cache.. For SQL database queries, the cache key’s hash code is computed with the the hash code of the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The LINQ query expression tree. The LINQ query expression tree is scanned recursively, the hash code of the nodes and APIs represented by the expression tree nodes are used to compute the hash code of the entire expression tree.&lt;/li&gt;
&lt;li&gt;DbContext.Model&lt;/li&gt;
&lt;li&gt;DbContext.ChangeTracker.QueryTrackingBehavior, which is an enumeration of TrackAll or NoTracking&lt;/li&gt;
&lt;li&gt;A Boolean value that indicates whether the query is executed asynchronously&lt;/li&gt;
&lt;li&gt;SqlServerOptionsExtension.UseRelationalNulls, which can be specified with SqlServerDbContextOptionsBuilder.UseRelationalNulls&lt;/li&gt;
&lt;li&gt;SqlServerOptionsExtension.RowNumberPaging, which can be specified with SqlServerDbContextOptionsBuilder.UseRowNumberForPaging&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EF always compiles the LINQ expression tree to database expression tree, then cache the SQL generation in a dictionary. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; query = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength)
        .Include(product =&amp;gt; product.ProductSubcategory);
    query.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EF generates the cache key with the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The database expression tree’s string representation. Here it is: [Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.Products:Transient.collection[Product(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),@p__linq__0:Edm.Int32(Nullable=False,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;The parameters’ string representation: @@1p__linq__0:System.Int32&lt;/li&gt;
&lt;li&gt;The path of the Include query. Here it is ProductSubcategory&lt;/li&gt;
&lt;li&gt;The query’s MergeOption, which is AppendOnly by default.&lt;/li&gt;
&lt;li&gt;System.Data.Entity.Core.Objects.ObjectContextOptions.UseCSharpNullComparisonBehavior&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The following example executes 2 LINQ to Entities queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UnreusedTranslationCache(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;Product&amp;gt; queryWithConstant1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= 1);
    queryWithConstant1.Load();

    IQueryable&amp;lt;Product&amp;gt; queryWithConstant2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= 10);
    queryWithConstant2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These first LINQ query builds expression trees with a ConstantExpression node representing int value 1. The second query builds similar expression tree but with a different ConstantExpression node representing int value 10. So these LINQ expression trees are different. In EF Core, the first expression tree’s translation cannot be reused for the second query.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, their compiled database expression trees are different too, with 2 different DbConstantExpression nodes. The 2 database expression trees’ string representations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),1:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),10:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the first query’s SQL generation cannot be used for the second query either.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To reuse the translation cache, these queries can be parameterized by simply replace the constants with variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReusedTranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure1.Load();

    minLength = 10;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the C# features chapter, the predicate lambda expressions capture variable minLength with the closure syntactic sugar. The above code is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReusedTranslationCache(AdventureWorks adventureWorks)
{
    int minLength = 1;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure1 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure1.Load();

    minLength = 10;
    IQueryable&amp;lt;Product&amp;gt; queryWithClosure2 = adventureWorks.Products
        .Where(product =&amp;gt; product.Name.Length &amp;gt;= minLength);
    queryWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the predicates, the outer variable access is compiled to field access. So in the LINQ queries’ expression trees, there are no longer ConstantExpression nodes representing different int values, but MemberExpression nodes representing the same field. As a result, the 2 query’s LINQ expression trees are identical, and the translation is reused.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, if a query method accepts values instead of lambda expression, this parameterization approach does not work. For example, Skip and Take accept int values as parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UnresuedSkipTakeTranslationCache(AdventureWorks adventureWorks)
{
    int skip = 1;
    int take = 1;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithVariable1 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(skip).Take(take);
    skipTakeWithVariable1.Load();

    skip = 10;
    take = 10;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithVariable2 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(skip).Take(take);
    skipTakeWithVariable2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above LINQ queries access to variable skip and take, but these variable access are also represented by ConstantExpression nodes. So their expression trees are different, and converted database command trees are different, and their translations cannot be reused for each other. To resolve this problem, EF provides a lambda expression version for these methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public static class QueryableExtensions
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);

        public static IQueryable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Skip and Take can access variables via closure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ResuedSkipTakeTranslationCache(AdventureWorks adventureWorks)
{
    int skip = 1;
    int take = 1;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithClosure1 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
    skipTakeWithClosure1.Load();

    skip = 10;
    take = 10;
    IQueryable&amp;lt;Product&amp;gt; skipTakeWithClosure2 = adventureWorks.Products
        .OrderBy(product =&amp;gt; product.ProductID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
    skipTakeWithClosure2.Load();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These LINQ queries have MemberExpression nodes again. EF can convert them to identical parameterized database expression trees. Now their translations can be reused for each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;SQL query plan cache&lt;/h3&gt;
&lt;p&gt;LINQ queries with different constants are translated to different SQL queries. Above queryWithConstant1 and queryWithConstant2 are translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= 1

SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently they have different query plans in SQL database, which cannot be reused for each other:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-9-_9F66/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-9-_9F66/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With parameterization, queryWithClosure1 and queryWithClosure2 are translated to identical SQL queries, with different parameter values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= @__minLength_0&apos;,N&apos;@__minLength_0 int&apos;,@__minLength_0=1

exec sp_executesql N&apos;SELECT [product].[ProductID], [product].[ListPrice], [product].[Name], [product].[ProductSubcategoryID], [product].[RowVersion]
FROM [Production].[Product] AS [product]
WHERE LEN([product].[Name]) &amp;gt;= @__minLength_0&apos;,N&apos;@__minLength_0 int&apos;,@__minLength_0=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in SQL database, queryWithClosure1’s query plan is cached and reused for queryWithClosure2:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-9-_9F66/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-9-_9F66/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Asynchrony&lt;/h2&gt;
&lt;p&gt;Generally, for long running I/O bound operation, asynchrony can improve the application responsiveness and service scalability. EF/Core support asynchrony for database CRUD operations, and these async APIs are very easy to use with C# async/await keywords. Please notice this does not mean all the synchronous API calls must be replaced by asynchronous API calls, the application must be tested to identify which API has better performance.&lt;/p&gt;
&lt;h3&gt;Asynchronous data queries and data changes&lt;/h3&gt;
&lt;p&gt;For LINQ to Entities queries, EF/Core start to read the data when values are pulled from IQueryable&amp;lt;T&amp;gt; data source, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull the values from the query represented by IQueryable&amp;lt;T&amp;gt;.&lt;/li&gt;
&lt;li&gt;Call a query method to return a single value from the IQueryable&amp;lt;T&amp;gt;, like First, etc..&lt;/li&gt;
&lt;li&gt;Call a LINQ to Objects query method to return a new collection, like ToArray, etc..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For these operations and APIs, async parities are provided as IQueryable&amp;lt;T&amp;gt; extension methods. In EF Core, these async query APIs are also provided as extension methods in Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;async iteration method: ForEachAsync asynchronously pulls each value from IQueryable&amp;lt;T&amp;gt; data source and call the specified function.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;async methods to return a single value:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Element: FirstAsync, FirstOrDefaultAsync, LastAsync, LastOrDefaultAsync, SingleAsync, SingleOrDefaultAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: CountAsync, LongCountAsync, MinAsync, MaxAsync, SumAsync, AverageAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quantifier: AllAsync, AnyAsync, ContainsAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;async methods to return a new collection: ToArrayAsync, ToDictionaryAsync, ToListAsync&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;In EF, these methods are provided in System.Data.Entity.QueryableExtensions, and LastAsync, LastOrDefaultAsync are not provided, since EF does not support Last, LastOrDefault.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For data changes, DbContext.SaveChangesAsync is provided as a parity of DbContext.SaveChanges. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task Async(AdventureWorks adventureWorks)
{
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories;
    await categories.ForEachAsync( // Async version of foreach/ForEach.
        category =&amp;gt; category.Name.WriteLine());

    ProductSubcategory subcategory = await adventureWorks.ProductSubcategories
        .FirstAsync(entity =&amp;gt; entity.Name.Contains(&quot;Bike&quot;)); // Async version of First.
    subcategory.Name.WriteLine();

    Product[] products = await adventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt;= 10)
        .ToArrayAsync(); // Async version of ToArray.

    adventureWorks.Products.RemoveRange(products);
    (await adventureWorks.SaveChangesAsync()).WriteLine(); // Async version of SaveChanges.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Transactions and connection resiliency with asynchronous operations&lt;/h3&gt;
&lt;p&gt;These async APIs work in EF/Core transaction. In this tutorial, connection resiliency is enabled because cloud SQL database is used, so call the retry strategy’s ExecuteAsync method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task DbContextTransactionAsync(AdventureWorks adventureWorks)
{
    await adventureWorks.Database.CreateExecutionStrategy().ExecuteAsync(async () =&amp;gt;
    {
#if EF
        using (IDbContextTransaction transaction = adventureWorks.Database.BeginTransaction(
#else
        using (IDbContextTransaction transaction = await adventureWorks.Database.BeginTransactionAsync(
#endif
            IsolationLevel.ReadUncommitted))
        {
            try
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // ReadUncommitted

                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
#if EF
                adventureWorks.ProductCategories.Add(category);
#else
                await adventureWorks.ProductCategories.AddAsync(category);
#endif
                (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1

                await adventureWorks.Database.ExecuteSqlCommandAsync(
                    sql: &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {0}&quot;,
                    parameters: nameof(ProductCategory)).WriteLine(); // 1
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These async APIs also work in ADO.NET transaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task DbTransactionAsync()
{
    using (SqlConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
    {
        await connection.OpenAsync();
        using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
        {
            try
            {
                using (AdventureWorks adventureWorks = new AdventureWorks(connection))
                {
                    await adventureWorks.Database.CreateExecutionStrategy().ExecuteAsync(async () =&amp;gt;
                    {
                        adventureWorks.Database.UseTransaction(transaction);
                        adventureWorks.CurrentIsolationLevel().WriteLine(); // Serializable

                        ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
#if EF
                        adventureWorks.ProductCategories.Add(category);
#else
                        await adventureWorks.ProductCategories.AddAsync(category);
#endif
                        (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1.
                    });
                }

                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                    DbParameter parameter = command.CreateParameter();
                    parameter.ParameterName = &quot;@p0&quot;;
                    parameter.Value = nameof(ProductCategory);
                    command.Parameters.Add(parameter);
                    command.Transaction = transaction;
                    (await command.ExecuteNonQueryAsync()).WriteLine(); // 1
                }
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TransactionScope by default does not support across thread transaction flow. Using the the async/await syntactic sugar for TransactionScope causes InvalidOperationException: A TransactionScope must be disposed on the same thread that it was created.. To resolved this, Since .NET 4.5.1, a new constructor for TransactionScope is provided to explicitly enable transaction flow across thread continuations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task TransactionScopeAsync()
{
    await new ExecutionStrategy().ExecuteAsync(async () =&amp;gt;
    {
        using (TransactionScope scope = new TransactionScope(
            scopeOption: TransactionScopeOption.Required,
            transactionOptions: new TransactionOptions()
            {
                IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead
            },
            asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
        {
            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = DbContextExtensions.CurrentIsolationLevelSql;
                await connection.OpenAsync();
                using (DbDataReader reader = await command.ExecuteReaderAsync())
                {
                    await reader.ReadAsync();
                    reader[0].WriteLine(); // RepeatableRead
                }
            }

            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                adventureWorks.ProductCategories.Add(category);
                (await adventureWorks.SaveChangesAsync()).WriteLine(); // 1
            }

            using (AdventureWorks adventureWorks = new AdventureWorks())
            {
                adventureWorks.CurrentIsolationLevel().WriteLine(); // RepeatableRead
            }

            using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
            using (DbCommand command = connection.CreateCommand())
            {
                command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                DbParameter parameter = command.CreateParameter();
                parameter.ParameterName = &quot;@p0&quot;;
                parameter.Value = nameof(ProductCategory);
                command.Parameters.Add(parameter);

                await connection.OpenAsync();
                (await command.ExecuteNonQueryAsync()).WriteLine(); // 1
            }

            scope.Complete();
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Asynchronous concurrent conflicts&lt;/h3&gt;
&lt;p&gt;EF/Core also provide async APIs for other database operations. In the previous concurrency part, a DbContext.SaveChanges overload is implemented to handle concurrency conflict, refresh entity, and retry saving changes. Here a async version can be implemented easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, int retryCount = 3)
    {
        if (retryCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryCount));
        }

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return await context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                await resolveConflictsAsync(exception.Entries);
            }
        }
        return await context.SaveChangesAsync();
    }

    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;EntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, RetryStrategy retryStrategy)
    {
        RetryPolicy retryPolicy = new RetryPolicy(
            new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(), retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt;
            resolveConflictsAsync(((DbUpdateConcurrencyException)e.LastException).Entries).Wait();
        return await retryPolicy.ExecuteAsync(async () =&amp;gt; await context.SaveChangesAsync());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the async/await syntactic sugar, the implementation looks very similar to the synchronous version. The following are the SaveChangesAsync overloads to accept RefreshConflict enumeration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
    this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
{
    if (retryCount &amp;lt;= 0)
    {
        throw new ArgumentOutOfRangeException(nameof(retryCount));
    }

    return await context.SaveChangesAsync(
        async conflicts =&amp;gt; await Task.WhenAll(conflicts.Select(async tracking =&amp;gt;
            await tracking.RefreshAsync(refreshMode))),
        retryCount);
}

public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
    this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =&amp;gt;
        await context.SaveChangesAsync(
            async conflicts =&amp;gt; await Task.WhenAll(conflicts.Select(async tracking =&amp;gt;
                await tracking.RefreshAsync(refreshMode))),
            retryStrategy);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of calling the previously defined Refresh extension method to refresh the DbEntityEntry instance, here a async method RefreshAsync is called to refresh asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;EntityEntry&amp;gt; RefreshAsync(this EntityEntry tracking, RefreshConflict refreshMode)
{
    switch (refreshMode)
    {
        case RefreshConflict.StoreWins:
        {
            await tracking.ReloadAsync();
            break;
        }
        case RefreshConflict.ClientWins:
        {
            PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
            if (databaseValues == null)
            {
                tracking.State = EntityState.Detached;
            }
            else
            {
                tracking.OriginalValues.SetValues(databaseValues);
            }
            break;
        }
        case RefreshConflict.MergeClientAndStore:
        {
            PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
            if (databaseValues == null)
            {
                tracking.State = EntityState.Detached;
            }
            else
            {
                PropertyValues originalValues = tracking.OriginalValues.Clone();
                tracking.OriginalValues.SetValues(databaseValues);
#if EF
                databaseValues.PropertyNames
                    .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
#else
                databaseValues.Properties
                    .Where(property =&amp;gt; !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
                    .ForEach(property =&amp;gt; tracking.Property(property.Name).IsModified = false);
#endif
            }
            break;
        }
    }
    return tracking;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now concurrency conflict can be resolved automatically and asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task SaveChangesAsync()
{
    using (AdventureWorks adventureWorks1 = new AdventureWorks())
    using (AdventureWorks adventureWorks2 = new AdventureWorks())
    {
        int id = 950;
        Product productCopy1 = await adventureWorks1.Products.FindAsync(id);
        Product productCopy2 = await adventureWorks2.Products.FindAsync(id);

        productCopy1.Name = nameof(productCopy1);
        productCopy1.ListPrice = 100;
        (await adventureWorks1.SaveChangesAsync()).WriteLine(); // 1

        productCopy2.Name = nameof(productCopy2);
        productCopy2.ProductSubcategoryID = 1;
        (await adventureWorks2.SaveChangesAsync(RefreshConflict.MergeClientAndStore)).WriteLine(); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (4) Performance</title><link>https://dixin.github.io/posts/parallel-linq-4-performance-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-4-performance-7/</guid><description>Parallel LINQ is powerful, but also can be more complex. This part discusses Parallel LINQ query performance in different cases.</description><pubDate>Sun, 30 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/parallel-linq-4-performance&quot;&gt;https://weblogs.asp.net/dixin/parallel-linq-4-performance&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Parallel LINQ is powerful, but also can be more complex. This part discusses Parallel LINQ query performance in different cases.&lt;/p&gt;
&lt;h2&gt;Sequential query vs. parallel query&lt;/h2&gt;
&lt;p&gt;Parallel LINQ query can be faster than the parity sequential LINQ to Objects query, but not always. Take OrderBy as example, the following method compares the query execution duration of sequential OrderBy and parallel OrderBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void OrderByTest(Func&amp;lt;int, int&amp;gt; keySelector, int count, int run)
{
    $&quot;Sort {count} values.&quot;.WriteLine();
    int[] source = EnumerableX.RandomInt32(count: count).ToArray();
    Stopwatch stopwatch = Stopwatch.StartNew();
    Enumerable.Range(0, run).ForEach(_ =&amp;gt;
    {
        int[] sequential = source.OrderBy(keySelector).ToArray();
    });
    stopwatch.Stop();
    $&quot;Sequential:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine();

    stopwatch.Restart();
    Enumerable.Range(0, run).ForEach(_ =&amp;gt;
    {
        int[] parallel1 = source.AsParallel().OrderBy(keySelector).ToArray();
    });
    stopwatch.Stop();
    $&quot;Parallel:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It calls the RandomInt32 method, which was defined in the LINQ to Objects chapter, to generate an array of random int values with the specified length. Then it executes the sequential and parallel OrderBy methods for the specified times, so that the total execution time can be controlled, The following code compares the sequential/parallel OrderBy execution on small/medium/large size array, with the same simple key selector:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByTestForCount()
{
    OrderByTest(keySelector: value =&amp;gt; value, count: 5, run: 10_000);    
    // Sequential:11    Parallel:1422
    OrderByTest(keySelector: value =&amp;gt; value, count: 5_000, run: 100);
    // Sequential:114   Parallel:107
    OrderByTest(keySelector: value =&amp;gt; value, count: 500_000, run: 100);
    // Sequential:18210 Parallel:8204
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following method compares the sequential/parallel OrderBy execution on the same size array, with different key selector of light/medium/heavy workload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByTestForKeySelector()
{
    OrderByTest(
        keySelector: value =&amp;gt; value + ComputingWorkload(iteration: 1), 
        count: Environment.ProcessorCount, run: 100_000);
    // Sequential:37   Parallel:2218
    OrderByTest(
        keySelector: value =&amp;gt; value + ComputingWorkload(iteration: 10_000), 
        count: Environment.ProcessorCount, run: 1_000);
    // Sequential:115  Parallel:125
    OrderByTest(
        keySelector: value =&amp;gt; value + ComputingWorkload(iteration: 100_000), 
        count: Environment.ProcessorCount, run: 100);
    // Sequential:1240 Parallel:555
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It turns out sequential LINQ to Object can be faster than Parallel LINQ in some cases. Here, sequential OrderBy can execute faster for smaller source/lighter key selector, and parallel OrderBy can execute faster for larger source/more expensive key selector&lt;/p&gt;
&lt;h2&gt;CPU bound operation vs. I/O bound operation&lt;/h2&gt;
&lt;p&gt;So far, all the examples are CPU bound operations. In many cases, Parallel LINQ by default takes the logic processor count as the degree of parallelism. This makes sense for CPU bound operations, but may not for I/O bound operations. For example, when downloading files from Internet with parallel threads, it could be nice if the worker thread count can be controlled accurately, and independently from CPU core count. The following ForceParallel method can be implementation for this purpose:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ParallelEnumerableX
{
    public static void ForceParallel&amp;lt;TSource&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; action, int forcedDegreeOfParallelism)
    {
        if (forcedDegreeOfParallelism &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(forcedDegreeOfParallelism));
        }

        IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; partitions = Partitioner
            .Create(source, EnumerablePartitionerOptions.NoBuffering) // Stripped partitioning.
            .GetPartitions(forcedDegreeOfParallelism);
        using (CountdownEvent countdownEvent = new CountdownEvent(forcedDegreeOfParallelism))
        {
            partitions.ForEach(partition =&amp;gt; new Thread(() =&amp;gt;
            {
                try
                {
                    using (partition)
                    {
                        while (partition.MoveNext())
                        {
                            action(partition.Current);
                        }
                    }
                }
                finally 
                {
                    countdownEvent.Signal();
                }
            }).Start());
            countdownEvent.Wait();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It creates the specified number of partitions from the source, then start one threads to work with each partition. Also, by calling Partitioner.Create with EnumerablePartitionerOptions.NoBuffering, stripped partitioning is enabled for better load balance.&lt;/p&gt;
&lt;p&gt;To demonstrate the I/O bound operation, define the following network I/O method to download file synchronously from the the specified URI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static string Download(string uri)
    {
        WebRequest request = WebRequest.Create(uri);
        using (WebResponse response = request.EndGetResponse(request.BeginGetResponse(null, null)))
        using (Stream downloadStream = response.GetResponseStream())
        using (StreamReader streamReader = new StreamReader(downloadStream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following method compares and visualizes sequential download, parallel download with Parallel LINQ, and parallel download with above ForceParallel method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void DownloadTest(string[] uris)
{
    uris.Visualize(uri =&amp;gt; Functions.Download(uri)); // Sequential with no concurrency.

    uris.AsParallel()
        .WithDegreeOfParallelism(10) // Parallel with max concurrency.
        .Visualize(uri =&amp;gt; Functions.Download(uri));

    using (Markers.EnterSpan(-3, nameof(ParallelEnumerableX.ForceParallel)))
    {
        MarkerSeries markerSeries = Markers.CreateMarkerSeries(nameof(ParallelEnumerableX.ForceParallel));
        uris.ForceParallel(
            uri =&amp;gt;
            {
                using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, uri))
                {
                    Functions.Download(uri);
                }
            },
            forcedDegreeOfParallelism: 10); // Parallel with forced concurrency.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code queries some some thumbnail picture file URIs from the Flickr RSS feed with LINQ to XML, then compares the performance of downloading those small files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RunDownloadSmallFilesTest()
{
    string[] thumbnails = 
        XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;)
        .Descendants((XNamespace)&quot;http://search.yahoo.com/mrss/&quot; + &quot;thumbnail&quot;)
        .Attributes(&quot;url&quot;)
        .Select(uri =&amp;gt; (string)uri)
        .ToArray();
    DownloadTest(thumbnails);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-in-Depth-4-Performance_8FF0/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-in-Depth-4-Performance_8FF0/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here sequential downloading takes longer time, which totally makes sense. The Parallel LINQ query is specified with a max degree of parallelism 10, but it decides to utilize 5 threads. ForceParallel starts 10 threads exactly as specified, and its execution time is about half of Parallel LINQ.&lt;/p&gt;
&lt;p&gt;The following code queries for the same Flickr RSS feed for large picture file URIs, and compares the performance of downloading those large files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RunDownloadLargeFilesTest()
{
    string[] contents = 
        XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;)
        .Descendants((XNamespace)&quot;http://search.yahoo.com/mrss/&quot; + &quot;content&quot;)
        .Attributes(&quot;url&quot;)
        .Select(uri =&amp;gt; (string)uri)
        .ToArray();
    DownloadTest(contents);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-in-Depth-4-Performance_8FF0/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-in-Depth-4-Performance_8FF0/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This time Parallel LINQ still utilizes 5 threads from the beginning, then decides to start 2 more threads a while later. ForceParallel simply start 10 threads since the beginning. However, the execution time of sequential download, Parallel LINQ download, and ForceParallel download are about the same. This is because when downloading larger files, the network bandwidth becomes the performance bottleneck, and the degree of parallelization does not make much difference.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This part and the previous parts has demonstrated many aspects that can have performance impact for Parallel LINQ, and here is a summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The partitioning strategy can impact performance, because different partitioning algorithms introduce different synchronization and load balance.&lt;/li&gt;
&lt;li&gt;The degree of parallelism can impact performance, when degree of parallelism is set to 1, Parallel LINQ works like sequential LINQ to Object.&lt;/li&gt;
&lt;li&gt;The 2 execution modes, Default (sequential/parallel) and ForceParallel, can result different performance&lt;/li&gt;
&lt;li&gt;The merge option can also impact performance, smaller buffer size can have the early value results available faster, but can also make the query execute longer&lt;/li&gt;
&lt;li&gt;The order preservation can impact the performance, query as unordered can have better performance, but can also have incorrect results.&lt;/li&gt;
&lt;li&gt;The source size can impact performance, for source with smaller size, the overhead of parallelization can be more significant, and result even lower performance than sequential query&lt;/li&gt;
&lt;li&gt;The callback function provided to query methods can impact performance, more expensive callback functions can have better performance with parallel queries&lt;/li&gt;
&lt;li&gt;The type of operation can impact performance, utilize more CPU cores can improve the performance of compute bound operation, but I/O bound operations can depend on the I/O hardware.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parallel LINQ is provided for performance. In the real world, the performance of each Parallel LINQ query has to be measured and optimized accordingly.&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (3) Query Methods (Operators)</title><link>https://dixin.github.io/posts/parallel-linq-3-query-methods-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-3-query-methods-7/</guid><description>Parallel LINQ provides additional query methods and additional overrides for Aggregate method:</description><pubDate>Sat, 29 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/parallel-linq-3-query-methods&quot;&gt;https://weblogs.asp.net/dixin/parallel-linq-3-query-methods&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Parallel LINQ provides additional query methods and additional overrides for Aggregate method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sequence queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ordering: AsOrdered, AsUnordered&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conversion: AsParallel*, AsSequential*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Settings: WithCancellation, WithDegreeOfParallelism, WithExecutionMode, WithMergeOptions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Value queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: Aggregate&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Void queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Iteration: ForAll*&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The methods marked with * are already discussed in previous parts. This part covers the unmarked query methods, and also other query methods with different behaviors from LINQ to Objects.&lt;/p&gt;
&lt;h2&gt;Query settings&lt;/h2&gt;
&lt;h3&gt;Cancellation&lt;/h3&gt;
&lt;p&gt;Parallel LINQ query execution can be cancelled by specifying a System.Threading.CancellationToken instance for the query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithCancellation&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source, CancellationToken cancellationToken);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CancellationToken can be created with System.Threading.CancellationTokenSource:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Cancel()
{
    using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(
        delay: TimeSpan.FromSeconds(1)))
    {
        CancellationToken cancellationToken = cancellationTokenSource.Token;
        try
        {
            ParallelEnumerable.Range(0, Environment.ProcessorCount * 10)
                .WithCancellation(cancellationToken)
                .Select(value =&amp;gt; ComputingWorkload(value))
                .ForAll(value =&amp;gt; value.WriteLine());
        }
        catch (OperationCanceledException exception)
        {
            exception.WriteLine();
            // OperationCanceledException: The query has been canceled via the token supplied to WithCancellation.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After 1 second delay, If the query is still executing, is signaled to cancel, and throws an OperationCanceledException.&lt;/p&gt;
&lt;h3&gt;Degree of parallelism&lt;/h3&gt;
&lt;p&gt;WithDegreeOfParallelism specifies the maximum number of concurrent executing tasks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithDegreeOfParallelism&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source, int degreeOfParallelism);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DegreeOfParallelism()
{
    int maxConcurrency = Environment.ProcessorCount * 10;
    ParallelEnumerable
        .Range(0, maxConcurrency)
        .WithDegreeOfParallelism(maxConcurrency)
        .Visualize(value =&amp;gt; ComputingWorkload());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WithDegreeOfParallelism accepts any int value from 1 to 512 (System.Linq.Parallel.Scheduling’s MAX_SUPPORTED_DOP constant field). At runtime, the actual query thread count is less than or equal to the specified count. When executing above query on a quad core CPU, WithDegreeOfParallelism is called with 40. However the visualization shows Parallel LINQ only utilizes 6 threads.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If WithDegreeOfParallelism is not called, the default degree of parallelism is the minimum value of current device’s processor count and 512:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq.Parallel
{
    internal static class Scheduling
    {
        internal const int MAX_SUPPORTED_DOP = 512;

        internal static int DefaultDegreeOfParallelism = Math.Min(Environment.ProcessorCount, MAX_SUPPORTED_DOP);

        internal static int GetDefaultDegreeOfParallelism() =&amp;gt; DefaultDegreeOfParallelism;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Execution mode&lt;/h3&gt;
&lt;p&gt;WithExecutionMode specifies allowing the query to execute sequentially or not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithExecutionMode&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source, ParallelExecutionMode executionMode);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ParallelExecutionMode is an enumeration type with 2 members. Default means Parallel LINQ can possibly &lt;a href=&quot;http://blogs.msdn.com/b/pfxteam/archive/2009/10/31/9915569.aspx&quot;&gt;decide to execute the query sequentially&lt;/a&gt;; And ForceParallelism: the query is execute in parallel. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ExecutionMode()
{
    int count = Environment.ProcessorCount * 10_000;
    using (Markers.EnterSpan(-1, nameof(Enumerable)))
    {
        Enumerable
            .Range(0, count)
            .ToArray();
    }

    using (Markers.EnterSpan(-2, nameof(ParallelExecutionMode.Default)))
    {
        ParallelEnumerable
            .Range(0, count)
            .ToArray();
    }

    using (Markers.EnterSpan(-3, nameof(ParallelExecutionMode.ForceParallelism)))
    {
        ParallelEnumerable
            .Range(0, count)
            .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
            .ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb21_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb21_thumb.png&quot; alt=&quot;image_thumb21&quot; title=&quot;image_thumb21&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When Parallel LINQ execute ToArray query in the default mode, it is the same sequential execution as LINQ to Objects, with no additional thread involved. When execution mode is specified to ForceParallelism, Parallel LINQ executes ToArray in parallel with additional thread.&lt;/p&gt;
&lt;h3&gt;Merge the values&lt;/h3&gt;
&lt;p&gt;Parallel LINQ can partition the source values and process the partitions in parallel. After the processing, the result values may need to be merged, e.g., when the result values are consumed by a single thread foreach loop/ForEach method. WithMergeOptions suggests Parallel LINQ how to merge the data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; WithMergeOptions&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source, ParallelMergeOptions mergeOptions);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ParallelMergeOptions is an enumeration with 4 members. NotBuffered means when each result value is available, it is yielded to consumer immediately without being buffered., which is similar to lazy evaluation in LINQ to Objects; FullyBuffered means all result values are stored in the full size buffer, then, they are yielded to the consumer, which is similar to eager evaluation in LINQ to Objects; AutoBuffered is between NotBuffered and FullyBuffered, means the buffer size is determined by Parallel LINQ, result values are stored in the auto sized buffer, and when the buffer is full, the result values are yielded to consumer; And Default is the same as AutoBuffered. The following code demonstrates the difference of these options:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeForSelect()
{
    int count = 10;
    Stopwatch stopwatch = Stopwatch.StartNew();
    ParallelQuery&amp;lt;int&amp;gt; notBuffered = ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.NotBuffered)
        .Select(value =&amp;gt; value + ComputingWorkload(0, 10_000_000));
    notBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
    // 0:217 3:283 6:363 8:462 1:521 4:612 7:629 9:637 2:660 5:695

    stopwatch.Restart();
    ParallelQuery&amp;lt;int&amp;gt; autoBuffered = ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.AutoBuffered)
        .Select(value =&amp;gt; value + ComputingWorkload(0, 10_000_000));
    autoBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
    // 6:459 8:493 7:498 9:506 0:648 1:654 2:656 3:684 4:686 5:688

    stopwatch.Restart();
    ParallelQuery&amp;lt;int&amp;gt; fullyBuffered = ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.FullyBuffered)
        .Select(value =&amp;gt; value + ComputingWorkload(0, 10_000_000));
    fullyBuffered.ForEach(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;.WriteLine());
    // 0:584 1:589 2:618 3:627 4:629 5:632 6:634 7:636 8:638 9:641
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For above Select query execution, if NotBuffered is specified, the first result value is yielded faster; if FullyBuffered is specified, the last result value is yielded faster; if AutoBuffered is specified, the behavior is between NotBuffered and FullyBuffered. Also, since FullyBuffered buffers all result values, it can persist their order, while NotBuffered and AutoBuffered cannot.&lt;/p&gt;
&lt;p&gt;WithMergeOptions just provides a suggestion to Parallel LINQ, so Parallel LINQ can still make its own decision. For example, OrderBy has to evaluate all source values, fully buffer them, then sort them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeForOrderBy()
{
    int count = Environment.ProcessorCount * 2;
    Stopwatch stopwatch = Stopwatch.StartNew();
    ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.NotBuffered)
        .Select(value =&amp;gt; ComputingWorkload(value))
        .WriteLines(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;);
    // 0:132 2:273 1:315 4:460 3:579 6:611 5:890 7:1103

    stopwatch.Restart();
    ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.NotBuffered)
        .Select(value =&amp;gt; ComputingWorkload(value))
        .OrderBy(value =&amp;gt; value) // Eager evaluation.
        .WriteLines(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;);
    // 0:998 1:999 2:999 3:1000 4:1000 5:1000 6:1001 7:1001

    stopwatch.Restart();
    ParallelEnumerable.Range(0, count)
        .WithMergeOptions(ParallelMergeOptions.FullyBuffered)
        .Select(value =&amp;gt; ComputingWorkload(value))
        .OrderBy(value =&amp;gt; value) // Eager evaluation.
        .WriteLines(value =&amp;gt; $&quot;{value}:{stopwatch.ElapsedMilliseconds}&quot;);
    // 0:984 1:985 2:985 3:986 4:987 5:987 6:988 7:989
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So OrderBy ignores the suggested ParallelMergeOptions and always fully buffer the values, then yield the buffered values.&lt;/p&gt;
&lt;h2&gt;Ordering&lt;/h2&gt;
&lt;p&gt;In Parallel LINQ, it is more complex to control the order of values than in sequential LINQ to Objects. Apparently, the order of values may not be persisted when they are not sequentially processed. Take the indexed Select as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectWithIndex() =&amp;gt; 
    new StaticPartitioner&amp;lt;int&amp;gt;(Enumerable.Range(0, Environment.ProcessorCount * 2))
        .AsParallel()
        .Select((value, index) =&amp;gt; $&quot;[{index}]={value}&quot;)
        .WriteLines(); // [0]=0 [1]=2 [2]=4 [3]=5 [4]=6 [5]=1 [6]=3 [7]=7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As demonstrated above, WithMergeOptions can impact the order of query results, where ParallelMergeOptions.FullyBuffered can be specified to preserve the order. Parallel LINQ also provides other APIs to control the order.&lt;/p&gt;
&lt;h3&gt;Control the order&lt;/h3&gt;
&lt;p&gt;AsOrdered method can be called to specify the order of values should be preserved for its following query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsOrdered&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsOrdered can only be called on the ParallelQuery&amp;lt;T&amp;gt; instance returned by ParallelEnumerable.AsParallel, ParallelEnumerable.Range, and ParallelEnumerable.Repeat. It throws InvalidOperationException for ParallelQuery&amp;lt;T&amp;gt; instance returned by any other methods.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsOrdered()
{
    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .AsParallel()
        .Select(value =&amp;gt; value + ComputingWorkload())
        .WriteLines(); // 3 1 2 0 4 5 6 7

    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .AsParallel()
        .AsOrdered()
        .Select(value =&amp;gt; value + ComputingWorkload())
        .WriteLines(); // 0 1 2 3 4 5 6 7
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preserving the order means additional work. So AsUnordered method is provided to ignore the order of values for its following query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsUnordered&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can improve the query performance. Take GroupBy as example, it can execute faster if the source values are explicitly specified to be unordered:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsUnordered()
{
    Random random = new Random();
    Model[] source = Enumerable
        .Range(0, Environment.ProcessorCount * 10_000)
        .Select(_ =&amp;gt; new Model(name: Guid.NewGuid().ToString(), weight: random.Next(1, 100)))
        .ToArray();

    Stopwatch stopwatch = Stopwatch.StartNew();
    source
        .AsParallel()
        .GroupBy(model =&amp;gt; model.Weight, model =&amp;gt; model.Name)
        .ForAll();
    stopwatch.Stop();
    stopwatch.ElapsedMilliseconds.WriteLine(); // 35.

    stopwatch.Restart();
    source
        .AsParallel()
        .AsUnordered()
        .GroupBy(model =&amp;gt; model.Weight, model =&amp;gt; model.Name)
        .ForAll();
    stopwatch.Stop();
    stopwatch.ElapsedMilliseconds.WriteLine(); // 2.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the order introduced by OrderBy/OrderByDescending/ThenBy/ThenByDescending/Reverse is preserved in their following query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderBy()
{
    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .AsParallel()
        .Select(value =&amp;gt; value) // Order is not preserved.
        .WriteLines(); // 3 1 2 0 4 5 6 7

    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .AsParallel()
        .Select(value =&amp;gt; value) // Order is not preserved.
        .OrderBy(value =&amp;gt; value) // Order is introduced.
        .Select(value =&amp;gt; value) // Order is preserved.
        .WriteLines(); // 3 1 2 0 4 5 6 7
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Order and correctness&lt;/h3&gt;
&lt;p&gt;In Parallel LINQ, many methods are order sensitive. If the source values are unordered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ElementAt: returns arbitrary value&lt;/li&gt;
&lt;li&gt;ElementAtOrDefault: returns arbitrary value or default&lt;/li&gt;
&lt;li&gt;First: returns arbitrary value&lt;/li&gt;
&lt;li&gt;FirstOrDefault: returns arbitrary value or default&lt;/li&gt;
&lt;li&gt;Last: returns arbitrary value&lt;/li&gt;
&lt;li&gt;LastOrDefault: returns arbitrary value or default&lt;/li&gt;
&lt;li&gt;Reverse: does nothing&lt;/li&gt;
&lt;li&gt;SequenceEqual: compares values in arbitrary order&lt;/li&gt;
&lt;li&gt;Skip: skips arbitrary values&lt;/li&gt;
&lt;li&gt;SkipWhile: skips arbitrary values&lt;/li&gt;
&lt;li&gt;Take: takes arbitrary values&lt;/li&gt;
&lt;li&gt;TakeWhile: takes arbitrary values with the predicate&lt;/li&gt;
&lt;li&gt;Zip: zips unordered values&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void Correctness()
{
    int count = Environment.ProcessorCount * 4;
    int[] source = Enumerable.Range(0, count).ToArray(); // 0 ... 15.

    int elementAt = new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .ElementAt(count / 2).WriteLine() // Expected: 8, 
        .WriteLine(); // Actual: 2.

    int first = new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .First() // Expected: 0.
        .WriteLine(); // Actual: 3.

    int last = new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .Last() // Expected: 15.
        .WriteLine(); // Actual: 13.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .Take(count / 2) // Expected: 0 ... 7.
        .WriteLines(); // Actual: 3 2 5 7 10 11 14 15.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .Skip(count / 2) // Expected: 8 ... 15.
        .WriteLines(); // Actual: 3 0 7 5 11 10 15 14.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .TakeWhile(value =&amp;gt; value &amp;lt;= count / 2) // Expected: 0 ... 7.
        .WriteLines(); // Actual: 3 5 8.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .SkipWhile(value =&amp;gt; value &amp;lt;= count / 2) // Expected: 9 ... 15.
        .WriteLines(); // Actual: 1 3 2 13 5 7 6 11 9 10 15 12 14.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .Reverse() // Expected: 15 ... 0.
        .WriteLines(); // Actual: 12 8 4 2 13 9 5 1 14 10 6 0 15 11 7 3.

    bool sequentialEqual = new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .SequenceEqual(new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel()); // Expected: True.
    sequentialEqual.WriteLine(); // Actual: False.

    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel().Select(value =&amp;gt; value + ComputingWorkload())
        .Zip(
            second: new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel(),
            resultSelector: (a, b) =&amp;gt; $&quot;({a}, {b})&quot;) // Expected: (0, 0) ... (15, 15).
        .WriteLines(); // Actual: (3, 8) (0, 12) (1, 0) (2, 4) (6, 9) (7, 13) ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So they must be used with ordered source to return the correct query results.&lt;/p&gt;
&lt;p&gt;And, once again, ForAll pulls values and calls the specified function in parallel, and does not maintain the order as well.&lt;/p&gt;
&lt;h3&gt;Orderable partitioner&lt;/h3&gt;
&lt;p&gt;.NET also provides APIs for partitioning with order control. The contract is the the System.Collections.OrderablePartitioner&amp;lt;TSource&amp;gt; abstract class, which inherits the fore mentioned Partitioner&amp;lt;TSource&amp;gt; type. The following are the new members in OrderablePartitioner&amp;lt;TSource&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Concurrent
{
    public abstract class OrderablePartitioner&amp;lt;TSource&amp;gt; : Partitioner&amp;lt;TSource&amp;gt;
    {
        protected OrderablePartitioner(bool keysOrderedInEachPartition, bool keysOrderedAcrossPartitions, bool keysNormalized)
        {
            this.KeysOrderedInEachPartition = keysOrderedInEachPartition;
            this.KeysOrderedAcrossPartitions = keysOrderedAcrossPartitions;
            this.KeysNormalized = keysNormalized;
        }

        public bool KeysNormalized { get; }

        public bool KeysOrderedInEachPartition { get; }

        public bool KeysOrderedAcrossPartitions { get; }

        public abstract IList&amp;lt;IEnumerator&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;&amp;gt; GetOrderablePartitions(int partitionCount);

        public virtual IEnumerable&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt; GetOrderableDynamicPartitions() =&amp;gt;
            throw new NotSupportedException(&quot;Dynamic partitions are not supported by this partitioner.&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of providing partitions of values, orderable partitioner provides partitions of key value pairs, where key is the index of source value. Its GetOrderablePartitions is the parity with Partitioner&amp;lt;TSource&amp;gt;.GetPartitions, return a list of iterators that yield values with keys; GetOrderableDynamicPartitions is the parity with Partitioner&amp;lt;TSource&amp;gt;.GetDynamicPartitions, also yields values with keys; Its KeysNormalized property returns a bool value to indicate whether the keys increase from 0; Its KeysOrderedInEachPartition indicates whether in each partition, keys increase, so that a later value’s key is greater then an former value’s key; And its KeysOrderedAcrossPartitions indicates whether keys increase partition by partition, so that a later partition’s keys are greater then an former partition’s keys. Orderable partitioner is also easy to implement with EnumerableEx.Share and IBuffer&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class OrderableDynamicPartitioner&amp;lt;TSource&amp;gt; : OrderablePartitioner&amp;lt;TSource&amp;gt;
{
    private readonly IBuffer&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt; buffer;

    public OrderableDynamicPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source)
        : base(keysOrderedInEachPartition: true, keysOrderedAcrossPartitions: true, keysNormalized: true)
    {
        long index = -1;
        this.buffer = source
            .Select(value =&amp;gt; new KeyValuePair&amp;lt;long, TSource&amp;gt;(Interlocked.Increment(ref index), value))
            .Share();
    }

    public override bool SupportsDynamicPartitions =&amp;gt; true;

    public override IList&amp;lt;IEnumerator&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt;&amp;gt; GetOrderablePartitions(
        int partitionCount) =&amp;gt; Enumerable
            .Range(0, partitionCount)
            .Select(_ =&amp;gt; this.buffer.GetEnumerator())
            .ToArray();

    public override IEnumerable&amp;lt;KeyValuePair&amp;lt;long, TSource&amp;gt;&amp;gt; GetOrderableDynamicPartitions() =&amp;gt; this.buffer;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Orderable partitioner can be used with AsOrdered:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Partitioning
{
    internal static void PartitionerAsOrdered()
    {
        int[] source = Enumerable.Range(0, Environment.ProcessorCount * 2).ToArray();
        new OrderableDynamicPartitioner&amp;lt;int&amp;gt;(source)
            .AsParallel()
            .Select(value =&amp;gt; value + ComputingWorkload())
            .WriteLines(); // 1 0 5 3 4 6 2 7

        new OrderableDynamicPartitioner&amp;lt;int&amp;gt;(source)
            .AsParallel()
            .AsOrdered()
            .Select(value =&amp;gt; value + ComputingWorkload())
            .WriteLines(); // 0 ... 7

        new DynamicPartitioner&amp;lt;int&amp;gt;(source)
            .AsParallel()
            .AsOrdered()
            .Select(value =&amp;gt; value + ComputingWorkload())
            .WriteLines();
        // InvalidOperationException: AsOrdered may not be used with a partitioner that is not orderable.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Aggregation&lt;/h2&gt;
&lt;p&gt;Parallel LINQ’s Aggregate methods are more sensitive than LINQ to Object.&lt;/p&gt;
&lt;h3&gt;Commutativity, associativity and correctness&lt;/h3&gt;
&lt;p&gt;In Parallel LINQ, Aggregate methods require the provided accumulator functions to be both commutative and associative. Assume func is a function that accepts 2 parameters and returns a result, if func(a, b) ≡ func(b, a), then func is commutative; if func(func(a, b), c) ≡ func(a, func(b, c)), then func is associative. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CommutativeAssociative()
{
    Func&amp;lt;int, int, int&amp;gt; func1 = (a, b) =&amp;gt; a + b;
    (func1(1, 2) == func1(2, 1)).WriteLine(); // True, commutative
    (func1(func1(1, 2), 3) == func1(1, func1(2, 3))).WriteLine(); // True, associative.

    Func&amp;lt;int, int, int&amp;gt; func2 = (a, b) =&amp;gt; a * b + 1;
    (func2(1, 2) == func2(2, 1)).WriteLine(); // True, commutative
    (func2(func2(1, 2), 3) == func2(1, func2(2, 3))).WriteLine(); // False, not associative.

    Func&amp;lt;int, int, int&amp;gt; func3 = (a, b) =&amp;gt; a;
    (func3(1, 2) == func3(2, 1)).WriteLine(); // False, not commutative
    (func3(func3(1, 2), 3) == func3(1, func3(2, 3))).WriteLine(); // True, associative.

    Func&amp;lt;int, int, int&amp;gt; func4 = (a, b) =&amp;gt; a - b;
    (func4(1, 2) == func4(2, 1)).WriteLine(); // False, not commutative
    (func4(func4(1, 2), 3) == func4(1, func4(2, 3))).WriteLine(); // False, not associative.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To demonstrate how parallel aggregation is impacted by commutativity and associativity, it can be compared with sequential aggregation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AggregateCorrectness()
{
    int count = Environment.ProcessorCount * 2;
    int sequentialAdd = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a + b);
    sequentialAdd.WriteLine(); // 28
    int parallelAdd = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a + b);
    parallelAdd.WriteLine(); // 28

    int sequentialSubtract = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a - b);
    sequentialSubtract.WriteLine(); // -28
    int parallelSubtract = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt; a - b);
    parallelSubtract.WriteLine(); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, parallelSubtract has incorrect result value, because the function provided to Aggregate is neither commutative nor associative. The following code visualizes the aggregation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void VisualizeAggregate()
{
    int count = Environment.ProcessorCount * 2;
    using (Markers.EnterSpan(-1, &quot;Sequential subtract&quot;))
    {
        MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Sequential subtract&quot;);
        int sequentialSubtract = Enumerable.Range(0, count).Aggregate((a, b) =&amp;gt;
        {
            using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, $&quot;{a}, {b} =&amp;gt; {a - b}&quot;))
            {
                return a - b + ComputingWorkload();
            }
        });
    }

    using (Markers.EnterSpan(-2, &quot;Parallel subtract&quot;))
    {
        MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Parallel subtract&quot;);
        int parallelSubtract = ParallelEnumerable.Range(0, count).Aggregate((a, b) =&amp;gt;
        {
            using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, $&quot;{a}, {b} =&amp;gt; {a - b}&quot;))
            {
                return a - b + ComputingWorkload();
            }
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The sequential aggregation has the expected process:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The parallel aggregation has different behavior:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-3-Query-Methods-Operators_8F49/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It follows the pattern of parallel query methods. It first partitions the data. On this quad core CPU, it splits the 8 source values into 4 partitions, (0, 1), (2, 3), (4, 5), (6, 7). Then it execute the provided function for each parallel in parallel, the 4 partitions’ result values are –1, –1, –1, –1. And finally it merges the 4 result values with the provided function, so the final aggregation result is 2. This demonstrates that the accumulator function must be commutative and associative for the parallel aggregation.&lt;/p&gt;
&lt;h3&gt;Partition and merge&lt;/h3&gt;
&lt;p&gt;Parallel LINQ provides 2 additional Aggregate overloads, where the seed for each partition be specified with either a value or a value factory function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(
    this ParallelQuery&amp;lt;TSource&amp;gt; source, 
    TAccumulate seed, 
    Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; updateAccumulatorFunc, 
    Func&amp;lt;TAccumulate, TAccumulate, TAccumulate&amp;gt; combineAccumulatorsFunc, 
    Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);

public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(
    this ParallelQuery&amp;lt;TSource&amp;gt; source, 
    Func&amp;lt;TAccumulate&amp;gt; seedFactory, 
    Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; updateAccumulatorFunc, 
    Func&amp;lt;TAccumulate, TAccumulate, TAccumulate&amp;gt; combineAccumulatorsFunc, 
    Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They also both accept 2 accumulator functions. First, updateAccumulatorFunc can be read as “source value accumulator”, it accumulates the values within each partition to a partition result. So if there are N partitions, there are N partition results. Then, combineAccumulatorsFunc can be read as “partition result accumulator”, it accumulates all partitions’ results to a single final result. The following example calculates the sum of squares:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeForAggregate()
{
    int count = Environment.ProcessorCount * 2;
    int sequentialSumOfSquares = Enumerable
        .Range(0, count)
        .Aggregate(seed: 0, func: (accumulate, value) =&amp;gt; accumulate + value * value);
    sequentialSumOfSquares.WriteLine(); // 140

    int parallelSumOfSquares1 = ParallelEnumerable
        .Range(0, Environment.ProcessorCount * 2)
        .Aggregate(
            seed: 0, // Seed for each partition.
            updateAccumulatorFunc: (accumulation, value) =&amp;gt; accumulation + value * value, // Source value accumulator for each partition&apos;s result.
            combineAccumulatorsFunc: (accumulation, partition) =&amp;gt; accumulation + partition, // Partition result accumulator for final result.
            resultSelector: result =&amp;gt; result);
    parallelSumOfSquares1.WriteLine(); // 140

    int parallelSumOfSquares2 = ParallelEnumerable
        .Range(0, Environment.ProcessorCount * 2)
        .Aggregate(
            seedFactory: () =&amp;gt; 0, // Seed factory for each partition.
            updateAccumulatorFunc: (accumulation, value) =&amp;gt; accumulation + value * value, // Source value accumulator for each partition&apos;s result.
            combineAccumulatorsFunc: (accumulation, partition) =&amp;gt; accumulation + partition, // Partition result accumulator for final result.
            resultSelector: result =&amp;gt; result);
    parallelSumOfSquares2.WriteLine(); // 140
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the parallel aggregation, first the sum of squares are calculated for each partition. Then all partitions’ results are merged by summing up.&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (2) Partitioning</title><link>https://dixin.github.io/posts/parallel-linq-2-partitioning-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-2-partitioning-7/</guid><description>The first step of Parallel LINQ is partitioning. The source values is split into several partitions, so that multiple threads can execute the query logic in parallel.</description><pubDate>Wed, 26 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/parallel-linq-2-partitioning&quot;&gt;https://weblogs.asp.net/dixin/parallel-linq-2-partitioning&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The first step of Parallel LINQ is partitioning. The source values is split into several partitions, so that multiple threads can execute the query logic in parallel.&lt;/p&gt;
&lt;h2&gt;Partitioning algorithms and load balancing&lt;/h2&gt;
&lt;p&gt;In Parallel LINQ, there are 4 kinds of partitioning algorithms – range partitioning, chunk partitioning, strip partitioning, and hash partitioning.&lt;/p&gt;
&lt;h3&gt;Range partitioning&lt;/h3&gt;
&lt;p&gt;Range partitioning works with indexed source sequence has known length, like T[] arrays with a Length property, and IList&amp;lt;T&amp;gt; lists with a Count property. Assume on a quad core CPU, if there are 12 values in the source, by default Parallel LINQ splits these 12 values (at indexes 0, 1, 2, …, 11) into 4 partition A, B, C, D:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index:     0  1  2  3  4  5  6  7  8  9 10 11
Partition: A  A  A, B  B  B, C  C  C, D  D  D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If there are 13 source values, their are partitioned as: AAAA, BBB, CCC, DDD; 14 values are partitioned as AAAA, BBBB, CCC, DDD; 15 values are partitioned as AAAA, BBBB, CCCC, DDD; 16 values are partitioned as AAAA, BBBB, CCCC, DDDD; and so on.&lt;/p&gt;
&lt;p&gt;With the Visualize and ComputingWorkload methods defined previously, the following code can visualize how an array is partitioned by range of index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Partitioning
{
    internal static void Range()
    {
        int[] array = Enumerable.Range(0, Environment.ProcessorCount * 4).ToArray();
        array.AsParallel().Visualize(value =&amp;gt; ComputingWorkload(value), nameof(Range));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Execute this method with Concurrency Visualizer for Visual Studio, the following chart is generated:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here the timespan of value 12 is longer than the timespan of 15, because CPU was fully used at the beginning. Regarding there are also other processes and thread running on the device, when processing value 12, the query thread cannot ideally utilize 25% of CPU (100% of one core). It also shows the threads do not balance the load very well. For example, thread 19140 is done with a partition (0, 1, 2, 3) quickly, then it becomes idle and just waits for other threads to be done with other partitions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Stripped partitioning&lt;/h3&gt;
&lt;p&gt;Stripped partitioning can work with non-indexed source. In this algorithm, each Parallel LINQ query thread pulls the first value from the source. when each thread is done with a done, it tried to pull the first value again, until the source becomes empty. Still assume a quad core CPU, and assume it costs about the same time for each thread to process each value, then the partitioning result is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Index:     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 ...
Partition: A  B  C  D  A  B  C  D  A  B  C  D  A  B  C  D ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take a simple IEnumerable&amp;lt;T&amp;gt; source as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Strip()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, Environment.ProcessorCount * 4);
    source.AsParallel().Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value)).ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The visualization is:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A benefit of stripped partitioning is that threads can balance the load. To demonstrate this, just tweak above code a little bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StripLoadBalance()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, Environment.ProcessorCount * 4);
    source.AsParallel().Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value % 2)).ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb4_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb4_thumb.png&quot; alt=&quot;image_thumb4&quot; title=&quot;image_thumb4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Firstly, the 4 query threads pulls 4 values 0, 1, 2, 3 to process. Apparently, threads processing 0 and 2 get the jobs done sooner. They are not idle, and immediately starts to pull the following values 4 and 5 to process. As a result, the load is better balanced, 4 threads finish the query with similar time.&lt;/p&gt;
&lt;p&gt;To enable stripped partitioning for arrays and lists, call System.Collections.Concurrency.Partitioner’s Create method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StripForArray()
{
    int[] array = Enumerable.Range(0, Environment.ProcessorCount * 4).ToArray();
    Partitioner.Create(array, loadBalance: true).AsParallel().Visualize(value =&amp;gt; ComputingWorkload(value), nameof(Strip));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Partitioner.Create returns Partitioner&amp;lt;T&amp;gt; which implements load balanced strip partitioning. Then another ParallelEnumerable.AsParallel overload can be called on it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery&amp;lt;TSource&amp;gt; AsParallel&amp;lt;TSource&amp;gt;(this Partitioner&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Partitioner&amp;lt;TSource&amp;gt; type will be discussed later.&lt;/p&gt;
&lt;h3&gt;Hash partitioning&lt;/h3&gt;
&lt;p&gt;When Parallel LINQ needs to compare values in the source, like GroupBy, Join, GroupJoin, etc., it partitions the values based on hash code. As a result, values with the same hash code are processed by the same thread. To demonstrate this behavior, a data structure with a custom hash algorithm can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal readonly struct Data
{
    internal Data(int value) =&amp;gt; this.Value = value;

    internal int Value { get; }

    public override int GetHashCode() =&amp;gt; this.Value % Environment.ProcessorCount;

    public override bool Equals(object obj) =&amp;gt; obj is Data &amp;amp;&amp;amp; this.GetHashCode() == ((Data)obj).GetHashCode();

    public override string ToString() =&amp;gt; this.Value.ToString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just wraps an Int32 value, but only produces 4 kinds of hash code on a quad core CPU.&lt;/p&gt;
&lt;p&gt;GroupBy query can be visualized by the other Visualize overload from previous part:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void HashInGroupBy()
{
    IEnumerable&amp;lt;Data&amp;gt; source = new int[] { 0, 1, 2, 2, 2, 2, 3, 4, 5, 6, 10 }.Select(value =&amp;gt; new Data(value));
    source.AsParallel()
        .Visualize(
            (parallelQuery, elementSelector) =&amp;gt; parallelQuery.GroupBy(
                keySelector: data =&amp;gt; data, // Key instance&apos;s GetHashCode will be called.
                elementSelector: elementSelector),
            data =&amp;gt; ComputingWorkload(data.Value)) // elementSelector.
        .ForAll();
    // Equivalent to:
    // MarkerSeries markerSeries = Markers.CreateMarkerSeries(&quot;Parallel&quot;);
    // source.AsParallel()
    //    .GroupBy(
    //        keySelector: data =&amp;gt; data,
    //        elementSelector: data =&amp;gt;
    //        {
    //            using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, data.ToString()))
    //            {
    //                return ComputingWorkload(data.Value);
    //            }
    //        })
    //    .ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb5_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb5_thumb.png&quot; alt=&quot;image_thumb5&quot; title=&quot;image_thumb5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here GroupBy uses Data instances as the keys, where Data.GetHashCode is called, and the returned hash codes are used for partitioning. Also, apparently there is no load balance. And the following the visualization of Join:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void HashInJoin()
{
    IEnumerable&amp;lt;Data&amp;gt; outerSource = new int[] { 0, 1, 2, 2, 2, 2, 3, 6 }.Select(value =&amp;gt; new Data(value));
    IEnumerable&amp;lt;Data&amp;gt; innerSource = new int[] { 4, 5, 6, 7 }.Select(value =&amp;gt; new Data(value));
    outerSource.AsParallel()
        .Visualize(
            (parallelQuery, resultSelector) =&amp;gt; parallelQuery
                .Join(
                    inner: innerSource.AsParallel(),
                    outerKeySelector: data =&amp;gt; data, // Key instance&apos;s GetHashCode is called.
                    innerKeySelector: data =&amp;gt; data, // Key instance&apos;s GetHashCode is called.
                    resultSelector: (outerData, innerData) =&amp;gt; resultSelector(outerData)),
            data =&amp;gt; ComputingWorkload(data.Value)) // resultSelector.
        .ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb7_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb7_thumb.png&quot; alt=&quot;image_thumb7&quot; title=&quot;image_thumb7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Chunk partitioning&lt;/h3&gt;
&lt;p&gt;Parallel LINQ also implements chunk partitioning, where each thread pulls a chunk of values from the source. Initially the chunk size is 1, each thread pulls a chunk for 3 times; Then the chunk size increases to 2, and each thread pulls a chunk for 3 times; Then the chunk size increase to 3, and each thread pulls a chunk for 3 times again; and so on. On a quad core CPU, Parallel LINQ creates 4 partitions A, B, C, D by default, and the partitioning is: ABCD ABCD ABCD AABBCCDD AABBCCDD AABBCCDD AAABBBCCCDDD ... Another overload of Partitioner.Create can create such a chunk partitioner:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Chunk()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, (1 + 2) * 3 * Environment.ProcessorCount + 3);
    Partitioner.Create(source, EnumerablePartitionerOptions.None).AsParallel()
        .Visualize(ParallelEnumerable.Select, _ =&amp;gt; ComputingWorkload())
        .ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing this query on a quad core CPU, the first 12 chunks have 1 value in each chunk, the next 12 chunks have 2 values in each chunk, then the 25th chunk has 3 values, and so on:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb8_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb8_thumb.png&quot; alt=&quot;image_thumb8&quot; title=&quot;image_thumb8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stripped partitioning can be viewed as a special case of chunk partitioning, where chunk size is always 1. And for this reason, stripped partition can have better load balance.&lt;/p&gt;
&lt;h2&gt;Implement custom partitioner&lt;/h2&gt;
&lt;p&gt;.NET also provides APIs to implement custom partitioning. The contract is the System.Collections.Partitioner&amp;lt;TSource&amp;gt; abstract class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Concurrent
{
    public abstract class Partitioner&amp;lt;TSource&amp;gt;
    {
        protected Partitioner() { }

        public virtual bool SupportsDynamicPartitions =&amp;gt; false;

        public abstract IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; GetPartitions(int partitionCount);

        public virtual IEnumerable&amp;lt;TSource&amp;gt; GetDynamicPartitions() =&amp;gt;
            throw new NotSupportedException(&quot;Dynamic partitions are not supported by this partitioner.&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Static partitioner&lt;/h3&gt;
&lt;p&gt;The GetPartitions method is used to return the specified number of partitions, and each partition is represented by an iterator, which yields the values of each partition. This design of having multiple IEnumerator&amp;lt;T&amp;gt; iterators to share one IEnumerable&amp;lt;T&amp;gt; sequence, is the same idea as the EnumerableEx.Share and IBuffer&amp;lt;T&amp;gt; from Interactive Extenson (Ix) library discussed in the LINQ to Objects chapter. So an simple static partitioner can be implemented as a wrapper of IBuffer&amp;lt;T&amp;gt; created by Share:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class StaticPartitioner&amp;lt;TSource&amp;gt; : Partitioner&amp;lt;TSource&amp;gt;
{
    protected readonly IBuffer&amp;lt;TSource&amp;gt; buffer;

    public StaticPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; this.buffer = source.Share();

    public override IList&amp;lt;IEnumerator&amp;lt;TSource&amp;gt;&amp;gt; GetPartitions(int partitionCount)
    {
        if (partitionCount &amp;lt;= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(partitionCount));
        }

        return Enumerable
            .Range(0, partitionCount)
            .Select(_ =&amp;gt; this.buffer.GetEnumerator())
            .ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As demonstrated above, now the AsParallel for partitioner can be called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StaticPartitioner()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, Environment.ProcessorCount * 4);
    new StaticPartitioner&amp;lt;int&amp;gt;(source).AsParallel()
        .Visualize(ParallelEnumerable.Select, value =&amp;gt; ComputingWorkload(value))
        .ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Parallel LINQ only calls the GetPartitions method, and start to query the returned partitions in parallel. Apparently IBuffer&amp;lt;T&amp;gt; implements stripped partitioning.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-2-Partitioning_8EAF/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Dynamic partitioner&lt;/h3&gt;
&lt;p&gt;When a partitioner’s SupportsDynamicPartitions property returns true, it is a dynamic partitioner. Besides splitting source into a specified static number of iterators like above, dynamic partitioner’s GetDynamicPartitions can also split source into arbitrary number of partitions. GetDynamicPartitions returns a IEnumerable&amp;lt;T&amp;gt; sequence, whose GetEnumerator method can be called at any time, and can be called arbitrary times, to return arbitrary number of IEnumerator&amp;lt;T&amp;gt; iterators. This scenario is still supported by IBuffer&amp;lt;T&amp;gt;, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DynamicPartitioner&amp;lt;TSource&amp;gt; : StaticPartitioner&amp;lt;TSource&amp;gt;
{
    public DynamicPartitioner(IEnumerable&amp;lt;TSource&amp;gt; source) : base(source) { }

    public override bool SupportsDynamicPartitions =&amp;gt; true;

    public override IEnumerable&amp;lt;TSource&amp;gt; GetDynamicPartitions() =&amp;gt; this.buffer;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Parallel LINQ only calls the GetPartitions method, so for sure above DynamicPartitioner can be used in Parallel LINQ. Dynamic partitioner can be also used for System.Threading.Tasks.Parallel’s ForEach method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public static class Parallel
    {
        public static ParallelLoopResult ForEach&amp;lt;TSource&amp;gt;(Partitioner&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; body);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Parallel.ForEach first calls SupportsDynamicPartitions. If false is returned, it throws an InvalidOperationException: The Partitioner used here must support dynamic partitioning; If true is returned, it then calls GetDynamicPartitions to partition the values and call the specified callback function in parallel for each partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DynamicPartitioner()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, Environment.ProcessorCount * 4);
    Parallel.ForEach(new DynamicPartitioner&amp;lt;int&amp;gt;(source), value =&amp;gt; ComputingWorkload(value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Parallel.ForEach has another overload accepting an IEnumerable&amp;lt;T&amp;gt; sequence, which is more commonly used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelLoopResult ForEach&amp;lt;TSource&amp;gt;(IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; body);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Internally, it calls the fore mentioned Partitioner.Create method to create a dynamic partitioner from the source sequence, then use the dynamic partitioner to call the specified callback function in parallel.&lt;/p&gt;
</content:encoded></item><item><title>Parallel LINQ in Depth (1) Local Parallel Query and Visualization</title><link>https://dixin.github.io/posts/parallel-linq-1-local-parallel-query-and-visualization-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/parallel-linq-1-local-parallel-query-and-visualization-7/</guid><description>So far, all the discussion for LINQ to Objects/XML does not involve multi-threading, concurrency, or parallel computing. This is by design, because pulling values from an IEnumerable&lt;T&gt; sequence is no</description><pubDate>Sat, 01 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Parallel%20LINQ&quot;&gt;Parallel LINQ in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/parallel-linq-1-local-parallel-query-and-visualization&quot;&gt;https://weblogs.asp.net/dixin/parallel-linq-1-local-parallel-query-and-visualization&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;So far, all the discussion for LINQ to Objects/XML does not involve multi-threading, concurrency, or parallel computing. This is by design, because pulling values from an IEnumerable&amp;lt;T&amp;gt; sequence is not thread-safe.When multiple threads simultaneously access one IEnumerable&amp;lt;T&amp;gt; sequence, race condition can occur and lead to unpredictable consequence. As a result, all the LINQ to Objects/XML queries are implemented in a sequential manner with a single thread. To scale LINQ in multi-processor environment, Since .NET Framework4.0, a parallel version of LINQ to Objects is also provided, called Parallel LINQ or PLINQ.&lt;/p&gt;
&lt;h2&gt;Parallel LINQ types and methods&lt;/h2&gt;
&lt;p&gt;Parallel LINQ types are provided as a parity with LINQ to Objects:&lt;/p&gt;
&lt;p&gt;&amp;lt;table cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;531&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Sequential LINQ&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;251&quot;&amp;gt;Parallel LINQ&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;System.Collections.IEnumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;251&quot;&amp;gt;System.Linq.ParallelQuery&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;251&quot;&amp;gt;System.Linq.ParallelQuery&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;System.Linq.IOrderedEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;251&quot;&amp;gt;System.Linq.OrderedParallelQuery&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;System.Linq.Enumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;251&quot;&amp;gt;System.Linq.ParallelEnumerable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;As the parity, System.Linq.ParallelEnumerable provides the parallel version of System.Linq.Enumerable query methods. For example, the following is the comparison of the sequential and parallel generation query methods Range/Repeat:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count);

        public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);

        // Other members.
    }

    public static class ParallelEnumerable
    {
        public static ParallelQuery&amp;lt;int&amp;gt; Range(int start, int count);

        public static ParallelQuery&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following are the sequential and parallel Where/Select/Concat/Cast methods side by side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);

        public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);
    }

    public static class ParallelEnumerable
    {
        public static ParallelQuery&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static ParallelQuery&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        public static ParallelQuery&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; first, ParallelQuery&amp;lt;TSource&amp;gt; second);

        public static ParallelQuery&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this ParallelQuery source);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For each query method, the type of generic source sequence and result sequence is simply replaced by ParallelQuery&amp;lt;T&amp;gt;, the type of non-generic sequence is replaced by ParallelQuery, and other parameter types remain the same. Similarly, the following are the ordering methods side by side, where the type of ordered source sequence and result sequence is replaced by IOrderedQueryable&amp;lt;T&amp;gt;, and, again, the key selector callback function is replaced by expression tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
    }

    public static class ParallelEnumerable
    {
        public static OrderedParallelQuery&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static OrderedParallelQuery&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static OrderedParallelQuery&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this OrderedParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static OrderedParallelQuery&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this OrderedParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this design, the fluent method chaining, and the LINQ query expression pattern is implemented for Parallel LINQ queries.&lt;/p&gt;
&lt;p&gt;Besides Enumerable parities, ParallelEnumerable also provides additional methods and additional overrides for Aggregate method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sequence queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ordering: AsOrdered, AsUnordered&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conversion: AsParallel, AsSequential&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Settings: WithCancellation, WithDegreeOfParallelism, WithExecutionMode, WithMergeOptions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Value queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: Aggregate&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Void queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Iteration: ForAll&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are covered in this part and the next parts.&lt;/p&gt;
&lt;h2&gt;Parallel vs. sequential query&lt;/h2&gt;
&lt;p&gt;A ParallelQuery&amp;lt;T&amp;gt; instance can be created by calling generation methods of ParallelEnumerable, like Range, Repeat, etc., then the parallel query methods can be called fluently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Generation()
{
    IEnumerable&amp;lt;double&amp;gt; sequentialQuery = Enumerable
        .Repeat(0, 5) // Return IEnumerable&amp;lt;int&amp;gt;.
        .Concat(Enumerable.Range(0, 5)) // Enumerable.Concat.
        .Where(int32 =&amp;gt; int32 &amp;gt; 0) // Enumerable.Where.
        .Select(int32 =&amp;gt; Math.Sqrt(int32)); //  Enumerable.Select.

    ParallelQuery&amp;lt;double&amp;gt; parallelQuery = ParallelEnumerable
        .Repeat(0, 5) // Return ParallelQuery&amp;lt;int&amp;gt;.
        .Concat(ParallelEnumerable.Range(0, 5)) // ParallelEnumerable.Concat.
        .Where(int32 =&amp;gt; int32 &amp;gt; 0) // ParallelEnumerable.Where.
        .Select(int32 =&amp;gt; Math.Sqrt(int32)); // ParallelEnumerable.Select.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can also be created by calling ParallelEnumerable.AsParallel for IEnumerable&amp;lt;T&amp;gt; or IEnumerable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ParallelQuery AsParallel(this IEnumerable source);

public static ParallelQuery&amp;lt;TSource&amp;gt; AsParallel&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsParallel(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable source2)
{
    ParallelQuery&amp;lt;int&amp;gt; parallelQuery1 = source1 // IEnumerable&amp;lt;int&amp;gt;.
        .AsParallel(); // Return ParallelQuery&amp;lt;int&amp;gt;.

    ParallelQuery&amp;lt;int&amp;gt; parallelQuery2 = source2 // IEnumerable.
        .AsParallel() // Return ParallelQuery.
        .Cast&amp;lt;int&amp;gt;(); // ParallelEnumerable.Cast.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsParallel also has a overload accepting a partitioner, which is discussed later in this chapter.&lt;/p&gt;
&lt;p&gt;To apply sequential query methods to a ParallelQuery&amp;lt;T&amp;gt; instance, just call ParallelEnumerable.AsSequential method, which returns ]IEnumerable&amp;lt;T&amp;gt;, from where the sequential query methods can be called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsSequential&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
{
    private static readonly Assembly CoreLibrary = typeof(object).Assembly;

    internal static void SequentialParallel()
    {
        IEnumerable&amp;lt;string&amp;gt; obsoleteTypes = CoreLibrary.GetExportedTypes() // Return IEnumerable&amp;lt;Type&amp;gt;.
            .AsParallel() // Return ParallelQuery&amp;lt;Type&amp;gt;.
            .Where(type =&amp;gt; type.GetCustomAttribute&amp;lt;ObsoleteAttribute&amp;gt;() != null) // ParallelEnumerable.Where.
            .Select(type =&amp;gt; type.FullName) // ParallelEnumerable.Select.
            .AsSequential() // Return IEnumerable&amp;lt;Type&amp;gt;.
            .OrderBy(name =&amp;gt; name); // Enumerable.OrderBy.
        obsoleteTypes.WriteLines();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query expression version of the above query is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void QueryExpression()
{
    IEnumerable&amp;lt;string&amp;gt; obsoleteTypes =
        from name in
            (from type in CoreLibrary.GetExportedTypes().AsParallel()
             where type.GetCustomAttribute&amp;lt;ObsoleteAttribute&amp;gt;() != null
             select type.FullName).AsSequential()
        orderby name
        select name;
    obsoleteTypes.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Parallel LINQ, ParallelEnumerable.AsEnumerable calls AsSequential to do the same work.&lt;/p&gt;
&lt;h2&gt;Execute parallel query&lt;/h2&gt;
&lt;p&gt;As demonstrated in LINQ to Objects chapter, Interactive Extension (Ix) provides a useful EnumerableEx.ForEach method, which pulls values from the source sequence, and execute the specified function for each value sequentially. Its parallel version is ParallelEnumerable.ForAll method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class EnumerableEx
    {
        public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; onNext);
    }

    public static class ParallelEnumerable
    {
        public static void ForAll&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; action);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;FoAll can pull values from ParallelQuery&amp;lt;T&amp;gt; source with multiple threads simultaneously, and call function on those threads in parallel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachForAll()
{
    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .ForEach(value =&amp;gt; value.WriteLine()); // 0 1 2 3 4 5 6 7

    ParallelEnumerable
        .Range(0, Environment.ProcessorCount * 2)
        .ForAll(value =&amp;gt; value.WriteLine()); // 2 6 4 0 5 3 7 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above is the output after executing the code in a quad core CPU, ForAll can output the values in different order from ForEach. And if this code is executed multiple times, the order can be different from time to time. Apparently, this is the consequence of parallel pulling. The parallel query execution and values’ order preservation is discussed in detail later.&lt;/p&gt;
&lt;p&gt;The following ForAll overload can be defined to simply execute parallel query without calling a function for each query result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ParallelEnumerableX
{
    public static void ForAll&amp;lt;TSource&amp;gt;(this ParallelQuery&amp;lt;TSource&amp;gt; source) =&amp;gt; source.ForAll(value =&amp;gt; { });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Visualize parallel query execution&lt;/h2&gt;
&lt;h3&gt;Install and configure Concurrency Visualizer&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;It would be nice if the internal execution of sequential/parallel LINQ queries can be visualized. This can be done in variant ways. On Windows, Microsoft has released a tool &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd537632.aspx&quot;&gt;Concurrency Visualizer&lt;/a&gt; for this purpose. It is an extension of Visual Studio. It provides APIs to trace the execution information at the runtime. When the execution is done, it generates charts and diagrams with the collected tracing. After the installation, restart Visual Studio, go to Analyze =&amp;gt; Concurrency Visualizer =&amp;gt; Advanced Settings:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb4_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb4_thumb.png&quot; alt=&quot;image_thumb4&quot; title=&quot;image_thumb4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the Filter tab, check Sample Events only:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb8_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb8_thumb.png&quot; alt=&quot;image_thumb8&quot; title=&quot;image_thumb8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then go to Markers tab, check ConcurrencyVisualizer.Markers only:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb9_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb9_thumb.png&quot; alt=&quot;image_thumb9&quot; title=&quot;image_thumb9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Files tab, specified a proper directory for trace files. Notice the trace files can be very large, depends on how much information is collected.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb10_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb10_thumb.png&quot; alt=&quot;image_thumb10&quot; title=&quot;image_thumb10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Visualize sequential and parallel LINQ queries&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Next, add a reference to Concurrency Visualizer library. which is a &lt;a href=&quot;https://www.microsoft.com/en-in/download/details.aspx?id=49103&quot;&gt;binary for downloading&lt;/a&gt;. For convenience, a NuGget package ConcurrencyVisualizer has been created for this tutorial. The following APIs are provided to draw timespans on the time line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace Microsoft.ConcurrencyVisualizer.Instrumentation
{
    public static class Markers
    {
        public static Span EnterSpan(int category, string text);
    }

    public class MarkerSeries
    {
        public static Span EnterSpan(int category, string text);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The category parameter is used to determine the color of the timespan, and the span parameter becomes the text label for the timespan.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In .NET Core, this tool and SDK library are not available, so manually define these APIs to trace text information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Markers
{
    public static Span EnterSpan(int category, string spanName) =&amp;gt; new Span(category, spanName);

    public static MarkerSeries CreateMarkerSeries(string markSeriesName) =&amp;gt; new MarkerSeries(markSeriesName);
}

public class Span : IDisposable
{
    private readonly int category;

    private readonly string spanName;

    private readonly DateTime start;

    public Span(int category, string spanName, string markSeriesName = null)
    {
        this.category = category;
        this.spanName = string.IsNullOrEmpty(markSeriesName) ? spanName : $@&quot;{markSeriesName}/{spanName}&quot;;
        this.start = DateTime.Now;
        $&quot;{this.start.ToString(&quot;o&quot;)}: thread id: {Thread.CurrentThread.ManagedThreadId}, category: {this.category}, span: {this.spanName}&quot;
            .WriteLine();
    }

    public void Dispose()
    {
        DateTime end = DateTime.Now;
        $&quot;{end.ToString(&quot;o&quot;)}: thread id: {Thread.CurrentThread.ManagedThreadId}, category: {this.category}, span: {this.spanName}, duration: {end - start}&quot;
            .WriteLine();
    }
}

public class MarkerSeries
{
    private readonly string markSeriesName;

    public MarkerSeries(string markSeriesName) =&amp;gt; this.markSeriesName = markSeriesName;

    public Span EnterSpan(int category, string spanName) =&amp;gt; new Span(category, spanName, markSeriesName);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example calls these APIs to trace/visualize the sequence and parallel LINQ query execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachForAllTimeSpans()
{
    string sequentialTimeSpanName = nameof(EnumerableEx.ForEach);
    // Render a timespan for the entire sequential LINQ query execution, with text label &quot;ForEach&quot;.
    using (Markers.EnterSpan(-1, sequentialTimeSpanName))
    {
        MarkerSeries markerSeries = Markers.CreateMarkerSeries(sequentialTimeSpanName);
        Enumerable.Range(0, Environment.ProcessorCount * 2).ForEach(value =&amp;gt;
        {
            // Render a sub timespan for each action execution, with each value as text label.
            using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
            {
                // Add workload to extend the action execution to a more visible timespan.
                Enumerable.Range(0, 10_000_000).ForEach();
                value.WriteLine();
            }
        });
    }

    string parallelTimeSpanName = nameof(ParallelEnumerable.ForAll);
    // Render a timespan for the entire parallel LINQ query execution, with text label &quot;ForAll&quot;.
    using (Markers.EnterSpan(-2, parallelTimeSpanName))
    {
        MarkerSeries markerSeries = Markers.CreateMarkerSeries(parallelTimeSpanName);
        ParallelEnumerable.Range(0, Environment.ProcessorCount * 2).ForAll(value =&amp;gt;
        {
            // Render a sub timespan for each action execution, with each value as text label.
            using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
            {
                // Add workload to extends the action execution to a more visible timespan.
                Enumerable.Range(0, 10_000_000).ForEach();
                value.WriteLine();
            }
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the functions which are passed to ForEach and ForAll, a foreach loop over a sequence with 10 million values adds some workload to make the function call take longer time, otherwise the function execution timespan looks too tiny in the visualization. Now, setup a trace listener and call the above method to visualize the execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceToFile()
{
    // Trace to file:
    string file = Path.Combine(Path.GetTempPath(), &quot;Trace.txt&quot;);
    using (TextWriterTraceListener traceListener = new TextWriterTraceListener(file))
    // Or trace to console:
    // using (TextWriterTraceListener traceListener = new TextWriterTraceListener(Console.Out))
    {
        Trace.Listeners.Add(traceListener);
        QueryMethods.ForEachForAllTimeSpans();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;On Windows, click Visual Studio =&amp;gt; Analyze =&amp;gt; Concurrency Visualizer =&amp;gt; Start with Current Project. When the console application finishes running, a rich trace UI is generated. The first tab Utilization shows that the CPU usage was about 25% for a while, which seems to be the sequential LINQ query executing on the quad core CPU. Then the CPU usage became almost 100%, which seems to be the Parallel LINQ execution.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb3_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb3_thumb.png&quot; alt=&quot;image_thumb3&quot; title=&quot;image_thumb3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The second tab Threads proves this. In the thread list on the left, right click the threads not working on LINQ queries and hide them, the view becomes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It uncovers how the LINQ queries execute on this quad core CPU. ForEach query pulls the values and call the specified function sequentially, with the main thread. ForAll query does the work with 4 threads (main threads and 3 other threads), each thread processed 2 values. The values 6, 0, 4, 2 is processed before 7, 1, 5, 3, which leads to the trace output: 2 6 4 0 5 3 7 1.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Click the ForEach timespan, the Current panel shows the execution duration is 4750 milliseconds. Click ForAll, it shows 1314 milliseconds:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is about 27% of ForEach execution time, close a quarter, as expected. It cannot be exactly 25%, because On the device, there are other running processes and threads using CPU, also the parallel query has extra work to manage multithreading, which is covered later in this chapter.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the last tab Cores, select the LINQ query threads 9884, 12360, 11696, and 6760. It shows how the workload is distributed in the 4 cores:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb41_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb41_thumb.png&quot; alt=&quot;image_thumb41&quot; title=&quot;image_thumb41&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Above LINQ visualization code looks noisy, because it mixes the LINQ query and the tracing/visualizing. Regarding the Single Responsibility Principle, the tracing/visualizing logics can be encapsulated for reuse. The following methods wraps the tracing calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Visualizer
{
    internal const string Parallel = nameof(Parallel);

    internal const string Sequential = nameof(Sequential);

    internal static void Visualize&amp;lt;TSource&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; action, string span = Sequential, int category = -1)
    {
        using (Markers.EnterSpan(category, span))
        {
            MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
            source.ForEach(value =&amp;gt;
            {
                using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
                {
                    action(value);
                }
            });
        }
    }

    internal static void Visualize&amp;lt;TSource&amp;gt;(
        this ParallelQuery&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; action, string span = Parallel, int category = -2)
    {
        using (Markers.EnterSpan(category, span))
        {
            MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
            source.ForAll(value =&amp;gt;
            {
                using (markerSeries.EnterSpan(Thread.CurrentThread.ManagedThreadId, value.ToString()))
                {
                    action(value);
                }
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the LINQ queries can be visualized in a much cleaner way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void VisualizeForEachForAll()
{
    Enumerable
        .Range(0, Environment.ProcessorCount * 2)
        .Visualize(value =&amp;gt;
        {
            Enumerable.Range(0, 10_000_000).ForEach(); // Workload.
            value.WriteLine();
        });

    ParallelEnumerable
        .Range(0, Environment.ProcessorCount * 2)
        .Visualize(value =&amp;gt;
        {
            Enumerable.Range(0, 10_000_000).ForEach(); // Workload.
            value.WriteLine();
        });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Visualize chaining query methods&lt;/h3&gt;
&lt;p&gt;Besides visualizing function calls for ForEach and ForAll, the following Visualize overloads can be defined to visualize sequential and parallel query methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; Visualize&amp;lt;TSource, TMiddle, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, Func&amp;lt;TSource, TMiddle&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; query,
    Func&amp;lt;TSource, TMiddle&amp;gt; func,
    Func&amp;lt;TSource, string&amp;gt; spanFactory = null,
    string span = Sequential)
{
    MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
    return query(
        source,
        value =&amp;gt;
        {
            using (markerSeries.EnterSpan(
                Thread.CurrentThread.ManagedThreadId, spanFactory?.Invoke(value) ?? value.ToString()))
            {
                return func(value);
            }
        });
}

internal static ParallelQuery&amp;lt;TResult&amp;gt; Visualize&amp;lt;TSource, TMiddle, TResult&amp;gt;(
    this ParallelQuery&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;ParallelQuery&amp;lt;TSource&amp;gt;, Func&amp;lt;TSource, TMiddle&amp;gt;, ParallelQuery&amp;lt;TResult&amp;gt;&amp;gt; query,
    Func&amp;lt;TSource, TMiddle&amp;gt; func,
    Func&amp;lt;TSource, string&amp;gt; spanFactory = null,
    string span = Parallel)
{
    MarkerSeries markerSeries = Markers.CreateMarkerSeries(span);
    return query(
        source,
        value =&amp;gt;
        {
            using (markerSeries.EnterSpan(
                Thread.CurrentThread.ManagedThreadId, spanFactory?.Invoke(value) ?? value.ToString()))
            {
                return func(value);
            }
        });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following method encapsulates the workload generation according to the input value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static int ComputingWorkload(int value = 0, int iteration = 10_000_000)
    {
        Enumerable.Range(0, iteration * (value + 1)).ForEach();
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take a simple Where and Select query chaining as example,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// using static Functions;
internal static void WhereSelect()
{
    Enumerable
        .Range(0, 2)
        .Visualize(Enumerable.Where, _ =&amp;gt; ComputingWorkload() &amp;gt;= 0, value =&amp;gt; $&quot;{nameof(Enumerable.Where)} {value}&quot;)
        .Visualize(Enumerable.Select, _ =&amp;gt; ComputingWorkload(), value =&amp;gt; $&quot;{nameof(Enumerable.Select)} {value}&quot;)
        .ForEach();

    ParallelEnumerable
        .Range(0, Environment.ProcessorCount * 2)
        .Visualize(
            ParallelEnumerable.Where,
            _ =&amp;gt; ComputingWorkload() &amp;gt;= 0,
            value =&amp;gt; $&quot;{nameof(ParallelEnumerable.Where)} {value}&quot;)
        .Visualize(
            ParallelEnumerable.Select,
            _ =&amp;gt; ComputingWorkload(),
            value =&amp;gt; $&quot;{nameof(ParallelEnumerable.Select)} {value}&quot;)
        .ForAll();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The sequential and parallel queries are visualized as:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb11_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Parallel-LINQ-1-Local-Parallel-Query-and_8DE9/image_thumb11_thumb.png&quot; alt=&quot;image_thumb11&quot; title=&quot;image_thumb11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This visualizing approach will be used for the entire chapter to demonstrate parallel LINQ queries.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (3) Manipulating XML</title><link>https://dixin.github.io/posts/linq-to-xml-3-manipulating-xml-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-3-manipulating-xml-7/</guid><description>Besides creating and querying XML, LINQ to XML also provides APIs for other XML manipulations, including cloning, deleting, replacing, and updating XML structures:</description><pubDate>Thu, 30 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-xml-3-manipulating-xml&quot;&gt;https://weblogs.asp.net/dixin/linq-to-xml-3-manipulating-xml&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Besides creating and querying XML, LINQ to XML also provides APIs for other XML manipulations, including cloning, deleting, replacing, and updating XML structures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Clone&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explicit Clone: constructors of XAttribute, XCData, XComment, XDeclaration, XDocument, XElement, XProcessingInstruction, XText&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add annotations: XObject.AddAnnotation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add children: XContainer.Add, XContainer.AddFirst, XStreamingElement.Add&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add siblings: XNode.AddAfterSelf, XNode.AddBeforeSelf&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete annotations: XObject.RemoveAnnotations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete attributes: XElement.RemoveAttributes, XAttribute.Remove&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete self: XNode.Remove&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete children: XContainer.RemoveNodes, XElement.RemoveAll&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace attributes: XElement.ReplaceAttributes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace self: XNode.ReplaceWith&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace children: XContainer.ReplaceNodes, XElement.ReplaceAll&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update attribute: XAttribute.Value&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update comment: XComment.Value&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update declaration: XDeclaration.Encoding, XDeclaration.Standalone, XDeclaration.Version&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update document: XDocument.XDeclaration, XDocumentType.InternalSubset, XDocumentType.Name, XDocumentType.PublicId, XDocumentType.SystemId&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update element: XElement.Name, XElement.Value, XElement.SetAttributeValue, XElement.SetElementValue, XElement.SetValue&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;.NET Framework also provides APIs for validating and transforming XML:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Validate with XSD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query schema: XAttribute.GetSchemaInfo*, XElement.GetSchemaInfo*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate schema: XAttribute.Validate*, XDocument.Validate*, XElement.Validate*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transform with XSL: XslCompiledTransform.Transform&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The APIs with * are extension methods provided by System.Xml.Schema.Extensions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Clone&lt;/h2&gt;
&lt;p&gt;Most structures can be cloned by calling their constructors with the source instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExplicitClone()
{
    XElement sourceElement = XElement.Parse(&quot;&amp;lt;element /&amp;gt;&quot;);
    XElement clonedElement = new XElement(sourceElement);

    XText sourceText = new XText(&quot;text&quot;);
    XText clonedText = new XText(sourceText);

    XDocument sourceDocument = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XDocument clonedDocument = new XDocument(sourceDocument);
    object.ReferenceEquals(sourceDocument, clonedDocument).WriteLine(); // False
    object.Equals(sourceDocument, clonedDocument).WriteLine(); // False
    EqualityComparer&amp;lt;XDocument&amp;gt;.Default.Equals(sourceDocument, clonedDocument).WriteLine(); // False
    sourceDocument.Equals(clonedDocument).WriteLine(); // False
    (sourceDocument == clonedDocument).WriteLine(); // False
    XNode.DeepEquals(sourceDocument, clonedDocument).WriteLine(); // True
    XNode.EqualityComparer.Equals(sourceDocument, clonedDocument).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an XObject instance is in an XML tree, when it is added to a different XML tree, it is cloned, and the new instance is actually added to the target. The exceptions are XName and XNamespace, which are cached at runtime. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ImplicitClone()
{
    XElement child = XElement.Parse(&quot;&amp;lt;child /&amp;gt;&quot;);
    XName parentName = &quot;parent&quot;;
    XElement parent1 = new XElement(parentName, child); // Attach.
    object.ReferenceEquals(child, parent1.Elements().Single()).WriteLine(); // True
    object.ReferenceEquals(parentName, parent1.Name).WriteLine(); // True

    XElement parent2 = new XElement(parentName, child); // Clone and attach.
    object.ReferenceEquals(child, parent2.Elements().Single()).WriteLine(); // False
    object.ReferenceEquals(parentName, parent2.Name).WriteLine(); // True

    XElement element = new XElement(&quot;element&quot;);
    element.Add(element); // Clone and attach.
    object.ReferenceEquals(element, element.Elements().Single()).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Add, delete, replace, update, and events&lt;/h2&gt;
&lt;p&gt;Most of APIs to add/replace/delete/update XML structures are very intuitive. And when changing a XObject instance, XObject.Changing and XObject.Changed events are fired before and after the change. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Manipulate()
{
    XElement child = new XElement(&quot;child&quot;);
    child.Changing += (sender, e) =&amp;gt; 
        $&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {child}&quot;.WriteLine();
    child.Changed += (sender, e) =&amp;gt; 
        $&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {child}&quot;.WriteLine();
    XElement parent = new XElement(&quot;parent&quot;);
    parent.Changing += (sender, e) =&amp;gt; 
        $&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
    parent.Changed += (sender, e) =&amp;gt; 
        $&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();

    child.Value = &quot;value1&quot;;
    // Before Add: (XText value1) =&amp;gt; &amp;lt;child /&amp;gt;
    // After Add: (XText value1) =&amp;gt; &amp;lt;child&amp;gt;value1&amp;lt;/child&amp;gt;

    child.Value = &quot;value2&quot;;
    // Before Remove: (XText value1) =&amp;gt; &amp;lt;child&amp;gt;value1&amp;lt;/child&amp;gt;
    // After Remove: (XText value1) =&amp;gt; &amp;lt;child /&amp;gt;
    // Before Add: (XText value2) =&amp;gt; &amp;lt;child /&amp;gt;
    // After Add: (XText value2) =&amp;gt; &amp;lt;child&amp;gt;value2&amp;lt;/child&amp;gt;

    child.Value = string.Empty;
    // Before Remove: (XText value2) =&amp;gt; &amp;lt;child&amp;gt;value2&amp;lt;/child&amp;gt;
    // After Remove: (XText value2) =&amp;gt; &amp;lt;child /&amp;gt;
    // Before Value: (XElement &amp;lt;child /&amp;gt;) =&amp;gt; &amp;lt;child /&amp;gt;
    // After Value: (XElement &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;

    parent.Add(child);
    // Before Add: (XElement &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent /&amp;gt;
    // After Add: (XElement &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    child.Add(new XAttribute(&quot;attribute&quot;, &quot;value&quot;));
    // Before Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;
    // Before Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;
    // After Add: (XAttribute attribute=&quot;value&quot;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    child.AddBeforeSelf(0);
    // Before Add: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Add: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;0&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    parent.ReplaceAll(new XText(&quot;Text.&quot;));
    // Before Remove: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;0&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Remove: (XText 0) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // Before Remove: (XElement &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Remove: (XElement &amp;lt;child attribute=&quot;value&quot;&amp;gt;&amp;lt;/child&amp;gt;) =&amp;gt; &amp;lt;parent /&amp;gt;
    // Before Add: (XText Text.) =&amp;gt; &amp;lt;parent /&amp;gt;
    // After Add: (XText Text.) =&amp;gt; &amp;lt;parent&amp;gt;Text.&amp;lt;/parent&amp;gt;

    parent.Name = &quot;name&quot;;
    // Before Name: (XElement &amp;lt;parent&amp;gt;Text.&amp;lt;/parent&amp;gt;) =&amp;gt; &amp;lt;parent&amp;gt;Text.&amp;lt;/parent&amp;gt;
    // After Name: (XElement &amp;lt;name&amp;gt;Text.&amp;lt;/name&amp;gt;) =&amp;gt; &amp;lt;name&amp;gt;Text.&amp;lt;/name&amp;gt;

    XElement clonedChild = new XElement(child);
    clonedChild.SetValue(DateTime.Now); // No tracing.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are many APIs to manipulate XML, but there are only 4 kinds of Changing/Changed events: add object, deleting object, update object value, update element/attribute name. For example, as shown above, the APIs to replace objects are shortcuts of deleting old objects and adding new objects. When setting a string as an element’s value, the element first removes its children if there is any, then add the string as a child text node, if the string is not empty string. Also, an object’s events propagate/bubble up to the ancestors, and children and siblings are not impacted. When an object is cloned, the new object’s events is not observed by the original event handlers.&lt;/p&gt;
&lt;p&gt;XElement.SetAttributeValue and XElement.SetElementValue are different from other APIs. They can&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add a new attribute/child element if it does not exist&lt;/li&gt;
&lt;li&gt;update the attribute/child element value if it exists:&lt;/li&gt;
&lt;li&gt;remove the attribute/child element if it exists and the provided value to null.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void SetAttributeValue()
{
    XElement element = new XElement(&quot;element&quot;);
    element.Changing += (sender, e) =&amp;gt; 
        $&quot;Before {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {element}&quot;.WriteLine();
    element.Changed += (sender, e) =&amp;gt; 
        $&quot;After {e.ObjectChange}: ({sender.GetType().Name} {sender}) =&amp;gt; {element}&quot;.WriteLine();

    element.SetAttributeValue(&quot;attribute&quot;, &quot;value1&quot;); // Equivalent to: child1.Add(new XAttribute(&quot;attribute&quot;, &quot;value1&quot;));
    // Before Add: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element /&amp;gt;
    // After Add: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value1&quot; /&amp;gt;

    element.SetAttributeValue(&quot;attribute&quot;, &quot;value2&quot;); // Equivalent to: child1.Attribute(&quot;attribute&quot;).Value = &quot;value2&quot;;
    // Before Value: (XAttribute attribute=&quot;value1&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value1&quot; /&amp;gt;
    // After Value: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value2&quot; /&amp;gt;

    element.SetAttributeValue(&quot;attribute&quot;, null);
    // Before Remove: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element attribute=&quot;value2&quot; /&amp;gt;
    // After Remove: (XAttribute attribute=&quot;value2&quot;) =&amp;gt; &amp;lt;element /&amp;gt;
}

internal static void SetElementValue()
{
    XElement parent = new XElement(&quot;parent&quot;);
    parent.Changing += (sender, e) =&amp;gt; 
        $&quot;Before {e.ObjectChange}: {sender} =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();
    parent.Changed += (sender, e) =&amp;gt; 
        $&quot;After {e.ObjectChange}: {sender} =&amp;gt; {parent.ToString(SaveOptions.DisableFormatting)}&quot;.WriteLine();

    parent.SetElementValue(&quot;child&quot;, string.Empty); // Add child element.
    // Before Add: &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent /&amp;gt;
    // After Add: &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    parent.SetElementValue(&quot;child&quot;, &quot;value&quot;); // Update child element.
    // Before Value: &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Value: &amp;lt;child /&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
    // Before Add: value =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
    // After Add: value =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    parent.SetElementValue(&quot;child&quot;, null); // Remove child element.
    // Before Remove: &amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    // After Remove: &amp;lt;child&amp;gt;value&amp;lt;/child&amp;gt; =&amp;gt; &amp;lt;parent /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Annotation&lt;/h2&gt;
&lt;p&gt;Annotation is not a part of the XML. It is an separate arbitrary data in the memory, and associated with a XObject instance in the memory. The annotation APIs provided by XObject allows adding/querying/deleting any .NET data. Apparently, when cloning or serializing XObject, annotation is ignored on the the new XObject and the generated string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Annotation()
{
    XElement element = new XElement(&quot;element&quot;);
    element.AddAnnotation(new Uri(&quot;https://microsoft.com&quot;));

    Uri annotation = element.Annotation&amp;lt;Uri&amp;gt;();
    annotation.WriteLine(); // https://microsoft.com
    element.WriteLine(); // &amp;lt;element /&amp;gt;

    XElement clone = new XElement(element); // element is cloned.
    clone.Annotations&amp;lt;Uri&amp;gt;().Any().WriteLine(); // False

    element.RemoveAnnotations&amp;lt;Uri&amp;gt;();
    (element.Annotation&amp;lt;Uri&amp;gt;() == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Validate XML with XSD&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/XML_Schema_(W3C)&quot;&gt;XSD (XML Schema Definition)&lt;/a&gt; is the metadata of XML tree, including XML&apos;s elements, attributes, constrains rules, etc. System.Xml.Schema.Extensions provides a few APIs to validate XML with provided schema. To obtain a schema, one option is to infer it from existing XML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static XmlSchemaSet InferSchema(this XNode source)
{
    XmlSchemaInference schemaInference = new XmlSchemaInference();
    using (XmlReader reader = source.CreateReader())
    {
        return schemaInference.InferSchema(reader);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The returned XmlSchemaSet instance contains s sequence of XmlSchema instances, one for each namespace in the source XML. XmlSchema can be converted to XDocument with the help of XmlWriter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static XDocument ToXDocument(this XmlSchema source)
{
    XDocument document = new XDocument();
    using (XmlWriter writer = document.CreateWriter())
    {
        source.Write(writer);
    }
    return document;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still take an RSS feed as example, the following code outputs the RSS feed’s schema:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InferSchemas()
{
    XDocument aspNetRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    XmlSchemaSet schemaSet = aspNetRss.InferSchema();
    schemaSet.Schemas().Cast&amp;lt;XmlSchema&amp;gt;().WriteLines(schema =&amp;gt; schema.ToXDocument().ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The printed schema is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;xs:schema attributeFormDefault=&quot;unqualified&quot; elementFormDefault=&quot;qualified&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&amp;gt;
  &amp;lt;xs:element name=&quot;rss&quot;&amp;gt;
    &amp;lt;xs:complexType&amp;gt;
      &amp;lt;xs:sequence&amp;gt;
        &amp;lt;xs:element name=&quot;channel&quot;&amp;gt;
          &amp;lt;xs:complexType&amp;gt;
            &amp;lt;xs:sequence&amp;gt;
              &amp;lt;xs:element name=&quot;title&quot; type=&quot;xs:string&quot; /&amp;gt;
              &amp;lt;xs:element name=&quot;link&quot; type=&quot;xs:string&quot; /&amp;gt;
              &amp;lt;xs:element name=&quot;description&quot; type=&quot;xs:string&quot; /&amp;gt;
              &amp;lt;xs:element maxOccurs=&quot;unbounded&quot; name=&quot;item&quot;&amp;gt;
                &amp;lt;xs:complexType&amp;gt;
                  &amp;lt;xs:sequence&amp;gt;
                    &amp;lt;xs:element name=&quot;title&quot; type=&quot;xs:string&quot; /&amp;gt;
                    &amp;lt;xs:element name=&quot;link&quot; type=&quot;xs:string&quot; /&amp;gt;
                    &amp;lt;xs:element name=&quot;description&quot; type=&quot;xs:string&quot; /&amp;gt;
                    &amp;lt;xs:element name=&quot;pubDate&quot; type=&quot;xs:string&quot; /&amp;gt;
                    &amp;lt;xs:element name=&quot;guid&quot;&amp;gt;
                      &amp;lt;xs:complexType&amp;gt;
                        &amp;lt;xs:simpleContent&amp;gt;
                          &amp;lt;xs:extension base=&quot;xs:string&quot;&amp;gt;
                            &amp;lt;xs:attribute name=&quot;isPermaLink&quot; type=&quot;xs:boolean&quot; use=&quot;required&quot; /&amp;gt;
                          &amp;lt;/xs:extension&amp;gt;
                        &amp;lt;/xs:simpleContent&amp;gt;
                      &amp;lt;/xs:complexType&amp;gt;
                    &amp;lt;/xs:element&amp;gt;
                    &amp;lt;xs:element maxOccurs=&quot;unbounded&quot; name=&quot;category&quot; type=&quot;xs:string&quot; /&amp;gt;
                  &amp;lt;/xs:sequence&amp;gt;
                &amp;lt;/xs:complexType&amp;gt;
              &amp;lt;/xs:element&amp;gt;
            &amp;lt;/xs:sequence&amp;gt;
          &amp;lt;/xs:complexType&amp;gt;
        &amp;lt;/xs:element&amp;gt;
      &amp;lt;/xs:sequence&amp;gt;
      &amp;lt;xs:attribute name=&quot;version&quot; type=&quot;xs:decimal&quot; use=&quot;required&quot; /&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
  &amp;lt;/xs:element&amp;gt;
&amp;lt;/xs:schema&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The data is all gone, and there is only structural description for that RSS feed. Save it to a .xsd file, then it can be visualized in Visual Studio’s XML Schema Explorer:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/LINQ-to-XML-in-Depth-3-Manipulating-XML_8D00/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/LINQ-to-XML-in-Depth-3-Manipulating-XML_8D00/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, this RSS feed’s schema, represented by XmlSchemaSet, can be used to validate XML. The following example calls the Validate extension methods for XDocument to validate another RSS feed from Flickr. As demonstrated before, Flickr RSS has more elements. Apparently the validation fails:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Validate()
{
    XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XmlSchemaSet schemaSet = aspNetRss.InferSchema();

    XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    flickrRss.Validate(
        schemaSet,
        (sender, args) =&amp;gt;
        {
            $&quot;{args.Severity}: ({sender.GetType().Name}) =&amp;gt; {args.Message}&quot;.WriteLine();
            // Error: (XElement) =&amp;gt; The element &apos;channel&apos; has invalid child element &apos;pubDate&apos;. List of possible elements expected: &apos;item&apos;.
            args.Exception?.WriteLine();
            // XmlSchemaValidationException: The element &apos;channel&apos; has invalid child element &apos;pubDate&apos;. List of possible elements expected: &apos;item&apos;.
        });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Validate has another overload accepting a bool parameter addSchemaInfo. When it is called with true for addSchemaInfo, if an element or attribute is validated, the validation details are saved in an IXmlSchemaInfo instance, and associated with this element or attribute as an annotation. Then, the GetSchemaInfo method can be called on each element or attribute, to query that IXmlSchemaInfo annotation, if available. IXmlSchemaInfo can have a lot of information, including a Validity property, intuitively indicating the validation status:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GetSchemaInfo()
{
    XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XmlSchemaSet schemaSet = aspNetRss.InferSchema();

    XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    flickrRss.Validate(schemaSet, (sender, args) =&amp;gt; { }, addSchemaInfo: true);
    flickrRss
        .Root
        .DescendantsAndSelf()
        .ForEach(element =&amp;gt;
        {
            $&quot;{element.XPath()} - {element.GetSchemaInfo()?.Validity}&quot;.WriteLine();
            element.Attributes().WriteLines(attribute =&amp;gt; 
                $&quot;{attribute.XPath()} - {attribute.GetSchemaInfo()?.Validity.ToString() ?? &quot;null&quot;}&quot;);
        });
    // /rss - Invalid
    // /rss/@version - Valid
    // /rss/@xmlns:media - null
    // /rss/@xmlns:dc - null
    // /rss/@xmlns:creativeCommons - null
    // /rss/@xmlns:flickr - null
    // /rss/channel - Invalid
    // /rss/channel/title - Valid
    // /rss/channel/link - Valid
    // /rss/channel/description - Valid
    // /rss/channel/pubDate - Invalid
    // /rss/channel/lastBuildDate - NotKnown
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Transform XML with XSL&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/XSL&quot;&gt;XSL (Extensible Stylesheet Language)&lt;/a&gt; can transform a XML tree to another. XSL transformation can be done with the System.Xml.Xsl.XslCompiledTransform type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static XDocument XslTransform(this XNode source, XNode xsl)
{
    XDocument result = new XDocument();
    using (XmlReader sourceReader = source.CreateReader())
    using (XmlReader xslReader = xsl.CreateReader())
    using (XmlWriter resultWriter = result.CreateWriter())
    {
        XslCompiledTransform transform = new XslCompiledTransform();
        transform.Load(xslReader);
        transform.Transform(sourceReader, resultWriter);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example transforms RSS to HTML, the most recent 5 items in RSS are mapped to HTML hyperlinks in an unordered list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XslTransform()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XDocument xsl = XDocument.Parse(@&quot;
        &amp;lt;xsl:stylesheet version=&apos;1.0&apos; xmlns:xsl=&apos;http://www.w3.org/1999/XSL/Transform&apos;&amp;gt;
            &amp;lt;xsl:template match=&apos;/rss/channel&apos;&amp;gt;
            &amp;lt;ul&amp;gt;
                &amp;lt;xsl:for-each select=&apos;item[position() &amp;amp;lt;= 5]&apos;&amp;gt;&amp;lt;!--Position is less than or equal to 5.--&amp;gt;
                &amp;lt;li&amp;gt;
                    &amp;lt;a&amp;gt;
                    &amp;lt;xsl:attribute name=&apos;href&apos;&amp;gt;&amp;lt;xsl:value-of select=&apos;link&apos; /&amp;gt;&amp;lt;/xsl:attribute&amp;gt;
                    &amp;lt;xsl:value-of select=&apos;title&apos; /&amp;gt;
                    &amp;lt;/a&amp;gt;
                &amp;lt;/li&amp;gt;
                &amp;lt;/xsl:for-each&amp;gt;
            &amp;lt;/ul&amp;gt;
            &amp;lt;/xsl:template&amp;gt;
        &amp;lt;/xsl:stylesheet&amp;gt;&quot;);
    XDocument html = rss.XslTransform(xsl);
    html.WriteLine();
    // &amp;lt;ul&amp;gt;
    //  &amp;lt;li&amp;gt;
    //    &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/c-6-0-exception-filter-and-when-keyword&quot;&amp;gt;C# 6.0 Exception Filter and when Keyword&amp;lt;/a&amp;gt;
    //  &amp;lt;/li&amp;gt;
    //  &amp;lt;li&amp;gt;
    //    &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/use-fiddler-with-node-js&quot;&amp;gt;Use Fiddler with Node.js&amp;lt;/a&amp;gt;
    //  &amp;lt;/li&amp;gt;
    //  &amp;lt;li&amp;gt;
    //    &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/diskpart-problem-cannot-select-partition&quot;&amp;gt;DiskPart Problem: Cannot Select Partition&amp;lt;/a&amp;gt;
    //  &amp;lt;/li&amp;gt;
    //  &amp;lt;li&amp;gt;
    //    &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/configure-git-for-visual-studio-2015&quot;&amp;gt;Configure Git for Visual Studio 2015&amp;lt;/a&amp;gt;
    //  &amp;lt;/li&amp;gt;
    //  &amp;lt;li&amp;gt;
    //    &amp;lt;a href=&quot;https://weblogs.asp.net:443/dixin/query-operating-system-processes-in-c&quot;&amp;gt;Query Operating System Processes in C#&amp;lt;/a&amp;gt;
    //  &amp;lt;/li&amp;gt;
    // &amp;lt;/ul&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above transformation can also be done with LINQ to Objects/XML query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Transform()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XDocument html = rss
        .Element(&quot;rss&quot;)
        .Element(&quot;channel&quot;)
        .Elements(&quot;item&quot;)
        .Take(5)
        .Select(item =&amp;gt;
        {
            string link = (string)item.Element(&quot;link&quot;);
            string title = (string)item.Element(&quot;title&quot;);
            return new XElement(&quot;li&quot;, new XElement(&quot;a&quot;, new XAttribute(&quot;href&quot;, link), title));
            // Equivalent to: return XElement.Parse($&quot;&amp;lt;li&amp;gt;&amp;lt;a href=&apos;{link}&apos;&amp;gt;{title}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;);
        })
        .Aggregate(new XElement(&quot;ul&quot;), (ul, li) =&amp;gt; { ul.Add(li); return ul; }, ul =&amp;gt; new XDocument(ul));
    html.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (2) Query Methods (Operators)</title><link>https://dixin.github.io/posts/linq-to-xml-2-query-methods-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-2-query-methods-7/</guid><description>As fore mentioned, LINQ to XML is just a specialized LINQ to Objects, so all the LINQ to Objects query methods can be used in LINQ to XML queries. LINQ to XML provides many function members and other</description><pubDate>Sun, 26 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-xml-2-query-methods&quot;&gt;https://weblogs.asp.net/dixin/linq-to-xml-2-query-methods&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ to XML is just a specialized LINQ to Objects, so all the LINQ to Objects query methods can be used in LINQ to XML queries. LINQ to XML provides many function members and other methods for XML tree navigation, ordering, XPath querying, etc. The following list shows these functions and their return types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Navigation queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query direct parent element&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XObject.Parent -&amp;gt; XElement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query all ancestor elements:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.Ancestors -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.AncestorsAndSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.Ancestors* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;XElement&amp;gt;.AncestorsAndSelf* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query direct child elements&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XDocument.Root-&amp;gt; XElement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.Element -&amp;gt; XElement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.Elements -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.Elements* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query direct child nodes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.FirstNode -&amp;gt; XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.LastNode -&amp;gt; XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.Nodes -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.Nodes* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query all descendant elements&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.Descendants -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.DescendantsAndSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.Descendants* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;XElement&amp;gt;.DescendantsAndSelf* -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query all descendant nodes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer.DescendantNodes -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.DescendantNodesAndSelf =&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.DescendantNodes* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;, where T : XContainer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;XElement&amp;gt;.DescendantNodesAndSelf* -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query sibling elements&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.ElementsAfterSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.ElementsBeforeSelf -&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query sibling nodes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.PreviousNode -&amp;gt; XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.NextNode -&amp;gt; XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.NodesBeforeSelf -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.NodesAfterSelf -&amp;gt; IEnumerable&amp;lt;XNode&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query attributes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XAttribute.PreviousAttribute –&amp;gt; XAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XAttribute.NextAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.FirstAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.LastAttribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.Attribute -&amp;gt; XAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement.Attributes -&amp;gt; IEnumerable&amp;lt;XAttribute&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;XElement&amp;gt;.Attributes* -&amp;gt; IEnumerable&amp;lt;XAttribute&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query document&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XObject.Document –&amp;gt; XDocument&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query annotations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XObject.Annotation&amp;lt;T&amp;gt; –&amp;gt; T, where T : class&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XObject.Annotations –&amp;gt; IEnumerable&amp;lt;object&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ordering queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.CompareDocumentOrder -&amp;gt; int&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.IsAfter -&amp;gt; bool&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.IsBefore -&amp;gt; bool&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNodeDocumentOrderComparer.Compare -&amp;gt; int&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt;.InDocumentOrder* -&amp;gt; IEnumerable&amp;lt;T&amp;gt;, where T : XNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Comparison queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.DocumentOrderComparer –&amp;gt; XNodeDocumentOrderComparer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNodeDocumentOrderComparer.Compare –&amp;gt; int&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.EqualityComparer –&amp;gt; XNodeEqualityComparer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNodeEqualityComparer.Equals –&amp;gt; bool&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XPath queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.CreateNavigator** –&amp;gt; XPathNavigator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.XPathSelectElement** –&amp;gt; XElement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.XPathSelectElements** –&amp;gt; IEnumerable&amp;lt;XElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode.XPathEvaluate** –&amp;gt; object&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The functions with * are extension methods provided in static type System.Xml.Linq.Extensions. The functions with ** are extension methods provided in static type System.Xml.XPath.Extensions. The other methods are instance methods or properties.&lt;/p&gt;
&lt;h2&gt;Navigation&lt;/h2&gt;
&lt;p&gt;LINQ to XML provides rich APIs for navigation. And the methods returning IEnumerable&amp;lt;XObject&amp;gt; are also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb387055.aspx&quot;&gt;axis methods or axes&lt;/a&gt;. The following example queries the parent element and ancestor element, where. ancestors are parent, parent’s parent, …, recursively:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
{
    internal static void ParentAndAncestors()
    {
        XElement element = new XElement(&quot;element&quot;);
        new XDocument(new XElement(&quot;grandparent&quot;, new XElement(&quot;parent&quot;, element)));

        element.Parent.Name.WriteLine(); // parent
        element
            .Ancestors()
            .Select(ancestor =&amp;gt; ancestor.Name)
            .WriteLines(); // parent grandparent
        element
            .AncestorsAndSelf()
            .Select(selfOrAncestor =&amp;gt; selfOrAncestor.Name)
            .WriteLines(); // element parent grandparent
        object.ReferenceEquals(element.Ancestors().Last(), element.Document.Root).WriteLine(); // True.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice AncestorsAndSelf method yields self first, then yields ancestors recursively. It could be more intuitive if named as SelfAndAncestors.&lt;/p&gt;
&lt;p&gt;The following example queries direct child elements. In RSS feed, each &amp;lt;item&amp;gt; can have 0, 1, or multiple tags. And these tags are &amp;lt;category&amp;gt; elements under each &amp;lt;item&amp;gt; element. The following code queries a given RSS feed to get the items with a permalink, then queries the top 5 tags used by these items:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ChildElements()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    IEnumerable&amp;lt;string&amp;gt; categories = rss
        .Root // &amp;lt;rss&amp;gt;.
        .Element(&quot;channel&quot;) // Single &amp;lt;channel&amp;gt; under &amp;lt;rss&amp;gt;.
        .Elements(&quot;item&quot;) // All &amp;lt;item&amp;gt;s under single &amp;lt;channel&amp;gt;.
        .Where(item =&amp;gt; (bool)item
            .Element(&quot;guid&quot;) // Single &amp;lt;guid&amp;gt; under each &amp;lt;item&amp;gt;
            .Attribute(&quot;isPermaLink&quot;)) // isPermaLink attribute of &amp;lt;guid&amp;gt;.
        .Elements(&quot;category&quot;) // All &amp;lt;category&amp;gt;s under all &amp;lt;item&amp;gt;s.
        .GroupBy(
            keySelector: category =&amp;gt; (string)category, // String value of each &amp;lt;category&amp;gt;.
            elementSelector: category =&amp;gt; category,
            resultSelector: (key, group) =&amp;gt; new { Name = key, Count = group.Count() },
            comparer: StringComparer.OrdinalIgnoreCase)
        .OrderByDescending(category =&amp;gt; category.Count)
        .Take(5)
        .Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;);
    string.Join(&quot; &quot;, categories).WriteLine();
    // [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to ancestors, descendants are children, children’s children, …, recursively:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ChildrenAndDescendants()
{
    XElement root = XElement.Parse(@&quot;
        &amp;lt;root&amp;gt;
            &amp;lt;![CDATA[cdata]]&amp;gt;0&amp;lt;!--Comment--&amp;gt;
            &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
            &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
        &amp;lt;/root&amp;gt;&quot;);

    root.Elements()
        .WriteLines(element =&amp;gt; element.ToString(SaveOptions.DisableFormatting));
    // &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
    // &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;

    root.Nodes()
        .WriteLines(node =&amp;gt; $&quot;{node.NodeType}: {node.ToString(SaveOptions.DisableFormatting)}&quot;);
    // CDATA: &amp;lt;![CDATA[cdata]]&amp;gt;
    // Text: 0
    // Comment: &amp;lt;!--Comment--&amp;gt;
    // Element: &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
    // Element: &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;

    root.Descendants()
        .WriteLines(element =&amp;gt; element.ToString(SaveOptions.DisableFormatting));
    // &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
    // &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
    // &amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;

    root.DescendantNodes()
        .WriteLines(node =&amp;gt; $&quot;{node.NodeType}: {node.ToString(SaveOptions.DisableFormatting)}&quot;);
    // CDATA: &amp;lt;![CDATA[cdata]]&amp;gt;
    // Text: 0
    // Comment: &amp;lt;!--Comment--&amp;gt;
    // Element: &amp;lt;element&amp;gt;1&amp;lt;/element&amp;gt;
    // Text: 1
    // Element: &amp;lt;element&amp;gt;2&amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;&amp;lt;/element&amp;gt;
    // Text: 2
    // Element: &amp;lt;element&amp;gt;3&amp;lt;/element&amp;gt;
    // Text: 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regarding all the X* types are reference types, when querying the same XML tree, multiple queries’ results from the same source tree can reference to the same instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ResultReferences()
{
    XDocument rss1 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XElement[] items1 = rss1.Descendants(&quot;item&quot;).ToArray();
    XElement[] items2 = rss1.Element(&quot;rss&quot;).Element(&quot;channel&quot;).Elements(&quot;item&quot;).ToArray();
    object.ReferenceEquals(items1.First(), items2.First()).WriteLine(); // True
    items1.SequenceEqual(items2).WriteLine(); // True

    XDocument rss2 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XElement[] items3 = rss2.Root.Descendants(&quot;item&quot;).ToArray();
    object.ReferenceEquals(items1.First(), items3.First()).WriteLine(); // False
    items1.SequenceEqual(items3).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, LINQ to XML is just a specialized LINQ to Objects. For example, the implementation of XNode.Ancestors is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Xml.Linq
{
    public abstract class XNode : XObject
    {
        public IEnumerable&amp;lt;XElement&amp;gt; Ancestors()
        {
            for (XElement parent = this.Parent; parent != null; parent = parent.Parent)
            {
                yield return parent;
            }
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the implementation of the Extensions.Ancestors extension method is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Xml.Linq
{
    public static partial class Extensions
    {
        public static IEnumerable&amp;lt;XElement&amp;gt; Ancestors&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source) where T : XNode =&amp;gt;
            source
                .Where(node =&amp;gt; node != null)
                .SelectMany(node =&amp;gt; node.Ancestors())
                .Where(ancestor =&amp;gt; ancestor != null);
            // Equivalent to:
            // from node in source
            // where node != null
            // from ancestor in node.Ancestors()
            // where ancestor != null
            // select ancestor;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Ordering&lt;/h2&gt;
&lt;p&gt;Besides the LINQ to Objects ordering query methods, additional ordering methods are provided by LINQ to XML. The InDocumentOrder query method orders nodes by their positions in the XML tree, from top node down. For example, above Ancestors yields parent, parent’s parent, …, recursively. InDocumentOrder can reorder them from top down. As a result, the query result is reversed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DocumentOrder()
{
    XElement element1 = new XElement(&quot;element&quot;);
    XElement element2 = new XElement(&quot;element&quot;);
    new XDocument(new XElement(&quot;grandparent&quot;, new XElement(&quot;parent&quot;, element1, element2)));

    element1.IsBefore(element2).WriteLine(); // True
    XNode.DocumentOrderComparer.Compare(element1, element2).WriteLine(); // -1

    XElement[] ancestors = element1.Ancestors().ToArray();
    XNode.CompareDocumentOrder(ancestors.First(), ancestors.Last()).WriteLine(); // 1
    ancestors
        .InDocumentOrder()
        .Select(ancestor =&amp;gt; ancestor.Name)
        .WriteLines(); // grandparent parent

    element1
        .AncestorsAndSelf()
        .Reverse()
        .SequenceEqual(element1.AncestorsAndSelf().InDocumentOrder())
        .WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, InDocumentOrder requires the source nodes sequence to be in the same XML tree. This is determined by looking up a common ancestor of the source nodes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CommonAncestor()
{
    XElement root = XElement.Parse(@&quot;
        &amp;lt;root&amp;gt;
            &amp;lt;element value=&apos;4&apos; /&amp;gt;
            &amp;lt;element value=&apos;2&apos; /&amp;gt;
            &amp;lt;element value=&apos;3&apos;&amp;gt;&amp;lt;element value=&apos;1&apos; /&amp;gt;&amp;lt;/element&amp;gt;
        &amp;lt;/root&amp;gt;&quot;);
    XElement[] elements = root
        .Descendants(&quot;element&quot;)
        .OrderBy(element =&amp;gt; (int)element.Attribute(&quot;value&quot;)).ToArray();
    elements.WriteLines(ancestorOrSelf =&amp;gt; ancestorOrSelf.ToString(SaveOptions.DisableFormatting));
    // &amp;lt;element value=&quot;1&quot; /&amp;gt;
    // &amp;lt;element value=&quot;2&quot; /&amp;gt;
    // &amp;lt;element value=&quot;3&quot;&amp;gt;&amp;lt;element value=&quot;1&quot; /&amp;gt;&amp;lt;/element&amp;gt;
    // &amp;lt;element value=&quot;4&quot; /&amp;gt;

    new XElement[] { elements.First(), elements.Last() }
        .InDocumentOrder()
        .WriteLines(ancestorOrSelf =&amp;gt; ancestorOrSelf.ToString(SaveOptions.DisableFormatting));
    // &amp;lt;element value=&quot;4&quot; /&amp;gt;
    // &amp;lt;element value=&quot;1&quot; /&amp;gt;

    new XElement[] { elements.First(), elements.Last(), new XElement(&quot;element&quot;) }
        .InDocumentOrder()
        .ForEach();
    // InvalidOperationException: A common ancestor is missing.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice in the inline XML string, single quotes are used for attribute values, instead of double quotes. This is for readability of C# code, otherwise &quot;&quot; or \&quot; has to be used. According to the &lt;a href=&quot;https://www.w3.org/TR/xml/#NT-AttValue&quot;&gt;W3C XML spec&lt;/a&gt;, single quote is legal.&lt;/p&gt;
&lt;h2&gt;Comparison&lt;/h2&gt;
&lt;p&gt;LINQ to Objects provides many query methods accepting IComparer&amp;lt;T&amp;gt; or IEqualityComparer&amp;lt;T&amp;gt;. For these scenarios, LINQ to XML provides 2 built-in comparers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XNodeDocumentOrderComparer, which implements IComparer&amp;lt;XNode&amp;gt;. Its Compare method simply calls XNode.CompareDocumentOrder. Its instance is provided by XNode.DocumentOrderComparer property.&lt;/li&gt;
&lt;li&gt;XNodeEqualityComparer, which implements IEqualityComparer&amp;lt;XNode&amp;gt;. Its Equals method simply calls XNode.DeepEquals. Its instance is provided by XNode.EqualityComparer property.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, above InDocumentOrder query method simply calls OrderBy with XNodeDocumentOrderComparer. Its implementation is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Extensions
{
    public static IEnumerable&amp;lt;T&amp;gt; InDocumentOrder&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source) where T : XNode =&amp;gt;
        source.OrderBy(node =&amp;gt; node, XNode.DocumentOrderComparer);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More useful queries&lt;/h2&gt;
&lt;p&gt;With the knowledge of LINQ to Objects and LINQ to XML APIs, more useful query methods can be implemented. For example, the following DescendantObjects method queries an XObject source’s all descendant XObject instances:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class XExtensions
{
    public static IEnumerable&amp;lt;XObject&amp;gt; DescendantObjects(this XObject source) =&amp;gt;
        Enumerable
            .Empty&amp;lt;XObject&amp;gt;()
            .Concat(
                source is XElement element
                    ? element.Attributes() // T is covariant in IEnumerable&amp;lt;T&amp;gt;.
                    : Enumerable.Empty&amp;lt;XObject&amp;gt;())
            .Concat(
                source is XContainer container
                    ? container
                        .DescendantNodes()
                        .SelectMany(descendant =&amp;gt; EnumerableEx
                            .Return(descendant)
                            .Concat(
                                descendant is XElement descendantElement
                                    ? descendantElement.Attributes() // T is covariant in IEnumerable&amp;lt;T&amp;gt;.
                                    : Enumerable.Empty&amp;lt;XObject&amp;gt;()))
                    : Enumerable.Empty&amp;lt;XObject&amp;gt;());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, XObject can be either node or attribute. So in the query, If the source is element, it yields the element’s attributes; if the source is XContainer, it yields each descendant node; If a descendant node is element, it yields the attributes.&lt;/p&gt;
&lt;p&gt;The following SelfAndDescendantObjects method is straightforward to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;XObject&amp;gt; SelfAndDescendantObjects(this XObject source) =&amp;gt; 
    EnumerableEx
        .Return(source)
        .Concat(source.DescendantObjects());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Names method queries a XContainer source for all elements’ and attributes’ names:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;XName&amp;gt; Names(this XContainer source) =&amp;gt;
    (source is XElement element
        ? element.DescendantsAndSelf()
        : source.Descendants())
            .SelectMany(descendantElement =&amp;gt; EnumerableEx
                .Return(descendantElement.Name)
                .Concat(descendantElement
                    .Attributes()
                    .Select(attribute =&amp;gt; attribute.Name)))
        .Distinct();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, XName instances are cached, so Distinct is called to remove the duplicated references.&lt;/p&gt;
&lt;p&gt;Above built-in Attributes method is for querying an element’s attributes. The following AllAttributes queries an XContainer source’s attributes (if it is an element) and all its descendant elements’ attributes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;XAttribute&amp;gt; AllAttributes(this XContainer source) =&amp;gt;
    (source is XElement element 
        ? element.DescendantsAndSelf() 
        : source.Descendants())
        .SelectMany(elementOrDescendant =&amp;gt; elementOrDescendant.Attributes());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following Namespaces methods queries all namespaces defined in a XContainer source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;(string, XNamespace)&amp;gt; Namespaces(this XContainer source) =&amp;gt;
    source // Namespaces are defined as xmlns:prefix=&quot;namespace&quot; attributes.
        .AllAttributes()
        .Where(attribute =&amp;gt; attribute.IsNamespaceDeclaration)
        .Select(attribute =&amp;gt; (attribute.Name.LocalName, (XNamespace)attribute.Value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It returns a sequence of (prefix, namespace) tuples. This method can be very useful, regarding .NET does not provide such API. With its help, the following XmlNamespaceManager can be defined for any XContainer source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static XmlNamespaceManager CreateNamespaceManager(this XContainer source)
{
    XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
    source
        .Namespaces()
        .ForEach(@namespace =&amp;gt; namespaceManager.AddNamespace(@namespace.Item1, @namespace.Item2.ToString()));
    return namespaceManager;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method is used later when working with XPath.&lt;/p&gt;
&lt;h2&gt;XPath&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/XPath&quot;&gt;XPath&lt;/a&gt; is a simple query language to select or evaluate objects from an XML tree. It consists of 3 parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;axis, e.g.:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/ is to select root node (either a document node, or an element node on the fly)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/rss/channel/item is to select root node, then select root node’s all &amp;lt;rss&amp;gt; direct child elements, then select each &amp;lt;rss&amp;gt; element’s all &amp;lt;channel&amp;gt; child elements, then select each &amp;lt;channel&amp;gt; element’s all &amp;lt;item&amp;gt; child elements&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/rss/@version is to select root node, then select root node’s all &amp;lt;rss&amp;gt; direct child elements, then select each &amp;lt;rss&amp;gt; element’s version attribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;node test&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;text() is to select all text nodes, comment() is to select all comment nodes, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/element/text() is to select root node, then select all &amp;lt;element&amp;gt; child elements, then select each &amp;lt;element&amp;gt; element’s all child text nodes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;predicate:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[1] means select the first node, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/rss[1]/text()[2] means to select root node, then select the first &amp;lt;rss&amp;gt; child element, then select that &amp;lt;rss&amp;gt; element’s second child text node.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;LINQ to XML also provides a few extension methods to work with XPath. The latest XPath version is 3.0, .NET and LINQ to XML implements XPath 1.0.&lt;/p&gt;
&lt;p&gt;The CreateNavigator methods creates a XmlXPathNavigator, which can be used for navigation and querying:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathNavigator()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XPathNavigator rssNavigator = rss.CreateNavigator();
    rssNavigator.NodeType.WriteLine(); // Root
    rssNavigator.MoveToFirstChild().WriteLine(); // True
    rssNavigator.Name.WriteLine(); // rss

    ((XPathNodeIterator)rssNavigator
        .Evaluate(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category&quot;))
        .Cast&amp;lt;XPathNavigator&amp;gt;()
        .Select(categoryNavigator =&amp;gt; categoryNavigator.UnderlyingObject)
        .Cast&amp;lt;XElement&amp;gt;()
        .GroupBy(
            category =&amp;gt; category.Value, // Current text node&apos;s value.
            category =&amp;gt; category,
            (key, group) =&amp;gt; new { Name = key, Count = group.Count() },
            StringComparer.OrdinalIgnoreCase)
        .OrderByDescending(category =&amp;gt; category.Count)
        .Take(5)
        .Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
        .WriteLines();
        // [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It implements the same query as previous RSS tags example.&lt;/p&gt;
&lt;p&gt;The XPathSelectElements method is a shortcut of calling CreateNavigator to get an XPathNavigator and then call Evaluate. The above query can be shorten as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathQuery()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    rss
        .XPathSelectElements(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category&quot;)
        .GroupBy(
            category =&amp;gt; category.Value, // Current text node&apos;s value.
            category =&amp;gt; category,
            (key, group) =&amp;gt; new { Name = key, Count = group.Count() },
            StringComparer.OrdinalIgnoreCase)
        .OrderByDescending(category =&amp;gt; category.Count)
        .Take(5)
        .Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
        .WriteLines();
        // [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And XPathSelectElement is simply a shortcut of calling XPathSelectElements to get a sequence, then call FirstOrDefault.&lt;/p&gt;
&lt;p&gt;XPathEvaluate also calls CreateNavigator and then Evaluate, but it is more flexible. When the XPath is evaluated to a single value, it just returns that value. The following example queries the RSS feed for the average tags count of each &amp;lt;item&amp;gt; element, and also the equivalent LINQ query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathEvaluateValue()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    double average1 = (double)rss.XPathEvaluate(&quot;count(/rss/channel/item/category) div count(/rss/channel/item)&quot;);
    average1.WriteLine(); // 4.65

    double average2 = rss
        .Element(&quot;rss&quot;)
        .Element(&quot;channel&quot;)
        .Elements(&quot;item&quot;)
        .Average(item =&amp;gt; item.Elements(&quot;category&quot;).Count());
    average2.WriteLine(); // 4.65
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the XPath is evaluated to a sequence of values, XPathEvaluate returns IEnumerable&amp;lt;object&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathEvaluateSequence()
{
    XDocument rss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    ((IEnumerable&amp;lt;object&amp;gt;)rss
        .XPathEvaluate(&quot;/rss/channel/item[guid/@isPermaLink=&apos;true&apos;]/category/text()&quot;))
        .Cast&amp;lt;XText&amp;gt;()
        .GroupBy(
            categoryTextNode =&amp;gt; categoryTextNode.Value, // Current text node&apos;s value.
            categoryTextNode =&amp;gt; categoryTextNode,
            (key, group) =&amp;gt; new { Name = key, Count = group.Count() },
            StringComparer.OrdinalIgnoreCase)
        .OrderByDescending(category =&amp;gt; category.Count)
        .Take(5)
        .Select(category =&amp;gt; $&quot;[{category.Name}]:{category.Count}&quot;)
        .WriteLines();
        // [C#]:9 [LINQ]:6 [.NET]:5 [Functional Programming]:4 [LINQ via C#]:4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LINQ to XML also provides overloads for these XPath methods to accept an IXmlNamespaceResolver parameter. When the XPath expression involves namespace, an IXmlNamespaceResolver instance must be provided. Taking another RSS feed from Flickr as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;rss version=&quot;2.0&quot; xmlns:media=&quot;http://search.yahoo.com/mrss/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:flickr=&quot;urn:flickr:user&quot;&amp;gt;
  &amp;lt;channel&amp;gt;
    &amp;lt;item&amp;gt;
      &amp;lt;title&amp;gt;Microsoft Way, Microsoft Campus&amp;lt;/title&amp;gt;
      &amp;lt;dc:date.Taken&amp;gt;2011-11-02T16:45:54-08:00&amp;lt;/dc:date.Taken&amp;gt;
      &amp;lt;author flickr:profile=&quot;https://www.flickr.com/people/dixin/&quot;&amp;gt;nobody@flickr.com (Dixin Yan)&amp;lt;/author&amp;gt;
      &amp;lt;media:content url=&quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_b.jpg&quot; type=&quot;image/jpeg&quot; height=&quot;681&quot; width=&quot;1024&quot;/&amp;gt;
      &amp;lt;media:title&amp;gt;Microsoft Way, Microsoft Campus&amp;lt;/media:title&amp;gt;
      &amp;lt;media:description type=&quot;html&quot;&amp;gt;
        &amp;lt;p&amp;gt;Microsoft Campus is the informal name of Microsoft&apos;s corporate headquarters, located at One Microsoft Way in Redmond, Washington. Microsoft initially moved onto the grounds of the campus on February 26, 1986. &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Redmond_Campus&quot; rel=&quot;nofollow&quot;&amp;gt;en.wikipedia.org/wiki/Microsoft_Redmond_Campus&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
      &amp;lt;/media:description&amp;gt;
      &amp;lt;media:thumbnail url=&quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_s.jpg&quot; height=&quot;75&quot; width=&quot;75&quot;/&amp;gt;
      &amp;lt;media:credit role=&quot;photographer&quot;&amp;gt;Dixin Yan&amp;lt;/media:credit&amp;gt;
      &amp;lt;media:category scheme=&quot;urn:flickr:tags&quot;&amp;gt;microsoft&amp;lt;/media:category&amp;gt;
      &amp;lt;!-- Other elements. --&amp;gt;
    &amp;lt;/item&amp;gt;
    &amp;lt;!-- Other items. --&amp;gt;
  &amp;lt;/channel&amp;gt;
&amp;lt;/rss&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It contains additional information than the standard RSS format, and these additional elements/attributes are managed by namespaces. The following example calls the overload of XPathSelectElements to query the &lt;a&gt;media:category&lt;/a&gt; elements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathQueryWithNamespace()
{
    XDocument rss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    XmlNamespaceManager namespaceManager = rss.CreateNamespaceManager();
    IEnumerable&amp;lt;XElement&amp;gt; query1 = rss.XPathSelectElements(&quot;/rss/channel/item/media:category&quot;, namespaceManager);
    query1.Count().WriteLine(); // 20

    IEnumerable&amp;lt;XElement&amp;gt; query2 = rss.XPathSelectElements(&quot;/rss/channel/item/media:category&quot;);
    // XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since prefix “media” is in XPath expression, An IXmlNamespaceResolver instance is required. XmlNamespaceManager implements IXmlNamespaceResolver, so simply call the the previously defined CreateNamespaceManager method to create it. In contrast, querying the same XPath expression without IXmlNamespaceResolver instance throws XPathException.&lt;/p&gt;
&lt;p&gt;The last example calls the overload of XPathEvaluate to query the items’ titles, which has the tag “microsoft” in the &lt;a&gt;media:category&lt;/a&gt; element:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XPathEvaluateSequenceWithNamespace()
{
    XDocument rss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    ((IEnumerable&amp;lt;object&amp;gt;)rss
        .XPathEvaluate(
            &quot;/rss/channel/item[contains(media:category/text(), &apos;microsoft&apos;)]/media:title/text()&quot;,
            rss.CreateNamespaceManager()))
        .Cast&amp;lt;XText&amp;gt;()
        .WriteLines(mediaTitle =&amp;gt; mediaTitle.Value);
        // Chinese President visits Microsoft
        // Satya Nadella, CEO of Microsoft
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Generate XPath expression&lt;/h2&gt;
&lt;p&gt;To leverage LINQ to XML, one example is to generate XPath expression for a specified XObject instance, which can be either XAttribute or XNode. The XPath expression can be calculated with the following 3 segments are needed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the XPath of current object’s parent Element, which can be either calculated recursively, or be provided by caller.&lt;/li&gt;
&lt;li&gt;the XPath of current object, which can be&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;@attributeName if it is an attribute&lt;/li&gt;
&lt;li&gt;elementName if it is an element&lt;/li&gt;
&lt;li&gt;node test like text(), comment(), etc., if it is any other type of node.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;a predicate for current object, which can simply be the position:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;For example, [2] can be used to identify a comment node, if there is another sibling comment node before itself&lt;/li&gt;
&lt;li&gt;also, the position predicate can be omitted if current object has no ambiguous sibling objects, so that XPath of parent object combining XPath of current object selects one single object. For example, if current node is a comment node with no sibling comment node, then parentElement/comment() without position predicate is good enough&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First of all, a helper method is needed to calculate the current element or attribute’s name, which should be in simple localName format if the XName instance is not under any namespace, and should be in prefix:localName format if the XName instance is under a namespace. XName.ToString does not work for this requirement, because it returns the {namespaceUri}localName format, as already demonstrated. So the following XPath method can be defined for name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XName source, XElement container)
{
    string prefix = source.Namespace == XNamespace.None
        ? null
        : container.GetPrefixOfNamespace(source.Namespace); // GetPrefixOfNamespace returns null if not found.
    return string.IsNullOrEmpty(prefix) ? source.ToString() : $&quot;{prefix}:{source.LocalName}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regarding the above segment 1 and segment 2 has to be combined, another helper method is needed to combine 2 XPath expressions, which is similar to .NET built-in Combine method provided by System.IO.Path:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static string CombineXPath(string xPath1, string xPath2, string predicate = null) =&amp;gt;
    string.Equals(xPath1, &quot;/&quot;, StringComparison.Ordinal) || string.IsNullOrEmpty(xPath2)
    ? $&quot;{xPath1}{xPath2}{predicate}&quot;
    : $&quot;{xPath1}/{xPath2}{predicate}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regarding XObject can be either one type of attribute, or several types of nodes, apparently attribute does not need the position predicate, while the different types of nodes all share similar logic to identify the position and the ambiguous siblings. So the following helper method can be defined for XNode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static string XPath&amp;lt;TSource&amp;gt;(
    this TSource source,
    string parentXPath,
    string selfXPath = null,
    Func&amp;lt;TSource, bool&amp;gt; siblingPredicate = null) where TSource : XNode
{
    int index = source
        .NodesBeforeSelf()
        .Cast&amp;lt;TSource&amp;gt;()
        .Where(siblingPredicate ?? (_ =&amp;gt; true))
        .Count();
    string predicate = index == 0
        &amp;amp;&amp;amp; !source
            .NodesAfterSelf()
            .Cast&amp;lt;TSource&amp;gt;()
            .Where(siblingPredicate ?? (_ =&amp;gt; true))
            .Any()
        ? null
        : $&quot;[{index + 1}]&quot;;
    return CombineXPath(parentXPath, selfXPath, predicate);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the following XPath method can be defined to generate XPath expression for an element:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XElement source, string parentXPath = null) =&amp;gt; 
    string.IsNullOrEmpty(parentXPath) &amp;amp;&amp;amp; source.Parent == null &amp;amp;&amp;amp; source.Document == null
        ? &quot;/&quot; // source is an element on the fly, not attached to any parent node.
        : source.XPath(
            parentXPath ?? source.Parent?.XPath(),
            source.Name.XPath(source),
            sibling =&amp;gt; sibling.Name == source.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this method, there is a special case for element. As fore mentioned, an element can be constructed on the fly, and it is the root node of its XML tree. In this case, just returns XPath root expression /. For other cases, just call above XPath helper method for XNode, with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XPath of parent element, if not provided then calculate recursively&lt;/li&gt;
&lt;li&gt;XPath of element name, which can be generated by calling above XPath helper method for XName&lt;/li&gt;
&lt;li&gt;A lambda expression to identify ambiguous sibling elements with the same element name, so that the proper XPath predicate can be generated&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The XPath overloads for comment/text/processing instruction nodes are straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XComment source, string parentXPath = null) =&amp;gt; 
    source.XPath(parentXPath ?? source.Parent?.XPath(), &quot;comment()&quot;);

public static string XPath(this XText source, string parentXPath = null) =&amp;gt; 
    source.XPath(parentXPath ?? source.Parent?.XPath(), &quot;text()&quot;);

public static string XPath(this XProcessingInstruction source, string parentXPath = null) =&amp;gt; 
    source.XPath(
        parentXPath ?? source.Parent?.XPath(),
        $&quot;processing-instruction(&apos;{source.Target}&apos;)&quot;,
        sibling =&amp;gt; string.Equals(sibling.Target, source.Target, StringComparison.Ordinal));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the XPath overload for attribute just combine parent element’s XPath with the format of @attributeName:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string XPath(this XAttribute source, string parentXPath = null) =&amp;gt; 
    CombineXPath(parentXPath ?? source.Parent?.XPath(), $&quot;@{source.Name.XPath(source.Parent)}&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are some examples of using these methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GenerateXPath()
{
    XDocument aspNetRss = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    XElement element1 = aspNetRss
        .Root
        .Element(&quot;channel&quot;)
        .Elements(&quot;item&quot;)
        .Last();
    element1.XPath().WriteLine(); // /rss/channel/item[20]
    XElement element2 = aspNetRss.XPathSelectElement(element1.XPath());
    object.ReferenceEquals(element1, element2).WriteLine(); // True

    XDocument flickrRss = XDocument.Load(&quot;https://www.flickr.com/services/feeds/photos_public.gne?id=64715861@N07&amp;amp;format=rss2&quot;);
    XAttribute attribute1 = flickrRss
        .Root
        .Descendants(&quot;author&quot;) // &amp;lt;author flickr:profile=&quot;https://www.flickr.com/people/dixin/&quot;&amp;gt;...&amp;lt;/author&amp;gt;.
        .First()
        .Attribute(XName.Get(&quot;profile&quot;, &quot;urn:flickr:user&quot;)); // &amp;lt;rss xmlns:flickr=&quot;urn:flickr:user&quot;&amp;gt;...&amp;lt;/rss&amp;gt;.
    attribute1.XPath().WriteLine(); // /rss/channel/item[1]/author/@flickr:profile
    XAttribute attribute2 = ((IEnumerable&amp;lt;object&amp;gt;)flickrRss
        .XPathEvaluate(attribute1.XPath(), flickrRss.CreateNamespaceManager()))
        .Cast&amp;lt;XAttribute&amp;gt;()
        .Single();
    object.ReferenceEquals(attribute1, attribute2).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>LINQ to XML in Depth (1) Modeling XML</title><link>https://dixin.github.io/posts/linq-to-xml-1-modeling-xml-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-xml-1-modeling-xml-7/</guid><description>(eXtensible Markup Language) is widely used to represent, store, and transfer data. Since .NET 3.5, the built in LINQ to XML APIs are provided to enable LINQ q</description><pubDate>Wed, 15 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20XML&quot;&gt;LINQ to XML in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-xml-1-modeling-xml&quot;&gt;https://weblogs.asp.net/dixin/linq-to-xml-1-modeling-xml&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/XML&quot;&gt;XML&lt;/a&gt; (eXtensible Markup Language) is widely used to represent, store, and transfer data. Since .NET 3.5, the built in LINQ to XML APIs are provided to enable LINQ queries for XML data source. These APIs are located in System.Xml.XDocument NuGet package for .NET Core, and System.Xml.Linq.dll for .NET Framework. LINQ to XML can be viewed as specialized LINQ to Objects, where the objects in memory represents XML structures.&lt;/p&gt;
&lt;h2&gt;Imperative vs. declarative paradigm&lt;/h2&gt;
&lt;p&gt;The XML DOM APIs are provided since .NET Framework 1.0. There a set of Xml* types in System.Xml namespace representing XML structures. The following list shows their inheritance hierarchy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;XmlNamedNodeMap&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlAttributeCollection&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlAttribute&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlDocument&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlDocumentFragment&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlEntity&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlLinkedNode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlCharacterData&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlCDataSection&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlComment&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlSignificantWhitespace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlText&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlWhitespace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlDeclaration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlDocumentType&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlElement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlEntityReference&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlProcessingInstruction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlNotation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlNodeList&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XmlQualifiedName&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These DOM APIs for XML can be used to model and manipulate XML structures in imperative paradigm. Take the following XML fragment as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;rss version=&quot;2.0&quot; xmlns:dixin=&quot;https://weblogs.asp.net/dixin&quot;&amp;gt;
  &amp;lt;channel&amp;gt;
    &amp;lt;item&amp;gt;
      &amp;lt;title&amp;gt;LINQ via C#&amp;lt;/title&amp;gt;
      &amp;lt;link&amp;gt;https://weblogs.asp.net/dixin/linq-via-csharp&amp;lt;/link&amp;gt;
      &amp;lt;description&amp;gt;
        &amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;
      &amp;lt;/description&amp;gt;
      &amp;lt;pubDate&amp;gt;Mon, 07 Sep 2009 00:00:00 GMT&amp;lt;/pubDate&amp;gt;
      &amp;lt;guid isPermaLink=&quot;true&quot;&amp;gt;https://weblogs.asp.net/dixin/linq-via-csharp&amp;lt;/guid&amp;gt;
      &amp;lt;category&amp;gt;C#&amp;lt;/category&amp;gt;
      &amp;lt;category&amp;gt;LINQ&amp;lt;/category&amp;gt;
      &amp;lt;!--Comment.--&amp;gt;
      &amp;lt;dixin:source&amp;gt;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq&amp;lt;/dixin:source&amp;gt;
    &amp;lt;/item&amp;gt;
  &amp;lt;/channel&amp;gt;
&amp;lt;/rss&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a simple RSS feed with one single &amp;lt;item&amp;gt; element. The following example calls XML DOM APIs to build such a XML tree, and serialize the XML tree to string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class Dom
{
    internal static void CreateAndSerialize()
    {
        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
        const string NamespacePrefix = &quot;dixin&quot;;
        namespaceManager.AddNamespace(NamespacePrefix, &quot;https://weblogs.asp.net/dixin&quot;);

        XmlDocument document = new XmlDocument(namespaceManager.NameTable);

        XmlElement rss = document.CreateElement(&quot;rss&quot;);
        rss.SetAttribute(&quot;version&quot;, &quot;2.0&quot;);
        XmlAttribute attribute = document.CreateAttribute(
            &quot;xmlns&quot;, NamespacePrefix, namespaceManager.LookupNamespace(&quot;xmlns&quot;));
        attribute.Value = namespaceManager.LookupNamespace(NamespacePrefix);
        rss.SetAttributeNode(attribute);
        document.AppendChild(rss);

        XmlElement channel = document.CreateElement(&quot;channel&quot;);
        rss.AppendChild(channel);

        XmlElement item = document.CreateElement(&quot;item&quot;);
        channel.AppendChild(item);

        XmlElement title = document.CreateElement(&quot;title&quot;);
        title.InnerText = &quot;LINQ via C#&quot;;
        item.AppendChild(title);

        XmlElement link = document.CreateElement(&quot;link&quot;);
        link.InnerText = &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;;
        item.AppendChild(link);

        XmlElement description = document.CreateElement(&quot;description&quot;);
        description.InnerXml = &quot;&amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;&quot;;
        item.AppendChild(description);

        XmlElement pubDate = document.CreateElement(&quot;pubDate&quot;);
        pubDate.InnerText = new DateTime(2009, 9, 7).ToString(&quot;r&quot;);
        item.AppendChild(pubDate);

        XmlElement guid = document.CreateElement(&quot;guid&quot;);
        guid.InnerText = &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;;
        guid.SetAttribute(&quot;isPermaLink&quot;, &quot;true&quot;);
        item.AppendChild(guid);

        XmlElement category1 = document.CreateElement(&quot;category&quot;);
        category1.InnerText = &quot;C#&quot;;
        item.AppendChild(category1);

        XmlNode category2 = category1.CloneNode(false);
        category2.InnerText = &quot;LINQ&quot;;
        item.AppendChild(category2);

        XmlComment comment = document.CreateComment(&quot;Comment.&quot;);
        item.AppendChild(comment);

        XmlElement source = document.CreateElement(NamespacePrefix, &quot;source&quot;, namespaceManager.LookupNamespace(NamespacePrefix));
        source.InnerText = &quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq&quot;;
        item.AppendChild(source);

        // Serialize XmlDocument to string.
        StringBuilder xmlString = new StringBuilder();
        XmlWriterSettings settings = new XmlWriterSettings
        {
            Indent = true,
            IndentChars = &quot;  &quot;,
            OmitXmlDeclaration = true
        };
        using (XmlWriter writer = XmlWriter.Create(xmlString, settings))
        {
            document.Save(writer);
        }

        // rssItem.ToString() returns &quot;System.Xml.XmlElement&quot;.
        // rssItem.OuterXml returns a single line of XML text.
        xmlString.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These APIs have a few disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any XML structure has to be created with a XmlDocument instance.&lt;/li&gt;
&lt;li&gt;XML tree has to be built imperatively, node by node.&lt;/li&gt;
&lt;li&gt;Additional work is needed to manage namespaces and prefixes.&lt;/li&gt;
&lt;li&gt;Some operations, like serialization, is not straightforward.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fortunately, LINQ to XML does not work with these Xml* types. It redesigns a bunch of X* types under System.Xml.Linq namespace, and enables LINQ queries for these objects. The following list shows the inheritance hierarchy of all the X* types, as well as each type’s conversion from/to other types, and their overloaded operators:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;XDeclaration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XName: implicit convertible from string, ==, !=&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNamespace: implicit convertible from string, + string, ==, !=&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XObject&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XAttribute: explicit convertible to string/bool/bool?/int/int?/uint/uint?/long/long?/ulong/ulong?/float/float?/double/double?/decimal/decimal?/DateTime/DateTime?/TimeSpan/TimeSpan?/Guid/Guid?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XNode: DeepEquals&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XComment&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XContainer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XDocument&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XElement: explicit convertible to string/bool/bool?/int/int?/uint/uint?/long/long?/ulong/ulong?/float/float?/double/double?/decimal/decimal?/DateTime/DateTime?/TimeSpan/TimeSpan?/Guid/Guid?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XDocumentType&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XProcessingInstruction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XText&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XCData&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XStreamingElement&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the names suggest, e.g., XNode represents a XML node, XDocument represents a XML document, XName represents XML element name or XML attribute name, etc. And apparently, An XML element/attribute name is essentially a string, so XName implements implicit conversion from string, which provides great convenience. The following example builds the same XML tree with the new LINQ to XML types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Modeling
{
    internal static void CreateAndSerialize()
    {
        XNamespace @namespace = &quot;https://weblogs.asp.net/dixin&quot;;
        XElement rss = new XElement(
            &quot;rss&quot;,
            new XAttribute(&quot;version&quot;, &quot;2.0&quot;),
            new XAttribute(XNamespace.Xmlns + &quot;dixin&quot;, @namespace),
            new XElement(
                &quot;channel&quot;,
                new XElement(
                    &quot;item&quot;, // Implicitly converted to XName.
                    new XElement(&quot;title&quot;, &quot;LINQ via C#&quot;),
                    new XElement(&quot;link&quot;, &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;),
                    new XElement(
                        &quot;description&quot;,
                        XElement.Parse(&quot;&amp;lt;p&amp;gt;This is a tutorial of LINQ and functional programming. Hope it helps.&amp;lt;/p&amp;gt;&quot;)),
                    new XElement(&quot;pubDate&quot;, new DateTime(2009, 9, 7).ToString(&quot;r&quot;)),
                    new XElement(
                        &quot;guid&quot;,
                        new XAttribute(&quot;isPermaLink&quot;, &quot;true&quot;), // &quot;isPermaLink&quot; is implicitly converted to XName.
                        &quot;https://weblogs.asp.net/dixin/linq-via-csharp&quot;),
                    new XElement(&quot;category&quot;, &quot;C#&quot;),
                    new XElement(&quot;category&quot;, &quot;LINQ&quot;),
                    new XComment(&quot;Comment.&quot;),
                    new XElement(
                        @namespace + &quot;source&quot;,
                        https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Linq))));
        rss.ToString().WriteLine(); // Serialize XDocument to string.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The new code is shorter and more intuitive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XML structure can be create on the fly, XDocument is not involved in the entire example.&lt;/li&gt;
&lt;li&gt;XML tree can be built declaratively.&lt;/li&gt;
&lt;li&gt;Easier namespace management, with prefix automatically taken care of.&lt;/li&gt;
&lt;li&gt;To serialize an XML tree, simply call ToString.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Types, conversions and operators&lt;/h2&gt;
&lt;p&gt;Besides XDocument, XElement, XAttribute, and XComment in above example, some other XML structures can also can declaratively constructed too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Construction()
{
    XDeclaration declaration = new XDeclaration(&quot;1.0&quot;, null, &quot;no&quot;);
    declaration.WriteLine(); // &amp;lt;?xml version=&quot;1.0&quot; standalone=&quot;no&quot;?&amp;gt;

    XDocumentType documentType = new XDocumentType(&quot;html&quot;, null, null, null);
    documentType.WriteLine(); // &amp;lt;!DOCTYPE html &amp;gt;

    XText text = new XText(&quot;&amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt;&quot;);
    text.WriteLine(); // &amp;amp;lt;p&amp;amp;gt;text&amp;amp;lt;/p&amp;amp;gt;

    XCData cData = new XCData(&quot;cdata&quot;);
    cData.WriteLine(); // &amp;lt;![CDATA[cdata]]&amp;gt;

    XProcessingInstruction processingInstruction = new XProcessingInstruction(
        &quot;xml-stylesheet&quot;, @&quot;type=&quot;&quot;text/xsl&quot;&quot; href=&quot;&quot;Style.xsl&quot;&quot;&quot;);
    processingInstruction.WriteLine(); // &amp;lt;?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;Style.xsl&quot;?&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;XName is different. LINQ to XML provides 2 equivalent ways to instantiate XName:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;calling XName.Get&lt;/li&gt;
&lt;li&gt;implicitly converting from string (which is implemented with XName.Get as well).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The constructor is not exposed, because LINQ to XML caches all the constructed XName instances at runtime, so a XName instance is constructed only once for a specific name. LINQ to XML also implements the == and != operator by checking the reference equality:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Name()
{
    XName attributeName1 = &quot;isPermaLink&quot;; // Implicitly convert string to XName.
    XName attributeName2 = XName.Get(&quot;isPermaLink&quot;);
    XName attributeName3 = &quot;IsPermaLink&quot;;
    object.ReferenceEquals(attributeName1, attributeName2).WriteLine(); // True
    (attributeName1 == attributeName2).WriteLine(); // True
    (attributeName1 != attributeName3).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;XNamespace has the same behavior as XName. additionally, it implements the + operator to combine the namespace and local name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Namespace()
{
    XNamespace namespace1 = &quot;http://www.w3.org/XML/1998/namespace&quot;; // Implicitly convert string to XNamespace.
    XNamespace namespace2 = XNamespace.Xml;
    XNamespace namespace3 = XNamespace.Get(&quot;http://www.w3.org/2000/xmlns/&quot;);
    (namespace1 == namespace2).WriteLine(); // True
    (namespace1 != namespace3).WriteLine(); // True

    XNamespace @namespace = &quot;https://weblogs.asp.net/dixin&quot;;
    XName name = @namespace + &quot;localName&quot;; // + operator.
    name.WriteLine(); // {https://weblogs.asp.net/dixin}localName
    XElement element = new XElement(name, new XAttribute(XNamespace.Xmlns + &quot;dixin&quot;, @namespace)); // + operator.
    element.WriteLine(); // &amp;lt;dixin:localName xmlns:dixin=&quot;https://weblogs.asp.net/dixin&quot; /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;XElement can be explicitly converted to .NET primitive types, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Element()
{
    XElement pubDateElement = XElement.Parse(&quot;&amp;lt;pubDate&amp;gt;Mon, 07 Sep 2009 00:00:00 GMT&amp;lt;/pubDate&amp;gt;&quot;);
    DateTime pubDate = (DateTime)pubDateElement;
    pubDate.WriteLine(); // 9/7/2009 12:00:00 AM
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above conversion is implemented by calling DateTime.Parse with the string value returned by XElement.Value.&lt;/p&gt;
&lt;p&gt;XAttribute can be converted to primitive types too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Attribute()
{
    XName name = &quot;isPermaLink&quot;;
    XAttribute isPermaLinkAttribute = new XAttribute(name, &quot;true&quot;);
    bool isPermaLink = (bool)isPermaLinkAttribute;
    isPermaLink.WriteLine() // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the conversion is implemented by calling System.Xml.XmlConvert’s ToBoolean method with the string value returned by XElement.Value.&lt;/p&gt;
&lt;p&gt;XComment, XDocument, XElement, XDocumentType, XProcessingInstruction, XText, and XCData types inherit XNode. XNode provides a DeepEquals method to compare any 2 nodes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeepEquals()
{
    XElement element1 = XElement.Parse(&quot;&amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;&quot;);
    XElement element2 = new XElement(&quot;parent&quot;, new XElement(&quot;child&quot;)); // &amp;lt;parent&amp;gt;&amp;lt;child /&amp;gt;&amp;lt;/parent&amp;gt;
    object.ReferenceEquals(element1, element2).WriteLine(); // False
    XNode.DeepEquals(element1, element2).WriteLine(); // True

    XElement element3 = new XElement(&quot;parent&quot;, new XElement(&quot;child&quot;, string.Empty)); // &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    object.ReferenceEquals(element1, element2).WriteLine(); // False
    XNode.DeepEquals(element1, element3).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here element2’s child element is constructed with null content, so it is a empty element node &amp;lt;child /&amp;gt; (where XElement.IsEmpty returns true). element3’s child element is constructed with an empty string as content, so it is a non-empty element &amp;lt;child&amp;gt;&amp;lt;/child&amp;gt; ((where XElement.IsEmpty returns false). As a result, element1 has the same node structures and node values as element2, and they are different from element3.&lt;/p&gt;
&lt;h2&gt;Read and deserialize XML&lt;/h2&gt;
&lt;p&gt;In LINQ to XML, XML can be easily read or deserialized to XNode/XElement/XDocument instances in memory. with the following APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XmlReader (under System.Xml namespace)&lt;/li&gt;
&lt;li&gt;XNode.CreateReader, XNode.ReadFrom&lt;/li&gt;
&lt;li&gt;XDocument.Load, XDocument.Parse&lt;/li&gt;
&lt;li&gt;XElement.Load, XElement.Parse&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The APIs accepting URI, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Read()
{
    using (XmlReader reader = XmlReader.Create(&quot;https://weblogs.asp.net/dixin/rss&quot;))
    {
        reader.MoveToContent();
        XNode node = XNode.ReadFrom(reader);
    }

    XElement element1 = XElement.Parse(&quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&quot;);
    XElement element2 = XElement.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);

    XDocument document1 = XDocument.Parse(&quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&quot;);
    XDocument document2 = XDocument.Load(&quot;https://microsoft.com&quot;); // Succeed.
    XDocument document3 = XDocument.Load(&quot;https://asp.net&quot;); // Fail.
    // System.Xml.XmlException: The &apos;ul&apos; start tag on line 68 position 116 does not match the end tag of &apos;div&apos;. Line 154, position 109.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reading an RSS feed to construct an XML tree usually work smoothly, since RSS is just XML. Reading a web page usually has bigger chance to fail, because in the real world, a HTML document may be not strictly structured.&lt;/p&gt;
&lt;p&gt;The above example reads entire XML document and deserialize the string to XML tree in the memory. Regarding the specified XML can have arbitrary size, XmlReader and XNode.ReadFrom can also read XML fragment by fragment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;XElement&amp;gt; RssItems(string rssUri)
{
    using (XmlReader reader = XmlReader.Create(rssUri))
    {
        reader.MoveToContent();
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element &amp;amp;&amp;amp; reader.Name.Equals(&quot;item&quot;, StringComparison.Ordinal))
            {
                yield return (XElement)XNode.ReadFrom(reader);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the LINQ to Objects chapter, method with yield return statement is compiled to generator creation, and all the API calls in above method body is deferred, so each &amp;lt;item&amp;gt; in the RSS feed is read and deserialized on demand.&lt;/p&gt;
&lt;h2&gt;Serialize and write XML&lt;/h2&gt;
&lt;p&gt;The following APIs are provided to serialize XML to string, or write XML to somewhere (file system, memory, etc.):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XmlWriter&lt;/li&gt;
&lt;li&gt;XObject.ToString&lt;/li&gt;
&lt;li&gt;XNode.ToString, XNode.WriteTo&lt;/li&gt;
&lt;li&gt;XContainer.CreateWriter&lt;/li&gt;
&lt;li&gt;XDocument.Save&lt;/li&gt;
&lt;li&gt;XElement.Save&lt;/li&gt;
&lt;li&gt;XStramingElement.Save, XStramingElement.ToString, XStreamingElement.WriteTo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Write()
{
    XDocument document1 = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    using (FileStream stream = File.OpenWrite(Path.GetTempFileName()))
    {
        document1.Save(stream);
    }

    XElement element1 = new XElement(&quot;element&quot;, string.Empty);
    XDocument document2 = new XDocument();
    using (XmlWriter writer = document2.CreateWriter())
    {
        element1.WriteTo(writer);
    }
    document2.WriteLine(); // &amp;lt;element&amp;gt;&amp;lt;/element&amp;gt;

    XElement element2 = new XElement(&quot;element&quot;, string.Empty);
    using (XmlWriter writer = element2.CreateWriter())
    {
        writer.WriteStartElement(&quot;child&quot;);
        writer.WriteAttributeString(&quot;attribute&quot;, &quot;value&quot;);
        writer.WriteString(&quot;text&quot;);
        writer.WriteEndElement();
    }
    element2.ToString(SaveOptions.DisableFormatting).WriteLine();
    // &amp;lt;element&amp;gt;&amp;lt;child attribute=&quot;value&quot;&amp;gt;text&amp;lt;/child&amp;gt;&amp;lt;/element&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;XNode also provides a ToString overload to accept a SaveOptions flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void XNodeToString()
{
    XDocument document = XDocument.Parse(
        &quot;&amp;lt;root xmlns:prefix=&apos;namespace&apos;&amp;gt;&amp;lt;element xmlns:prefix=&apos;namespace&apos; /&amp;gt;&amp;lt;/root&amp;gt;&quot;);
    document.ToString(SaveOptions.None).WriteLine(); // Equivalent to document.ToString().
    // &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;
    //  &amp;lt;element xmlns:prefix=&quot;namespace&quot; /&amp;gt;
    // &amp;lt;/root&amp;gt;
    document.ToString(SaveOptions.DisableFormatting).WriteLine();
    // &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;&amp;lt;element xmlns:prefix=&quot;namespace&quot; /&amp;gt;&amp;lt;/root&amp;gt;
    document.ToString(SaveOptions.OmitDuplicateNamespaces).WriteLine();
    // &amp;lt;root xmlns:prefix=&quot;namespace&quot;&amp;gt;
    //  &amp;lt;element /&amp;gt;
    // &amp;lt;/root&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To serialize XML with even more custom settings, the XmlWriter with XmlWriterSettings approach in the DOM API example can be used.&lt;/p&gt;
&lt;h2&gt;Deferred construction&lt;/h2&gt;
&lt;p&gt;The XStreamingElement is a special type. It is used to defer the build of element. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StreamingElementWithChildElements()
{
    IEnumerable&amp;lt;XElement&amp;gt; ChildElementsFactory() =&amp;gt;
        Enumerable
            .Range(0, 5).Do(value =&amp;gt; value.WriteLine())
            .Select(value =&amp;gt; new XElement(&quot;child&quot;, value));

    XElement immediateParent = new XElement(&quot;parent&quot;, ChildElementsFactory()); // 0 1 2 3 4.
    immediateParent.ToString(SaveOptions.DisableFormatting).WriteLine();
    // &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;0&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;1&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;2&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;3&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;4&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;

    XStreamingElement deferredParent = new XStreamingElement(&quot;parent&quot;, ChildElementsFactory()); // Deferred.
    deferredParent.ToString(SaveOptions.DisableFormatting).WriteLine();
    // 0 1 2 3 4 
    // &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;0&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;1&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;2&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;3&amp;lt;/child&amp;gt;&amp;lt;child&amp;gt;4&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a factory function is defined to generate a sequence of child elements. It calls the Do query method from Interactive Extension (Ix) to prints each value when that pulled from the sequence. Next, the XElement constructor is called, which immediately pulls all child elements from the sequence returned by the factory function, so that the parent element is immediately built with those child elements. Therefore, the Do query is executed right away, and prints the values of the generated child elements. In contrast, XStreamingElement constructor does not pull the child elements from the sequence, the values are not printed yet by Do. The pulling is deferred until the parent element needs to be built, for example, when XStreamingElement.Save/XStreamingElement.ToString/XStreamingElement.WriteTo is called.&lt;/p&gt;
&lt;p&gt;This feature can also be demonstrated by modifying the child elements. For XElement, once constructed, the element is built immediately, and is not impacted by modifying the original child elements In contrast, .XStreamingElement can be impacted by the modification:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StreamingElementWithChildElementModification()
{
    XElement source = new XElement(&quot;source&quot;, new XElement(&quot;child&quot;, &quot;a&quot;));
    XElement child = source.Elements().Single();

    XElement immediateParent = new XElement(&quot;parent&quot;, child);
    XStreamingElement deferredParent = new XStreamingElement(&quot;parent&quot;, child); // Deferred.

    child.Value = &quot;b&quot;;
    immediateParent.ToString(SaveOptions.DisableFormatting).WriteLine(); // &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;a&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
    deferredParent.ToString(SaveOptions.DisableFormatting).WriteLine(); // &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;b&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (7) Custom Query Methods</title><link>https://dixin.github.io/posts/linq-to-objects-custom-query-methods-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-custom-query-methods-7/</guid><description>After discussing the query methods provided by .NET, this part demonstrates how to define custom query methods:</description><pubDate>Fri, 20 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-custom-query-methods&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-custom-query-methods&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;After discussing the query methods provided by .NET, this part demonstrates how to define custom query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequence queries: return a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution)
&lt;ul&gt;
&lt;li&gt;Generation: Create, Guid, RandomInt32, RandomDouble, FromValue, FromValues, EmptyIfNull&lt;/li&gt;
&lt;li&gt;Concatenation: Join&lt;/li&gt;
&lt;li&gt;Partitioning: Subsequence&lt;/li&gt;
&lt;li&gt;Comparison: OrderBy*, OrderByDescending*, ThenBy*, ThenByDescending*, GroupBy*, Join*, GroupJoin*, Distinct, Union, Intersect*, Except*&lt;/li&gt;
&lt;li&gt;List: Insert, Remove, RemoveAll, RemoveAt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries: return a new collection (immediate execution)
&lt;ul&gt;
&lt;li&gt;Comparison: ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries: return a single value (immediate execution)
&lt;ul&gt;
&lt;li&gt;List: IndexOf, LastIndexOf&lt;/li&gt;
&lt;li&gt;Aggregation: PercentileExclusive, PercentileInclusive, Percentile&lt;/li&gt;
&lt;li&gt;Quantifiers: IsNullOrEmpty, IsNotNullOrEmpty&lt;/li&gt;
&lt;li&gt;Comparison: Contains, SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Void queries: return void (immediate execution)
&lt;ul&gt;
&lt;li&gt;Iteration: ForEach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The sequence queries all implement deferred execution, where the sequence queries marked with * implements eager evaluation, and other unmarked sequence queries implements lazy evaluation. The collection queries, value queries, and void queries all implements immediate execution.&lt;/p&gt;
&lt;p&gt;These query methods can be defined in the following static class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableX { }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Returns a new IEnumerable&amp;lt;T&amp;gt; sequence&lt;/h2&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;The previous part discussed the Defer query method a sequence factory, and the Create query method accepting a iterator factory. The following Create method is defined to generate a sequence of values by repeatedly calling a value factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Create&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; valueFactory, int? count = null)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }

    IEnumerable&amp;lt;TResult&amp;gt; CreateGenerator()
    {
        if (count == null)
        {
            while (true)
            {
                yield return valueFactory(); // Deferred execution.
            }
        }
        for (int index = 0; index &amp;lt; count; index++)
        {
            yield return valueFactory(); // Deferred execution.
        }
    }
    return CreateGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When count is not provided, an infinite sequence is generated. For example, the following Guid query method calls Create repeatedly with Guid.NewGuid to generate a sequence of new GUIDs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;Guid&amp;gt; NewGuid(int? count) =&amp;gt; Create(Guid.NewGuid, count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following methods generate a sequence of random numbers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; RandomInt32(
    int min = int.MinValue, int max = int.MaxValue, int? seed = null, int? count = null) =&amp;gt;
        EnumerableEx.Defer(() =&amp;gt;
        {
            Random random = new Random(seed ?? Environment.TickCount);
            return Create(() =&amp;gt; random.Next(min, max), count);
        });

public static IEnumerable&amp;lt;double&amp;gt; RandomDouble(int? seed = null, int? count = null) =&amp;gt;
    EnumerableEx.Defer(() =&amp;gt; Create(new Random(seed ?? Environment.TickCount).NextDouble, count));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Defer is called to defer the instantiation of Random.&lt;/p&gt;
&lt;p&gt;The following EmptyIfNull can be used to replace null check and null coalescing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; EmptyIfNull&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
    source ?? Enumerable.Empty&amp;lt;TSource&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EmptyIfNull(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable&amp;lt;int&amp;gt; source2)
{
    IEnumerable&amp;lt;int&amp;gt; positive = source1.EmptyIfNull()
        .Union(source2.EmptyIfNull())
        .Where(int32 =&amp;gt; int32 &amp;gt; 0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;string has a useful method Join:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    using System.Collections.Generic;

    public class String
    {
        public static string Join(string separator, IEnumerable&amp;lt;string&amp;gt; values);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It concatenates the values with a single separator between each 2 adjacent string values. A general Join query method can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Join&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource separator)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            yield return iterator.Current; // Deferred execution.
            while (iterator.MoveNext())
            {
                yield return separator; // Deferred execution.
                yield return iterator.Current; // Deferred execution.
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following overload accepting a sequence of multiple separators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Join&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEnumerable&amp;lt;TSource&amp;gt; separators)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            yield return iterator.Current; // Deferred execution.
            while (iterator.MoveNext())
            {
                foreach (TSource separator in separators)
                {
                    yield return separator; // Deferred execution.
                }
                yield return iterator.Current; // Deferred execution.
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Similar to string.Substring, a general Subsequence method can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Subsequence&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, int startIndex, int count) =&amp;gt; 
        source.Skip(startIndex).Take(count);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Comparison&lt;/h3&gt;
&lt;p&gt;The IComparer&amp;lt;T&amp;gt; and IEqualityComparer&amp;lt;T&amp;gt; interfaces are involved a lot in LINQ query methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IComparer&amp;lt;in T&amp;gt;
    {
        int Compare(T x, T y);
    }

    public interface IEqualityComparer&amp;lt;in T&amp;gt;
    {
        bool Equals(T x, T y);

        int GetHashCode(T obj);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are wrappers of simple functions. However, in C#, interfaces are less convenient then functions. C# supports lambda expression define anonymous functions inline, but does not support &lt;a href=&quot;https://en.wikipedia.org/wiki/Closure_(computer_programming)#Local_classes_and_Lambda_functions_.28Java.29&quot;&gt;anonymous class&lt;/a&gt; to enable inline interface. It could be convenient if query methods can accept functions instead of interfaces. To Iplement this, the following helper methods can be defined to convert functions to the above interfaces:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static IComparer&amp;lt;T&amp;gt; ToComparer&amp;lt;T&amp;gt;(Func&amp;lt;T, T, int&amp;gt; compare) =&amp;gt;
    Comparer&amp;lt;T&amp;gt;.Create(new Comparison&amp;lt;T&amp;gt;(compare));

private static IEqualityComparer&amp;lt;T&amp;gt; ToEqualityComparer&amp;lt;T&amp;gt;(
    Func&amp;lt;T, T, bool&amp;gt; equals, Func&amp;lt;T, int&amp;gt; getHashCode = null) =&amp;gt;
        new EqualityComparerWrapper&amp;lt;T&amp;gt;(equals, getHashCode);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides a built-in API Comparer&amp;lt;T&amp;gt;.Create to convert function to IComparer&amp;lt;T&amp;gt;, which can be directly used. F#’s core library provides a Microsoft.FSharp.Collections.HashIdentity type to wrap functions for IEqualityComparer&amp;lt;T&amp;gt;, but it is not easy to use in C#. So the EqualityComparerWrapper&amp;lt;T&amp;gt; wrapper can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class EqualityComparerWrapper&amp;lt;T&amp;gt; : IEqualityComparer&amp;lt;T&amp;gt;
{
    private readonly Func&amp;lt;T, T, bool&amp;gt; equals;

    private readonly Func&amp;lt;T, int&amp;gt; getHashCode;

    public EqualityComparerWrapper(Func&amp;lt;T, T, bool&amp;gt; equals, Func&amp;lt;T, int&amp;gt; getHashCode = null)
    {
        this.equals = equals;
        this.getHashCode = getHashCode ?? (value =&amp;gt; value.GetHashCode());
    }

    public bool Equals(T x, T y) =&amp;gt; this.equals(x, y);

    public int GetHashCode(T obj) =&amp;gt; this.getHashCode(obj);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The getHashCode function is optional, because any type inherits a GetHashCode method from object. Take the ordering query methods as example, now overloads can be defined to accept a (T, T) –&amp;gt; int function instead of IComparer&amp;lt;T&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, TKey, int&amp;gt; compare) =&amp;gt;
        source.OrderBy(keySelector, ToComparer(compare));

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, TKey, int&amp;gt; compare) =&amp;gt;
        source.OrderByDescending(keySelector, ToComparer(compare));

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, TKey, int&amp;gt; compare) =&amp;gt;
        source.ThenBy(keySelector, ToComparer(compare));

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, TKey, int&amp;gt; compare) =&amp;gt;
        source.ThenByDescending(keySelector, ToComparer(compare));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar overloads can be defined for GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
    Func&amp;lt;TKey, TKey, bool&amp;gt; equals,
    Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
        source.GroupBy(keySelector, elementSelector, resultSelector, ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    Func&amp;lt;TKey, TKey, bool&amp;gt; equals,
    Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
        outer.Join(
            inner, 
            outerKeySelector, 
            innerKeySelector, 
            resultSelector, 
            ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    Func&amp;lt;TKey, TKey, bool&amp;gt; equals,
    Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
        outer.GroupJoin(
            inner,
            outerKeySelector,
            innerKeySelector,
            resultSelector,
            ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
        source.Distinct(ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
        first.Union(second, ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
        first.Intersect(second, ToEqualityComparer(equals, getHashCode));

public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt;
        first.Except(second, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;List&lt;/h3&gt;
&lt;p&gt;The List&amp;lt;T&amp;gt; type provides handy methods, which can be implemented for sequence too. The Insert query method return a new sequence with the specified value inserted at the specified index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Insert&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index, TSource value)
{
    if (index &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(index));
    }

    IEnumerable&amp;lt;TSource&amp;gt; InsertGenerator()
    {
        int currentIndex = 0;
        foreach (TSource sourceValue in source)
        {
            if (currentIndex == index)
            {
                yield return value; // Deferred execution.
            }
            yield return sourceValue; // Deferred execution.
            currentIndex = checked(currentIndex + 1);
        }
        if (index == currentIndex)
        {
            yield return value; // Deferred execution.
        }
        else if (index &amp;gt; currentIndex)
        {
            throw new ArgumentOutOfRangeException(
                nameof(index),
                $&quot;{nameof(index)} must be within the bounds of {nameof(source)}.&quot;);
        }
    }
    return InsertGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are some difference between the above Insert query method and List&amp;lt;T&amp;gt;.Insert. The above Insert is fluent by returning IEnumerable&amp;lt;T&amp;gt;, while List&amp;lt;T&amp;gt;.Insert returns void so is not fluent. The above Insert creates a new sequence with the specified value inserted, while List&amp;lt;T&amp;gt;.Insert directly changes the original list. The above Insert also implements deferred execution and lazy evaluation with generator, while List&amp;lt;T&amp;gt;.Insert executes immediately.&lt;/p&gt;
&lt;p&gt;RemoveAt returns a new sequence with a value removed at the specified index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; RemoveAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index)
{
    if (index &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(index));
    }

    IEnumerable&amp;lt;TSource&amp;gt; RemoveAtGenerator()
    {
        int currentIndex = 0;
        foreach (TSource value in source)
        {
            if (currentIndex != index)
            {
                yield return value; // Deferred execution.
            }
            currentIndex = checked(currentIndex + 1);
        }
        if (index &amp;gt;= currentIndex)
        {
            throw new ArgumentOutOfRangeException(nameof(index));
        }
    }
    return RemoveAtGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remove returns a new sequence with the first occurrence of the specified value removed. Besides being deferred and lazy, it also accepts an optional equality comparer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Remove&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    bool isRemoved = false;
    foreach (TSource sourceValue in source)
    {
        if (!isRemoved &amp;amp;&amp;amp; comparer.Equals(sourceValue, value))
        {
            isRemoved = true;
        }
        else
        {
            yield return sourceValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RemoveAll return a new sequence with all occurrences of the specified value removed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; RemoveAll&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    foreach (TSource sourceValue in source)
    {
        if (!comparer.Equals(sourceValue, value))
        {
            yield return sourceValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Collection queries&lt;/h2&gt;
&lt;h3&gt;Comparison&lt;/h3&gt;
&lt;p&gt;ToDictionary and ToLookup accept IEqualityComparer&amp;lt;T&amp;gt; too. Their overloads for functions can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, TKey, bool&amp;gt; equals,
    Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
        source.ToDictionary(keySelector, elementSelector, ToEqualityComparer(equals, getHashCode));

public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, TKey, bool&amp;gt; equals,
    Func&amp;lt;TKey, int&amp;gt; getHashCode = null) =&amp;gt;
        source.ToLookup(keySelector, elementSelector, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Returns a single value&lt;/h2&gt;
&lt;h3&gt;List&lt;/h3&gt;
&lt;p&gt;IndexOf is similar to List&amp;lt;T&amp;gt;.IndexOf. It finds the index of first occurrence of the specified value. –1 is returned id the specified value is not found:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int IndexOf&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    int startIndex = 0,
    int? count = null,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    source = source.Skip(startIndex);
    if (count != null)
    {
        source = source.Take(count.Value);
    }
    int index = checked(0 + startIndex);
    foreach (TSource sourceValue in source)
    {
        if (comparer.Equals(sourceValue, value))
        {
            return index;
        }
        index = checked(index + 1);
    }
    return -1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LastIndexOf finds the index of last occurrence of the specified value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int LastIndexOf&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    int startIndex = 0,
    int? count = null,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    source = source.Skip(startIndex);
    if (count != null)
    {
        source = source.Take(count.Value);
    }
    int lastIndex = -1;
    int index = checked(0 + startIndex);
    foreach (TSource sourceValue in source)
    {
        if (comparer.Equals(sourceValue, value))
        {
            lastIndex = index;
        }
        index = checked(index + 1);
    }
    return lastIndex;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;.NET provides basic aggregation queries, including Sum/Average/Max/Min queries. In reality, it is also common to calculate the variance, standard deviation, and percentile. The following VariancePopulation/VarianceSample/Variance query methods are equivalent to Excel &lt;a href=&quot;https://support.office.com/en-us/article/VAR-P-function-73d1285c-108c-4843-ba5d-a51f90656f3a&quot;&gt;VAR.P&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/VAR-S-function-913633de-136b-449d-813e-65a00b2b990b&quot;&gt;VAR.S&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/VAR-function-270da762-03d5-4416-8503-10008194458a&quot;&gt;VAR&lt;/a&gt; functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static double VariancePopulation&amp;lt;TSource, TKey&amp;gt;( // Excel VAR.P function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible
{
    double[] keys = source.Select(key =&amp;gt; keySelector(key).ToDouble(formatProvider)).ToArray();
    double mean = keys.Average();
    return keys.Sum(key =&amp;gt; (key - mean) * (key - mean)) / keys.Length;
}

public static double VarianceSample&amp;lt;TSource, TKey&amp;gt;( // Excel VAR.S function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible
{
    double[] keys = source.Select(key =&amp;gt; keySelector(key).ToDouble(formatProvider)).ToArray();
    double mean = keys.Average();
    return keys.Sum(key =&amp;gt; (key - mean) * (key - mean)) / (keys.Length - 1);
}

public static double Variance&amp;lt;TSource, TKey&amp;gt;( // Excel VAR function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible =&amp;gt;
        source.VarianceSample(keySelector, formatProvider);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following StandardDeviationPopulation/StabdardDeviationSample/StabdardDeviation query methods implements Excel &lt;a href=&quot;https://support.office.com/en-us/article/STDEV-P-function-6e917c05-31a0-496f-ade7-4f4e7462f285&quot;&gt;STDEV.P&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/STDEV-S-function-7d69cf97-0c1f-4acf-be27-f3e83904cc23&quot;&gt;STDEV.S&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/STDEV-function-51fecaaa-231e-4bbb-9230-33650a72c9b0&quot;&gt;STDEV&lt;/a&gt; functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static double StandardDeviationPopulation&amp;lt;TSource, TKey&amp;gt;( // Excel STDEV.P function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible =&amp;gt;
        Math.Sqrt(source.VariancePopulation(keySelector, formatProvider));

public static double StandardDeviationSample&amp;lt;TSource, TKey&amp;gt;( // Excel STDEV.S function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible =&amp;gt;
        Math.Sqrt(source.VarianceSample(keySelector, formatProvider));

public static double StandardDeviation&amp;lt;TSource, TKey&amp;gt;( // Excel STDDEV.P function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible =&amp;gt;
        Math.Sqrt(source.Variance(keySelector, formatProvider));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following PercentileExclusive/PercentileInclusive/Percentile implement Excel &lt;a href=&quot;https://support.office.com/en-us/article/PERCENTILE-EXC-function-bbaa7204-e9e1-4010-85bf-c31dc5dce4ba&quot;&gt;PERCENTILE.EXC&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/PERCENTILE-INC-Function-DAX-15f69af8-1588-4863-9acf-2acc00384ffd&quot;&gt;PERCENTILE.INC&lt;/a&gt;/&lt;a href=&quot;https://support.office.com/en-us/article/PERCENTILE-function-91b43a53-543c-4708-93de-d626debdddca&quot;&gt;PERCENTILE&lt;/a&gt; functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static double PercentileExclusive&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE.EXC function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    double percentile,
    IComparer&amp;lt;TKey&amp;gt; comparer = null,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible
{
    if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
    {
        throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
    }

    comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
    TKey[] orderedKeys = source.Select(keySelector).OrderBy(key =&amp;gt; key, comparer).ToArray();
    int length = orderedKeys.Length;
    if (percentile &amp;lt; (double)1 / length || percentile &amp;gt; 1 - (double)1 / (length + 1))
    {
        throw new ArgumentOutOfRangeException(
            nameof(percentile),
            $&quot;{nameof(percentile)} must be in the range between (1 / source.Count()) and (1 - 1 / source.Count()).&quot;);
    }

    double index = percentile * (length + 1) - 1;
    int integerComponentOfIndex = (int)index;
    double decimalComponentOfIndex = index - integerComponentOfIndex;
    double keyAtIndex = orderedKeys[integerComponentOfIndex].ToDouble(formatProvider);

    double keyAtNextIndex = orderedKeys[integerComponentOfIndex + 1].ToDouble(formatProvider);
    return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex;
}

public static double PercentileInclusive&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE.INC function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    double percentile,
    IComparer&amp;lt;TKey&amp;gt; comparer = null,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible
{
    if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
    {
        throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
    }

    comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
    TKey[] orderedKeys = source.Select(keySelector).OrderBy(key =&amp;gt; key, comparer).ToArray();
    int length = orderedKeys.Length;

    double index = percentile * (length - 1);
    int integerComponentOfIndex = (int)index;
    double decimalComponentOfIndex = index - integerComponentOfIndex;
    double keyAtIndex = orderedKeys[integerComponentOfIndex].ToDouble(formatProvider);

    if (integerComponentOfIndex &amp;gt;= length - 1)
    {
        return keyAtIndex;
    }

    double keyAtNextIndex = orderedKeys[integerComponentOfIndex + 1].ToDouble(formatProvider);
    return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex;
}

public static double Percentile&amp;lt;TSource, TKey&amp;gt;( // Excel PERCENTILE function.
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    double percentile,
    IComparer&amp;lt;TKey&amp;gt; comparer = null,
    IFormatProvider formatProvider = null)
    where TKey : IConvertible
{
    if (percentile &amp;lt; 0 || percentile &amp;gt; 1)
    {
        throw new ArgumentOutOfRangeException(nameof(percentile), $&quot;{nameof(percentile)} must be between 0 and 1.&quot;);
    }

    return PercentileInclusive(source, keySelector, percentile, comparer, formatProvider);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Quantifiers&lt;/h3&gt;
&lt;p&gt;string has a very useful IsNullOrEmpty method, and here is the LINQ version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool IsNullOrEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; source == null || !source.Any();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Comparison&lt;/h3&gt;
&lt;p&gt;Contains and SequentialEqual also accepts IEqualityComparer&amp;lt;T&amp;gt;. They can be overloaded with functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Contains&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt; 
        source.Contains(value, ToEqualityComparer(equals, getHashCode));

public static bool SequenceEqual&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    Func&amp;lt;TSource, TSource, bool&amp;gt; equals,
    Func&amp;lt;TSource, int&amp;gt; getHashCode = null) =&amp;gt; 
        first.SequenceEqual(second, ToEqualityComparer(equals, getHashCode));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Void queries&lt;/h2&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;EnumerableEx.ForEach from Ix is very handy. However, in contrast of foreach statement, it does not support breaking the loop. So here is an improved EnumerableX.ForEach:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; onNext)
{
    foreach (TSource value in source)
    {
        if (!onNext(value))
        {
            break;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It follows the same convention of &lt;a href=&quot;http://api.jquery.com/jquery.each/&quot;&gt;jQuery.each&lt;/a&gt;. When onNext function returns false, ForEach stops execution. And the indexed overload is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; onNext)
{
    int index = 0;
    foreach (TSource value in source)
    {
        if (!onNext(value, index))
        {
            break;
        }
        index = checked(index + 1);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last overload just iterate the source sequence and pull all values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach(this IEnumerable source)
{
    IEnumerator iterator = source.GetEnumerator();
    try
    {
        while (iterator.MoveNext()) { }
    }
    finally
    {
        (iterator as IDisposable)?.Dispose();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is useful to just execute a LINQ query and ignore all query results.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (6) Interactive Extensions (Ix)</title><link>https://dixin.github.io/posts/linq-to-objects-interactive-extensions-ix-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-interactive-extensions-ix-7/</guid><description>Besides the built-in query methods (standard query operators) provided by System.Linq.Enumerable, Microsoft also provides additional query methods through the System.Interactive NuGet package (aka [In</description><pubDate>Thu, 12 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-interactive-extensions-ix&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-interactive-extensions-ix&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Besides the built-in query methods (standard query operators) provided by System.Linq.Enumerable, Microsoft also provides additional query methods through the System.Interactive NuGet package (aka &lt;a href=&quot;https://github.com/Reactive-Extensions/Rx.NET&quot;&gt;Interactive Extensions (Ix)&lt;/a&gt; library), which has a System.Linq.EnumerableEx type with the following query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sequence queries: return a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generation: Defer, Create, Return, Repeat&lt;/li&gt;
&lt;li&gt;Filtering: IgnoreElements*, DistinctUntilChanged&lt;/li&gt;
&lt;li&gt;Mapping: SelectMany, Scan, Expand&lt;/li&gt;
&lt;li&gt;Concatenation: Concat, StartWith&lt;/li&gt;
&lt;li&gt;Set: Distinct&lt;/li&gt;
&lt;li&gt;Partitioning: TakeLast*, SkipLast**&lt;/li&gt;
&lt;li&gt;Conversion: Hide&lt;/li&gt;
&lt;li&gt;Buffering: Buffer*, Share, Publish, Memoize&lt;/li&gt;
&lt;li&gt;Exception: Throw, Catch, Finally, OnErrorResumeNext, Retry&lt;/li&gt;
&lt;li&gt;Imperative: If, Case, Using, While, DoWhile, Generate, For&lt;/li&gt;
&lt;li&gt;Iteration: Do&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Value queries: return a single value (immediate execution)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: Min, Max, MinBy, MaxBy&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quantifiers: isEmpty&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Void queries: return void (immediate execution)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Iteration: ForEach&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is not much documentation for this library provided from Microsoft, except the APIs’ XML comments. In this part, these query methods are discussed by either examples and/or their internal implementation, whichever can be more intuitive.&lt;/p&gt;
&lt;p&gt;Similar to Enumerable methods, in above list, Methods returning void and methods returning a single value implement immediate execution; and methods returning an IEnumerable&amp;lt;T&amp;gt; sequence implements deferred execution, where the methods marked with * implement eager evaluation, and the unmarked methods implements lazy evaluation. The SkipLast method marked with ** is special, it can be eager evaluation or lazy evaluation, which is discussed later.&lt;/p&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Defer accepts a sequence factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Defer&amp;lt;TResult&amp;gt;(Func&amp;lt;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; enumerableFactory)
{
    foreach (TResult value in enumerableFactory())
    {
        yield return value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it defers the execution of the factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void Defer()
{
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; sequenceFactory = () =&amp;gt;
    {
        &quot;Executing factory.&quot;.WriteLine();
        return Enumerable.Empty&amp;lt;int&amp;gt;();
    };
    IEnumerable&amp;lt;int&amp;gt; sequence1 = sequenceFactory() // Executing factory.
        .Where(int32 =&amp;gt; int32 &amp;gt; 0);
    IEnumerable&amp;lt;int&amp;gt; sequence2 = EnumerableEx.Defer(sequenceFactory)
        .Where(int32 =&amp;gt; int32 &amp;gt; 0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, Create accepts an iterator factory method, and delay its execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Create&amp;lt;TResult&amp;gt;(Func&amp;lt;IEnumerator&amp;lt;TResult&amp;gt;&amp;gt; getEnumerator)
{
    using (IEnumerator&amp;lt;TResult&amp;gt; iterator = getEnumerator())
    {
        while (iterator.MoveNext())
        {
            yield return iterator.Current; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload of Create is not so intuitive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(Action&amp;lt;IYielder&amp;lt;T&amp;gt;&amp;gt; create);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It accepts a callback function of type System.Linq.IYielder&amp;lt;T&amp;gt; –&amp;gt; void. IYielder&amp;lt;T&amp;gt; has 2 members, Return and Break, representing yield return statement and yield break statement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IYielder&amp;lt;in T&amp;gt;
{
    IAwaitable Return(T value);

    IAwaitable Break();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, lambda expression does not support yield statements, compiling the following code causes error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
internal static void Create()
{
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; sequenceFactory = () =&amp;gt;
    {
        yield return 0;
        yield return 1;
        yield break;
        yield return 2;
    };
    IEnumerable&amp;lt;int&amp;gt; sequence = sequenceFactory();
    sequence.WriteLine(); // 0 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Create provides a way to virtually use the yield statements in lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Create()
{
    Action&amp;lt;IYielder&amp;lt;int&amp;gt;&amp;gt; sequenceFactory = async yield =&amp;gt;
    {
        await yield.Return(0); // yield return 0;
        await yield.Return(1); // yield return 1;
        await yield.Break(); // yield break;
        await yield.Return(2); // yield return 2;
    };
    IEnumerable&amp;lt;int&amp;gt; sequence = EnumerableEx.Create(sequenceFactory);
    sequence.WriteLine(); // 0 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In previous part, when implementing Cast, since return statement cannot be used with yield return statement, the following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    if (source is IEnumerable&amp;lt;TResult&amp;gt; genericSource)
    {
        return genericSource; // Cannot be compiled.
    }
    foreach (object value in source)
    {
        yield return (TResult)value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With Create and IYielder&amp;lt;T&amp;gt;, Cast can be implemented without yield return statement. The following code works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; CastWithCreate&amp;lt;TResult&amp;gt;(this IEnumerable source) =&amp;gt;
    source is IEnumerable&amp;lt;TResult&amp;gt; genericSource
        ? genericSource
        : EnumerableEx.Create&amp;lt;TResult&amp;gt;(async yield =&amp;gt;
            {
                foreach (object value in source)
                {
                    await yield.Return((TResult)value); // yield return (TResult)value;
                }
            });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IYielder&amp;lt;T&amp;gt; is a great idea before C# 7.0 introduces local function, but at runtime, it can have unexpected iterator behavior when used with more complex control flow, like try-catch statement. Please avoid using this query method. In the above examples, define local function to use yield return statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Create()
{
    IEnumerable&amp;lt;int&amp;gt; SequenceFactory()
    {
        yield return 0; // Deferred execution.
        yield return 1;
        yield break;
        yield return 2;
    }
    IEnumerable&amp;lt;int&amp;gt; sequence = SequenceFactory();
    sequence.WriteLine(); // 0 1
}

public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    IEnumerable&amp;lt;TResult&amp;gt; CastGenerator()
    {
        foreach (object value in source)
        {
            yield return (TResult)value; // Deferred execution.
        }
    }
    return source is IEnumerable&amp;lt;TResult&amp;gt; genericSource
        ? genericSource
        : CastGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Return just wraps value in a singleton sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Return&amp;lt;TResult&amp;gt;(TResult value)
{
    yield return value; // Deferred execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, Return is a term used in other functional languages like Haskell, means wrap something in a monad (Monad is discussed in detail in the Category Theory chapter). However in C# return has totally different semantic. It could be more consistent with .NET naming convention if this method is named as FromValue, like Task.FromResult, Task.FromException, DateTime.FromBinary, DateTimeOffset.FromFileTime, TimeSpan.FromSeconds, RegistryKey.FromHandle, Observale.FromAsync, etc..&lt;/p&gt;
&lt;p&gt;Repeat generates an infinite sequence by repeating a value forever:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult value)
{
    while (true)
    {
        yield return value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another overload repeats values in the specified sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Repeat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int? count = null)
{
    if (count == null)
    {
        while (true)
        {
            foreach (TSource value in source)
            {
                yield return value; // Deferred execution.
            }
        }
    }

    for (int i = 0; i &amp;lt; count; i++)
    {
        foreach (TSource value in source)
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When count is not provided, it repeats iterating the source sequence forever.&lt;/p&gt;
&lt;h3&gt;Filtering&lt;/h3&gt;
&lt;p&gt;IgnoreElements filters out all values from the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; IgnoreElements&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    foreach (TSource value in source) { } // Eager evaluation.
    yield break; // Deferred execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DistinctUntilChanged removes the continuous duplication:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);

public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static IEnumerable&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctUntilChanged()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[]
    {
        0, 0, 0, /* Changed. */ 1, 1, /* Changed. */ 0, 0, /* Changed. */ 2, /* Changed. */ 1, 1
    };
    source.DistinctUntilChanged().WriteLines(); // 0 1 0 2 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Mapping&lt;/h3&gt;
&lt;p&gt;SelectMany maps source sequence’s each value to the other sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TOther&amp;gt; SelectMany&amp;lt;TSource, TOther&amp;gt;
    (this IEnumerable&amp;lt;TSource&amp;gt; source, IEnumerable&amp;lt;TOther&amp;gt; other) =&amp;gt; source.SelectMany(value =&amp;gt; other);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Scan accepts the same parameters as Aggregate. The difference is, Aggregate returns one final accumulation result value, Scan returns a sequence of all accumulation steps’ results. So Scan can implement deferred execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Scan&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            yield break; // Deferred execution.
        }
        TSource accumulate = iterator.Current;
        while (iterator.MoveNext())
        {
            yield return accumulate = func(accumulate, iterator.Current); // Deferred execution.
        }
    }
}

public static IEnumerable&amp;lt;TAccumulate&amp;gt; Scan&amp;lt;TSource, TAccumulate&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func) =&amp;gt; 
        source.Select(value =&amp;gt; seed = func(seed, value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Scan()
{
    int finalProduct = Int32Source().Aggregate((product, int32) =&amp;gt; product * int32).WriteLine();
    // ((((-1 * 1) * 2) * 3) * -4) =&amp;gt; 24.

    IEnumerable&amp;lt;int&amp;gt; allProducts = Int32Source().Scan((product, int32) =&amp;gt; product * int32).WriteLines();
    // ((((-1 * 1) * 2) * 3) * -4) =&amp;gt; { -1, -2, -6, 24 }.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expand maps source values with the selector, then maps the result values with the selector, and so on.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Expand&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the following example, selector maps each value to a singleton sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExpandSingle()
{
    Enumerable
        .Range(0, 5)
        .Expand(int32 =&amp;gt; EnumerableEx.Return(int32 * int32))
        .Take(25)
        .WriteLines();
    // 0 1 2 3 4, map each int32 to { int32 * int32 } =&amp;gt;
    // 0 1 4 9 16, map each int32 to { int32 * int32 }: =&amp;gt;
    // 0 1 16 81 256, map each int32 to { int32 * int32 } =&amp;gt;
    // 0 1 256 6561 65536, map each int32 to { int32 * int32 } =&amp;gt;
    // 0 1 65536 43046721 4294967296, ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The mapping goes on forever and results a infinite sequence. If selector maps each value to a sequence with more than one values, then the result sequences grows rapidly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExpandMuliple()
{
    Enumerable
        .Range(0, 5)
        .Expand(int32 =&amp;gt; Enumerable.Repeat(int32, 2))
        .Take(75)
        .WriteLines();
    // 0 1 2 3 4 =&amp;gt; map each int32 to { int32, int32 }:
    // 0 0 1 1 2 2 3 3 4 4 =&amp;gt; map each int32 to { int32, int32 }:
    // 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 =&amp;gt; map each int32 to { int32, int32 }:
    // 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 =&amp;gt; ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If selector maps each value to empty sequence, the expanding ends after all source values are iterated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExpandNone()
{
    Enumerable
        .Range(0, 5)
        .Expand(int32 =&amp;gt; Enumerable.Empty&amp;lt;int&amp;gt;())
        .Take(100)
        .WriteLines();
    // 0 1 2 3 4 =&amp;gt; map each int32 to { }.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;2 more overloads of Concat is provided to concatenate any number of sequences:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources) =&amp;gt; sources.SelectMany(source =&amp;gt; source);

public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
    params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.Concat();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By concatenating the sequences one after another, Concat flattens a hierarchical 2-level-sequence into a flat 1-level-sequence, which is the same as SelectMany.&lt;/p&gt;
&lt;p&gt;StartWith prepend the specified values to the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; StartWith&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, params TSource[] values) =&amp;gt; values.Concat(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;A overload of Distinct is provided to accept a key selector function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    HashSet&amp;lt;TKey&amp;gt; hashSet = new HashSet&amp;lt;TKey&amp;gt;(comparer);
    foreach (TSource value in source)
    {
        if (hashSet.Add(keySelector(value)))
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Skip/Take skips/takes the specified number values at the beginning of the source sequence. In contrast, SkipLast/TakeLast skips/takes the specified number of values at the end of the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

public static IEnumerable&amp;lt;TSource&amp;gt; TakeLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SkipLastTakeLast()
{
    int[] skipFirst2 = Enumerable.Range(0, 5).Skip(2).ToArray(); // 2 3 4.
    int[] skipLast2 = Enumerable.Range(0, 5).SkipLast(2).ToArray(); // 0 1 2.
    int[] takeFirst2 = Enumerable.Range(0, 5).Take(2).ToArray(); // 0 1.
    int[] takeLast2 = Enumerable.Range(0, 5).TakeLast(2).ToArray(); // 3 4.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation of SkipLast/TakeLast is very interesting. As already discussed, Take implements lazy evaluation. However, TakeLast has to pull all values to know which are the tail values of the source sequence. So TakeLast implements eager evaluation, and uses a queue to store the tail values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }

    IEnumerable&amp;lt;TSource&amp;gt; TakeLastGGenerator()
    {
        if (count &amp;lt;= 0)
        {
            yield break; // Deferred execution.
        }
        Queue&amp;lt;TSource&amp;gt; lastValues = new Queue&amp;lt;TSource&amp;gt;(count);
        foreach (TSource value in source)
        {
            if (lastValues.Count &amp;gt;= count)
            {
                lastValues.Dequeue();
            }

            lastValues.Enqueue(value);
        } // Eager evaluation.
        while (lastValues.Count &amp;gt; 0)
        {
            yield return lastValues.Dequeue(); // Deferred execution.
        }
    }
    return TakeLastGGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once TakeLast query is executed, all values are evaluated, and the last values are stored in a Queue&amp;lt;T&amp;gt; buffer.&lt;/p&gt;
&lt;p&gt;SkipLast also uses a queue to buffer the tail values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipLast&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }

    IEnumerable&amp;lt;TSource&amp;gt; SkipLastGenerator()
    {
        Queue&amp;lt;TSource&amp;gt; lastValues = new Queue&amp;lt;TSource&amp;gt;();
        foreach (TSource value in source)
        {
            lastValues.Enqueue(value);
            if (lastValues.Count &amp;gt; count) // Can be lazy, eager, or between.
            {
                yield return lastValues.Dequeue(); // Deferred execution.
            }
        }
    }
    return SkipLastGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It uses count as the max length of the buffer. When SkipLast starts to execute, it evaluate values to fill the buffer. When the buffer is full, each new value is enqueued to the buffer, and the head value of the buffer is dequeued and yielded. So at the end of query execution, the values left in the queue are the last values to skip. If count is equal to or greater than the source sequence’s value count, when trying to pull the first value from the returned generator, all values are pulled from the source sequence and buffered in the queue, and nothing is yielded to the caller, which is eager evaluation similar to IgnoreElements. If count is 0, SkipLast becomes lazy evaluation, it does not skip anything, just simply yield each source value to caller just like Hide. So SkipLast’s laziness/eagerness depends on the ratio of count to skip and count of source sequence.&lt;/p&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Hide has the same signature as AsEnumerable. As previously demonstrated, AsEnumerable simply returns the source sequence itself to caller. Hide returns a new generator to hide the source sequence from the caller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Hide&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    foreach (TSource value in source)
    {
        yield return value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the difference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Hide()
{
    List&amp;lt;int&amp;gt; source = new List&amp;lt;int&amp;gt;() { 1, 2 };
    IEnumerable&amp;lt;int&amp;gt; readWrite = source.AsEnumerable();
    object.ReferenceEquals(source, readWrite).WriteLine(); // True
    ((List&amp;lt;int&amp;gt;)readWrite).Reverse(); // List&amp;lt;T&amp;gt;.Reverse.
    ((List&amp;lt;int&amp;gt;)readWrite).Add(3); // List&amp;lt;T&amp;gt;.Add.

    IEnumerable&amp;lt;int&amp;gt; readOnly = source.Hide();
    object.ReferenceEquals(source, readOnly).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Buffering&lt;/h3&gt;
&lt;p&gt;Buffer segments the source sequence into smaller lists:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IList&amp;lt;TSource&amp;gt;&amp;gt; Buffer&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count, int skip);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here count is the length of each smaller list, and skip is the index to start the next list. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Buffer()
{
    IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers1 = Enumerable.Range(0, 5).Buffer(2, 1);
    // {
    //    { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4 }   
    // }

    IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers2 = Enumerable.Range(0, 5).Buffer(2, 2); // Equivalent to Buffer(2).
    // {
    //    { 0, 1 }, { 2, 3 }, { 4 }   
    // }

    IEnumerable&amp;lt;IList&amp;lt;int&amp;gt;&amp;gt; buffers3 = Enumerable.Range(0, 5).Buffer(2, 3);
    // {
    //    { 0, 1 }, { 3, 4 }
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Buffer implements eager evaluation. it creates all the smaller lists when the first list is pulled.&lt;/p&gt;
&lt;p&gt;The other overload without skip uses count as skip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IList&amp;lt;TSource&amp;gt;&amp;gt; Buffer&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In above example, calling Buffer(2, 2) is equivalent to Buffer(2).&lt;/p&gt;
&lt;p&gt;Share buffers the values of a sequence and share them with several iterators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IBuffer&amp;lt;TSource&amp;gt; Share&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The returned System.Linq.IBuffer&amp;lt;T&amp;gt; is just IEnumerable&amp;lt;T&amp;gt; plus IDisposable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IBuffer&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IDisposable { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, an IEnumerable&amp;lt;T&amp;gt; sequence’s multiple iterators are independent from each other. When these iterators are called, callers pull independent values from each iterator. In contrast, shared iterator works as if they are the same single iterator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Share()
{
    IEnumerable&amp;lt;int&amp;gt; sequence = Enumerable.Range(0, 5);
    IEnumerator&amp;lt;int&amp;gt; independentIteratorA = sequence.GetEnumerator();
    IEnumerator&amp;lt;int&amp;gt; independentIteratorB = sequence.GetEnumerator();          // A|B|C
    independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 0| |
    independentIteratorB.MoveNext(); independentIteratorB.Current.WriteLine(); //  |0|
    independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 1| |
    IEnumerator&amp;lt;int&amp;gt; independentIteratorC = sequence.GetEnumerator();          //  | |
    independentIteratorC.MoveNext(); independentIteratorC.Current.WriteLine(); //  | |0
    independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 2| |
    independentIteratorB.MoveNext(); independentIteratorB.Current.WriteLine(); //  |1|
    independentIteratorA.MoveNext(); independentIteratorA.Current.WriteLine(); // 3| |
    // ...

    IBuffer&amp;lt;int&amp;gt; share = Enumerable.Range(0, 5).Share();
    IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = share.GetEnumerator();
    IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = share.GetEnumerator();        // A|B|C
    sharedIterator1.MoveNext(); sharedIterator1.Current.WriteLine(); // 0| |
    sharedIterator2.MoveNext(); sharedIterator2.Current.WriteLine(); //  |1|
    sharedIterator1.MoveNext(); sharedIterator1.Current.WriteLine(); // 2| |
    IEnumerator&amp;lt;int&amp;gt; sharedIterator3 = share.GetEnumerator();        //  | |
    sharedIterator3.MoveNext(); sharedIterator3.Current.WriteLine(); //  | |3

    share.Dispose();
    sharedIterator1.MoveNext(); // ObjectDisposedException.
    sharedIterator2.MoveNext(); // ObjectDisposedException.
    sharedIterator3.MoveNext(); // ObjectDisposedException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When pulling values with multiple independent iterators, each value can be pulled multiple times. When pulling values with multiple shared iterators, each value can only be pulled once. And IBuffer&amp;lt;T&amp;gt;.Dispose terminates the sharing. After calling Dispose, all shared iterators’ MoveNext throws ObjectDisposedException.&lt;/p&gt;
&lt;p&gt;The other overload accepts a selector function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Share&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector) =&amp;gt; 
        Create(() =&amp;gt; selector(source.Share()).GetEnumerator());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcatShared()
{
    IEnumerable&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5);
    source1.Concat(source1).WriteLines(); // 0 1 2 3 4 0 1 2 3 4

    using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
    {
        source2.Concat(source2).WriteLines(); // 0 1 2 3 4
    }
    // Equivalent to:
    IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
    source3.Share(source =&amp;gt; source.Concat(source)).WriteLines(); // 0 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above 2 kinds of Share usage are equivalent. As already discussed, Concat can be desugared as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator1 = first.GetEnumerator())
    {
        while (iterator1.MoveNext())
        {
            yield return iterator1.Current;
        }
    }
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator2 = second.GetEnumerator())
    {
        while (iterator2.MoveNext())
        {
            yield return iterator2.Current;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the above 3 Concat calls can be virtually viewed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DesugaredConcatShared()
{
    IEnumerable&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;int&amp;gt; Concat1() // source1.Concat(source1)
    {
        using (IEnumerator&amp;lt;int&amp;gt; independentIterator1 = source1.GetEnumerator())
        {
            while (independentIterator1.MoveNext())
            {
                yield return independentIterator1.Current; // yield return 0 1 2 3 4.
            }
        }
        using (IEnumerator&amp;lt;int&amp;gt; independentIterator2 = source1.GetEnumerator())
        {
            while (independentIterator2.MoveNext())
            {
                yield return independentIterator2.Current; // yield return 0 1 2 3 4.
            }
        }
    }
    Concat1().WriteLines();

    using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
    {
        IEnumerable&amp;lt;int&amp;gt; Concat2() // source2.Concat(source2)
        {
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source2.GetEnumerator())
            {
                while (sharedIterator1.MoveNext())
                {
                    yield return sharedIterator1.Current; // yield return 0 1 2 3 4.
                }
            }
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source2.GetEnumerator())
            {
                while (sharedIterator2.MoveNext())
                {
                    yield return sharedIterator2.Current; // yield return nothing.
                }
            }
        }
        Concat2().WriteLines();
    }

    IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;int&amp;gt; Concat3() // source3.Share(source =&amp;gt; source.Concat(source))
    {
        using (IBuffer&amp;lt;int&amp;gt; source = source3.Share())
        {
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source.GetEnumerator())
            {
                while (sharedIterator1.MoveNext())
                {
                    yield return sharedIterator1.Current; // yield return 0 1 2 3 4.
                }
            }
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source.GetEnumerator())
            {
                while (sharedIterator2.MoveNext())
                {
                    yield return sharedIterator2.Current; // yield return nothing.
                }
            }
        }
    }
    Concat3().WriteLines();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Concat is executed, if values are pulled from 2 independent iterators, both iterators yields all source values; if values are pulled from 2 shared iterators. only the first iterator yields all source values, and the second iterator yields nothing. Another example is Zip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ZipShared()
{
    IEnumerable&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5);
    source1.Zip(source1, ValueTuple.Create).WriteLines(); // (0, 0) (1, 1) (2, 2) (3, 3) (4, 4)

    using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
    {
        source2.Zip(source2, ValueTuple.Create).WriteLines(); // (0, 1) (2, 3)
    }
    // Equivalent to:
    IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
    source3.Share(source =&amp;gt; source.Zip(source, ValueTuple.Create)).WriteLines(); // (0, 1) (2, 3).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the above 3 Zip calls can be virtually viewed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DesugaredZipShared()
{
    IEnumerable&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;(int, int)&amp;gt; Zip1()
    {
        using (IEnumerator&amp;lt;int&amp;gt; independentIterator1 = source1.GetEnumerator())
        using (IEnumerator&amp;lt;int&amp;gt; independentIterator2 = source1.GetEnumerator())
        {
            while (independentIterator1.MoveNext() &amp;amp;&amp;amp; independentIterator2.MoveNext())
            {
                yield return (independentIterator1.Current, independentIterator2.Current);
                // yield return (0, 0) (1, 1) (2, 2) (3, 3) (4, 4).
            }
        }
    }
    Zip1().WriteLines();

    using (IBuffer&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5).Share())
    {
        IEnumerable&amp;lt;(int, int)&amp;gt; Zip2()
        {
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source2.GetEnumerator())
            using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source2.GetEnumerator())
            {
                while (sharedIterator1.MoveNext() &amp;amp;&amp;amp; sharedIterator2.MoveNext())
                {
                    yield return (sharedIterator1.Current, sharedIterator2.Current);
                    // yield return (0, 1) (2, 3).
                }
            }
        }
        Zip2().WriteLines();
    }

    IEnumerable&amp;lt;int&amp;gt; source3 = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;(int, int)&amp;gt; Zip3()
    {
        using (IBuffer&amp;lt;int&amp;gt; source = source3.Share())
        using (IEnumerator&amp;lt;int&amp;gt; sharedIterator1 = source.GetEnumerator())
        using (IEnumerator&amp;lt;int&amp;gt; sharedIterator2 = source.GetEnumerator())
        {
            while (sharedIterator1.MoveNext() &amp;amp;&amp;amp; sharedIterator2.MoveNext())
            {
                yield return (sharedIterator1.Current, sharedIterator2.Current);
                // yield return (0, 1) (2, 3).
            }
        }
    }
    Zip3().WriteLines();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Publish has the same signatures as Share:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IBuffer&amp;lt;TSource&amp;gt; Publish&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static IEnumerable&amp;lt;TResult&amp;gt; Publish&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also buffers the values in a different way, so each iterator yields all remainder values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Publish()
{
    using (IBuffer&amp;lt;int&amp;gt; publish = Enumerable.Range(0, 5).Publish())
    { 
        IEnumerator&amp;lt;int&amp;gt; remainderIteratorA = publish.GetEnumerator();
        // remainderIteratorA: 0 1 2 3 4.                                         A|B|C
        remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 0| |
        remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 1| |
        remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 2| |
        IEnumerator&amp;lt;int&amp;gt; remainderIteratorB = publish.GetEnumerator();         //  | |
        // remainderIteratorB: 3 4.                                                | |
        remainderIteratorB.MoveNext(); remainderIteratorB.Current.WriteLine(); //  |3|
        remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 3| |
        IEnumerator&amp;lt;int&amp;gt; remainderIteratorC = publish.GetEnumerator();         //  | |
        // remainderIteratorC: 4.                                                  | |
        remainderIteratorB.MoveNext(); remainderIteratorB.Current.WriteLine(); //  |4|
        remainderIteratorA.MoveNext(); remainderIteratorA.Current.WriteLine(); // 4| |
        remainderIteratorC.MoveNext(); remainderIteratorC.Current.WriteLine(); //  | |4
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Memoize (not Memorize) simply buffers all values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IBuffer&amp;lt;TSource&amp;gt; Memoize&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static IEnumerable&amp;lt;TResult&amp;gt; Memoize&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The term &lt;a href=&quot;https://en.wikipedia.org/wiki/Memoization&quot;&gt;momoize/memoization&lt;/a&gt; means buffering the function call result, so that when the same call happens again, the buffered result can be returned. Its multiple iterators work like independent, but each value is only pulled once and is buffered for reuse:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Memoize()
{
    using (IBuffer&amp;lt;int&amp;gt; memoize = Enumerable.Range(0, 5).Memoize())
    {
        IEnumerator&amp;lt;int&amp;gt; bufferIteratorA = memoize.GetEnumerator();
        // bufferIteratorA: 0 1 2 3 4.                                      A|B|C
        bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 0| |
        bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 1| |
        bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 2| |
        IEnumerator&amp;lt;int&amp;gt; bufferIteratorB = memoize.GetEnumerator();      //  | |
        // bufferIteratorB: 0 1 2 3 4.                                       | |
        bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); //  |0|
        bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 3| |
        IEnumerator&amp;lt;int&amp;gt; bufferIteratorC = memoize.GetEnumerator();      //  | |
        // bufferIteratorC: 0 1 2 3 4.                                       | |
        bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); //  |1|
        bufferIteratorA.MoveNext(); bufferIteratorA.Current.WriteLine(); // 4| |
        bufferIteratorC.MoveNext(); bufferIteratorC.Current.WriteLine(); //  | |0
        bufferIteratorC.MoveNext(); bufferIteratorC.Current.WriteLine(); //  | |1
        bufferIteratorB.MoveNext(); bufferIteratorB.Current.WriteLine(); //  |2|
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There 2 more overloads accept a readerCount to specify how many times can the buffered values be reused:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IBuffer&amp;lt;TSource&amp;gt; Memoize&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, int readerCount);

public static IEnumerable&amp;lt;TResult&amp;gt; Memoize&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, int readerCount, Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When exceeding the readerCount, an InvalidOperationException is thrown: Element no longer available in the buffer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MemoizeWithReaderCount()
{
    using (IBuffer&amp;lt;int&amp;gt; source1 = Enumerable.Range(0, 5).Memoize(2))
    {
        int[] reader1 = source1.ToArray(); // First full iteration.
        int[] reader2 = source1.ToArray(); // Second full iteration.
        int[] reader3 = source1.ToArray(); // Third full iteration: InvalidOperationException.
    }

    IEnumerable&amp;lt;int&amp;gt; source2 = Enumerable.Range(0, 5);
    source2
        .Memoize(
            readerCount: 2, 
            selector: source =&amp;gt; source // First full iteration.
                .Concat(source) // Second full iteration.
                .Concat(source)) // Third full iteration: InvalidOperationException.
        .WriteLines();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Exception&lt;/h3&gt;
&lt;p&gt;The exception query methods address some exception related scenarios for IEnumerable&amp;lt;T&amp;gt;. Throw query just throws the specified exception when executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Throw&amp;lt;TResult&amp;gt;(Exception exception)
{
    throw exception;
    yield break; // Deferred execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The yield break statement at the end is required for deferred execution. Without the yield break statement, the specified exception is thrown immediately when Throw is called. With the yield break statement, a generator is returned when Throw is called, and the specified exception is thrown when trying to pull value from the returned generator for the first time. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Throw()
{
    IEnumerable&amp;lt;int&amp;gt; @throw = EnumerableEx.Throw&amp;lt;int&amp;gt;(new OperationCanceledException());
    IEnumerable&amp;lt;int&amp;gt; query = Enumerable.Range(0, 5).Concat(@throw); // Define query.
    try
    {
        foreach (int value in query) // Execute query.
        {
            value.WriteLine();
        }
    }
    catch (OperationCanceledException exception)
    {
        exception.WriteLine();
    }
    // 0 1 2 3 4 System.OperationCanceledException: The operation was canceled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Catch accepts a source sequence and an exception handler function. When the query is executed, it pulls and yields each value from source sequence. If there is no exception of the specified type thrown during the evaluation, the handler is not called. If any exception of the specified type is thrown, it calls the exception handler with the exception. The handler returns a sequence, whose values are then pulled and yielded. So Catch’s concept is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static IEnumerable&amp;lt;TSource&amp;gt; CatchWithYield&amp;lt;TSource, TException&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TException, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; handler)
    where TException : Exception
{
    try
    {
        foreach (TSource value in source)
        {
            yield return value; // Deferred execution.
        }
    }
    catch (TException exception)
    {
        foreach (TSource value in handler(exception) ?? Empty&amp;lt;TSource&amp;gt;())
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, yield return statement inside try-catch statement is not supported by C# compiler. Compiling the above code results error CS1626: Cannot yield a value in the body of a try block with a catch clause. The code can be compiled by replacing yield return statement with IYielder&amp;lt;T&amp;gt;.Return call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; CatchWithYield&amp;lt;TSource, TException&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TException, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; handler)
    where TException : Exception =&amp;gt; Create&amp;lt;TSource&amp;gt;(async yield =&amp;gt;
{
    try
    {
        foreach (TSource value in source)
        {
            await yield.Return(value); // yield return value;
        }
    }
    catch (TException exception)
    {
        foreach (TSource value in handler(exception) ?? Empty&amp;lt;TSource&amp;gt;())
        {
            await yield.Return(value); // yield return value;
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this version does not work at runtime. So, the solution is to desugar the foreach loop to a while loop for iterator. Then the try-catch statement can go inside the loop, and only contains iterator’s MoveNext and Current calls, so that yield return statement can go outside the try-catch statement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource, TException&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TException, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; handler)
    where TException : Exception
{
    TException firstException = null;
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (true)
        {
            TSource value;
            try // Only MoveNext and Current are inside try-catch.
            {
                if (iterator.MoveNext())
                {
                    value = iterator.Current;
                }
                else
                {
                    break; // Stops while loop at the end of iteration.
                }
            }
            catch (TException exception)
            {
                firstException = exception;
                break; // Stops while loop if TException is thrown.
            }
            yield return value; // Deferred execution, outside try-catch.
        }
    }
    if (firstException != null)
    {
        foreach (TSource value in handler(firstException) ?? Empty&amp;lt;TSource&amp;gt;())
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is a simple example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CatchWithHandler()
{
    IEnumerable&amp;lt;string&amp;gt; @throw = EnumerableEx.Throw&amp;lt;string&amp;gt;(new OperationCanceledException());
    IEnumerable&amp;lt;string&amp;gt; @catch = @throw.Catch&amp;lt;string, OperationCanceledException&amp;gt;(
        exception =&amp;gt; EnumerableEx.Return($&quot;Handled {exception.GetType().Name}: {exception.Message}&quot;));
    @catch.WriteLines(); // Handled OperationCanceledException: The operation was canceled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other Catch overloads accepts multiple sequences, and return a single sequence. The idea is, when executed, it tries to pull and yield values of the first sequence. if there is no exception, it stops execution; If any exception is thrown, it tries to pull and yield the values of the next sequence, and so on; After stopping the evaluation, it checks if there is any exception from the evaluation of the last sequence. If yes, it re-throws that exception. The concept is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
public static IEnumerable&amp;lt;TSource&amp;gt; CatchWithYield&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
{
    Exception lastException = null;
    foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
    {
        lastException = null;
        try
        {
            foreach (TSource value in source)
            {
                yield return value; // Deferred execution.
            }
            break; // Stops if no exception from current sequence.
        }
        catch (Exception exception)
        {
            lastException = exception;
            // Continue with next sequence if there is exception.
        }
    }
    if (lastException != null)
    {
        throw lastException;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, yield in above code can be replaced with IYielder&amp;lt;T&amp;gt; to compile, but that does not work at runtime. So above desugared while-try-catch-yield pattern can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
{
    Exception lastException = null;
    foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            while (true)
            {
                lastException = null;
                TSource value;
                try // Only MoveNext and Current are inside try-catch.
                {
                    if (iterator.MoveNext())
                    {
                        value = iterator.Current;
                    }
                    else
                    {
                        break; // Stops while loop at the end of iteration.
                    }
                }
                catch (Exception exception)
                {
                    lastException = exception;
                    break; // Stops while loop if TException is thrown.
                }
                yield return value; // Deferred execution, outside try-catch.
            }
        }
        if (lastException == null)
        {
            break; // If no exception, stops pulling the next source; otherwise, continue.
        }
    }
    if (lastException != null)
    {
        throw lastException;
    }
}

public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;(params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.Catch();

public static IEnumerable&amp;lt;TSource&amp;gt; Catch&amp;lt;TSource&amp;gt;
    (this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second) =&amp;gt; 
        new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }.Catch();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Catch()
{
    IEnumerable&amp;lt;int&amp;gt; scanWithException = Enumerable.Repeat(0, 5).Scan((a, b) =&amp;gt; a / b); // Divide by 0.
    IEnumerable&amp;lt;int&amp;gt; range = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;int&amp;gt; castWithException = new object[] { 5, &quot;a&quot; }.Cast&amp;lt;int&amp;gt;();

    IEnumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; source1 = new IEnumerable&amp;lt;int&amp;gt;[]
    {
        scanWithException, // Executed, with DivideByZeroException.
        range, // Executed, without exception.
        castWithException // Not executed.
    };
    source1.Catch().WriteLines(); // 0 1 2 3 4

    IEnumerable&amp;lt;IEnumerable&amp;lt;int&amp;gt;&amp;gt; source2 = new IEnumerable&amp;lt;int&amp;gt;[]
    {
        scanWithException,  // Executed, with DivideByZeroException.
        castWithException // Executed, with InvalidCastException.
    };
    try
    {
        source2.Catch().WriteLines(); // 5 
    }
    catch (InvalidCastException exception)
    {
        exception.WriteLine(); // System.InvalidCastException: Specified cast is not valid.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides Throw and Catch, there is also Finally query method. Finally is very intuitive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Finally&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action finalAction)
{
    try
    {
        foreach (TSource value in source)
        {
            yield return value; // Deferred execution.
        }
    }
    finally
    {
        finalAction();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OnErrorResumeNext is the same as Concat above, but it ignores any exception when evaluating values from each sequence. The idea is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
internal static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNextWithYield&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
{
    foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
    {
        try
        {
            foreach (TSource value in source)
            {
                yield return value; // Deferred execution.
            }
        }
        catch { }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, this can be implemented with the desugared while-try-catch-yield pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(IEnumerable&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; sources)
{
    foreach (IEnumerable&amp;lt;TSource&amp;gt; source in sources)
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            while (true)
            {
                TSource value = default;
                try
                {
                    if (!iterator.MoveNext())
                    {
                        break;
                    }
                    value = iterator.Current;
                }
                catch
                {
                    break;
                }
                yield return value; // Deferred execution.
            }
        }
    }
}

public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(
    params IEnumerable&amp;lt;TSource&amp;gt;[] sources) =&amp;gt; sources.OnErrorResumeNext();

public static IEnumerable&amp;lt;TSource&amp;gt; OnErrorResumeNext&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second) =&amp;gt;
        new IEnumerable&amp;lt;TSource&amp;gt;[] { first, second }.OnErrorResumeNext();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Retry query tries to yield the source values. If there is an exception thrown, it retries to yield the values again from the beginning of the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Retry&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, int? retryCount = null) =&amp;gt; 
        Return(source).Repeat(retryCount).Catch();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If retryCount is not provided, it retries forever.&lt;/p&gt;
&lt;h3&gt;Imperative&lt;/h3&gt;
&lt;p&gt;The imperative query methods just wrap the imperative control flows, and return a sequence for fluent LINQ query. If represents the if-else statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; If&amp;lt;TResult&amp;gt;(
    Func&amp;lt;bool&amp;gt; condition, IEnumerable&amp;lt;TResult&amp;gt; thenSource, IEnumerable&amp;lt;TResult&amp;gt; elseSource = null) =&amp;gt;
        Defer(() =&amp;gt; condition() ? thenSource : elseSource ?? Enumerable.Empty&amp;lt;TResult&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Case represents the switch-case statement. It accepts a selector function as the key factory, and a dictionary of key-sequence pairs, where each key represents a case label of the switch statement. When Case query is executed, the selector function is called to return a key. If the dictionary contains the key returned by selector, then the matching sequence is returned; otherwise, a default sequence is returned:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Case&amp;lt;TValue, TResult&amp;gt;(
    Func&amp;lt;TValue&amp;gt; selector,
    IDictionary&amp;lt;TValue, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; sources,
    IEnumerable&amp;lt;TResult&amp;gt; defaultSource = null) =&amp;gt; 
        Defer(() =&amp;gt; sources.TryGetValue(selector(), out IEnumerable&amp;lt;TResult&amp;gt; result)
            ? result
            : (defaultSource ?? Enumerable.Empty&amp;lt;TResult&amp;gt;()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using represents the using statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Using&amp;lt;TSource, TResource&amp;gt;(
    Func&amp;lt;TResource&amp;gt; resourceFactory, Func&amp;lt;TResource, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; enumerableFactory) 
    where TResource : IDisposable
{
    using (TResource resource = resourceFactory())
    {
        foreach (TSource value in enumerableFactory(resource))
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While represents the while loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; While&amp;lt;TResult&amp;gt;(Func&amp;lt;bool&amp;gt; condition, IEnumerable&amp;lt;TResult&amp;gt; source)
{
    while (condition())
    {
        foreach (TResult value in source)
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DoWhile represents the do-while loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; DoWhile&amp;lt;TResult&amp;gt;(
    this IEnumerable&amp;lt;TResult&amp;gt; source, Func&amp;lt;bool&amp;gt; condition) =&amp;gt; source.Concat(While(condition, source));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generate represents the for loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Generate&amp;lt;TState, TResult&amp;gt;(
    TState initialState, 
    Func&amp;lt;TState, bool&amp;gt; condition, 
    Func&amp;lt;TState, TState&amp;gt; iterate, 
    Func&amp;lt;TState, TResult&amp;gt; resultSelector)
{
    for (TState state = initialState; condition(state); state = iterate(state))
    {
        yield return resultSelector(state); // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Surprisingly, For is exactly the same as SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; For&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; resultSelector) =&amp;gt;
        source.SelectMany(resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not sure why Generate and For are named in this way.&lt;/p&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;Do does not transform the data in any way. It simply pull source values just like Hide. It also accepts 3 callback functions, onNext, onError, and onCompleted. When each source value is pulled, onNext is called with the value. When exception is thrown for pulling source value, onError is called with the exception. After all source values are pulled successfully without exception, onCompleted is called. Do can be implemented with the desugared while-try-catch-yield pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Do&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Action&amp;lt;TSource&amp;gt; onNext, Action&amp;lt;Exception&amp;gt; onError = null, Action onCompleted = null)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (true)
        {
            TSource value;
            try
            {
                if (!iterator.MoveNext())
                {
                    break;
                }
                value = iterator.Current;
            }
            catch (Exception exception)
            {
                onError?.Invoke(exception);
                throw;
            }
            onNext(value);
            yield return value; // Deferred execution, outside try-catch.
        }
        onCompleted?.Invoke();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do is very useful for logging and tracing LINQ queries, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Do()
{
    Enumerable
        .Range(-5, 10).Do(
            onNext: value =&amp;gt; $&quot;{nameof(Enumerable.Range)} yields {value}.&quot;.WriteLine(),
            onCompleted: () =&amp;gt; $&quot;{nameof(Enumerable.Range)} query completes.&quot;.WriteLine())
        .Where(value =&amp;gt; value &amp;gt; 0).Do(
            onNext: value =&amp;gt; $&quot;{nameof(Enumerable.Where)} yields {value}.&quot;.WriteLine(),
            onCompleted: () =&amp;gt; $&quot;{nameof(Enumerable.Where)} query completes.&quot;.WriteLine())
        .TakeLast(2).Do(
            onNext: value =&amp;gt; $&quot;{nameof(EnumerableEx.TakeLast)} yields {value}.&quot;.WriteLine(),
            onCompleted: () =&amp;gt; $&quot;{nameof(EnumerableEx.TakeLast)} query completes.&quot;.WriteLine())
        .WriteLines(value =&amp;gt; $&quot;Query yields result {value}.&quot;);
    // Range yields -5.
    // Range yields -4.
    // Range yields -3.
    // Range yields -2.
    // Range yields -1.
    // Range yields 0.
    // Range yields 1.
    // Where yields 1.
    // Range yields 2.
    // Where yields 2.
    // Range yields 3.
    // Where yields 3.
    // Range yields 4.
    // Where yields 4.
    // Range query completes.
    // Where query completes.
    // TakeLast yields 3.
    // Query yields result 3.
    // TakeLast yields 4.
    // Query yields result 4.
    // TakeLast query completes.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since System.IObserver&amp;lt;T&amp;gt; is the composition of above onNext, onError, onCompleted functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public interface IObserver&amp;lt;in T&amp;gt;
    {
        void OnCompleted();

        void OnError(Exception error);

        void OnNext(T value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do also has a overload accepting an observer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Do&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, IObserver&amp;lt;TSource&amp;gt; observer) =&amp;gt;
    Do(source, observer.OnNext, observer.OnError, observer.OnCompleted);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Value queries&lt;/h2&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;The additional overloads of Max/Min accept a comparer function, and return the first maximum/minimum value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Max&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, IComparer&amp;lt;TSource&amp;gt; comparer);

public static TSource Min&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, IComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, to use the standard Max/Min with a source sequence, exception is thrown if the source type does not implement IComparable or IComparable&amp;lt;T&amp;gt;, which is a problem when the source type cannot be modified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxMinGeneric()
{
    Character maxCharacter = Characters().Max().WriteLine();
    Character minCharacter = Characters().Min().WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The overloads with comparer does not have such requirement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxMin()
{
    Character maxCharacter = Characters()
        .Max(Comparer&amp;lt;Character&amp;gt;.Create((character1, character2) =&amp;gt; 
            string.Compare(character1.Name, character2.Name, StringComparison.OrdinalIgnoreCase)));
    Character minCharacter = Characters()
        .Max(Comparer&amp;lt;Character&amp;gt;.Create((character1, character2) =&amp;gt;
            string.Compare(character1.Name, character2.Name, StringComparison.OrdinalIgnoreCase)));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MaxBy/MinBy accept key selector and key comparer functions, they return a list of all maximum/minimum values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IList&amp;lt;TSource&amp;gt; MaxBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static IList&amp;lt;TSource&amp;gt; MaxBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);

public static IList&amp;lt;TSource&amp;gt; MinBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static IList&amp;lt;TSource&amp;gt; MinBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxByMinBy()
{
    IList&amp;lt;Character&amp;gt; maxCharacters = Characters()
        .MaxBy(character =&amp;gt; character.Name, StringComparer.OrdinalIgnoreCase);
    IList&amp;lt;Character&amp;gt; minCharacters = Characters()
        .MinBy(character =&amp;gt; character.Name, StringComparer.OrdinalIgnoreCase);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The previous example of finding the maximum types in .NET core library becomes easy with MaxBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxBy()
{
    CoreLibrary.GetExportedTypes()
        .Select(type =&amp;gt; (Type: type, MemberCount: type.GetDeclaredMembers().Length))
        .MaxBy(typeAndMemberCount =&amp;gt; typeAndMemberCount.MemberCount)
        .WriteLines(max =&amp;gt; $&quot;{max.Type.FullName}:{max.MemberCount}&quot;); // System.Convert:311
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Quantifiers&lt;/h3&gt;
&lt;p&gt;There is a IsEmpty query method for convenience. It is just the opposite of Any:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool IsEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; !source.Any();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Void queries&lt;/h2&gt;
&lt;h3&gt;Iteration&lt;/h3&gt;
&lt;p&gt;ForEach represents the foreach loop, with a non-indexed overload and a indexed overload, which can be fluently used at the end of the query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; onNext)
{
    foreach (TSource value in source)
    {
        onNext(value);
    }
}

public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource, int&amp;gt; onNext)
{
    int index = 0;
    foreach (TSource value in source)
    {
        onNext(value, index);
        index = checked(index + 1);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There was an issue with the indexed ForEach – the index increment was not checked. The issue was uncovered when writing this book and has been fixed.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (5) Query Methods Implementation</title><link>https://dixin.github.io/posts/linq-to-objects-query-methods-implementation-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-query-methods-implementation-7/</guid><description>Understanding of internals of query methods is very helpful for using them accurately and effectively, and is also helpful for defining custom query methods, which is discussed later in this chapter.</description><pubDate>Tue, 10 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-query-methods-implementation&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-query-methods-implementation&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Understanding of internals of query methods is very helpful for using them accurately and effectively, and is also helpful for defining custom query methods, which is discussed later in this chapter. Just like the usage discussion part, here query methods are still categorized by returned type, but in a different order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Collection queries: return a new collection (immediate execution):
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sequence queries: return a new IEnumerable&amp;lt;T&amp;gt; sequence (deferred execution, underlined are eager evaluation):
&lt;ul&gt;
&lt;li&gt;Conversion: Cast, AsEnumerable&lt;/li&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select, SelectMany&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy*&lt;/li&gt;
&lt;li&gt;Join: SelectMany, Join*, GroupJoin*&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect*, Except*&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy*, ThenBy*, OrderByDescending*, ThenByDescending*, Reverse*&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries: return a single value (immediate execution):
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The collection conversion queries are discussed first, because they can be used to implement other queries. All query methods work functionally, while many of them have imperative implementation. For the sequential query methods returning IEnumerable&amp;lt;T&amp;gt;, generators are heavily used to enable deferred execution, where the sequence queries marked with * implements eager evaluation, and the other sequence queries implements lazy evaluation. In some cases .NET uses the yield syntactic sugar to create generator, and in other cases .NET defines custom generators to improve the performance. In this tutorial, to make it intuitive and readable, all those query methods are implemented with yield.&lt;/p&gt;
&lt;h2&gt;Argument check and deferred execution&lt;/h2&gt;
&lt;p&gt;As fore mentioned, all sequence queries returning IEnumerable&amp;lt;T&amp;gt; implement deferred execution. When a generator function contains the yield syntactic sugar, the execution of all code in the function body is deferred, including argument check. For example, argument check can be added to Select query as the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DeferredExecution
{
    internal static IEnumerable&amp;lt;TResult&amp;gt; DeferredSelect&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
    {
        if (source == null) // Deferred execution.
        {
            throw new ArgumentNullException(nameof(source));
        }
        if (selector == null) // Deferred execution.
        {
            throw new ArgumentNullException(nameof(selector));
        }

        foreach (TSource value in source)
        {
            yield return selector(value); // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the method is called, the arguments are expected to be checked immediately. However the check is deferred. Its compilation is equivalent to the following generator creation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DeferredExecution
{
    internal static IEnumerable&amp;lt;TResult&amp;gt; CompiledDeferredSelect&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
            new Generator&amp;lt;TResult, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
                iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TResult&amp;gt;(
                    start: () =&amp;gt;
                    {
                        if (source == null)
                        {
                            throw new ArgumentNullException(nameof(source));
                        }
                        if (selector == null)
                        {
                            throw new ArgumentNullException(nameof(selector));
                        }
                        sourceIterator = source.GetEnumerator();
                    },
                    moveNext: () =&amp;gt; sourceIterator.MoveNext(),
                    getCurrent: () =&amp;gt; selector(sourceIterator.Current),
                    dispose: () =&amp;gt; sourceIterator?.Dispose()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The argument check is deferred to execute when pulling the values from the returns sequence for the first time. The easiest solution is to simply isolate yield statement and deferred execution to another method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    if (source == null) // Immediate execution.
    {
        throw new ArgumentNullException(nameof(source));
    }
    if (selector == null) // Immediate execution.
    {
        throw new ArgumentNullException(nameof(selector));
    }

    IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator()
    {
        foreach (TSource value in source)
        {
            yield return selector(value); // Deferred execution.
        }
    }
    return SelectGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, the above outer function is no longer a generator function. When it is called, it immediately checks the arguments, then immediately calls the local function to create a generator and return. In this tutorial, argument null check is omitted for readability.&lt;/p&gt;
&lt;h2&gt;Collection queries&lt;/h2&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;ToArray is implemented by pulling all values from source sequence and store them to a new array. To create an array, its length has to be provided. However, the count of values in source is unknown when starting to pull the values. The easiest way is to create an empty array, when each value is pulled from source sequence, resize the array to store that value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class EnumerableExtensions
{
    public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
    {
        TSource[] array = new TSource[0];
        foreach (TSource value in source)
        {
            Array.Resize(ref array, array.Length + 1);
            array[array.Length - 1] = value;
        }
        return array;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This implementation can be optimized. First, if the source sequence implements ICollection&amp;lt;T&amp;gt;, then it already has a CopyTo method to store its values to an array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface ICollection&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        int Count { get; }

        bool IsReadOnly { get; }

        void Add(T item);

        void Clear();

        bool Contains(T item);

        void CopyTo(T[] array, int arrayIndex);

        bool Remove(T item);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, the array resizing for each value can be avoided. One option is, a initial length can be used to create the array; when pulling values from source and storing to array, if array gets full, then double its length; After all values are pulled, the array needs to be consolidated to the actual length. The following is a optimized implementation of ToArray:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is ICollection&amp;lt;TSource&amp;gt; genericCollection)
    {
        int length = genericCollection.Count;
        if (length &amp;gt; 0)
        {
            TSource[] array = new TSource[length];
            genericCollection.CopyTo(array, 0);
            return array;
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            if (iterator.MoveNext())
            {
                const int InitialLength = 4; // Initial array length.
                const int MaxLength = 0x7FEFFFFF; // Max array length: Array.MaxArrayLength.
                TSource[] array = new TSource[InitialLength];
                array[0] = iterator.Current;
                int usedLength = 1;

                while (iterator.MoveNext())
                {
                    if (usedLength == array.Length)
                    {
                        int increaseToLength = usedLength * 2; // Array is full, double its length.
                        if ((uint)increaseToLength &amp;gt; MaxLength)
                        {
                            increaseToLength = MaxLength &amp;lt;= usedLength ? usedLength + 1 : MaxLength;
                        }
                        Array.Resize(ref array, increaseToLength);
                    }
                    array[usedLength++] = iterator.Current;
                }
                Array.Resize(ref array, usedLength); // Consolidate array to its actual length.
                return array;
            }
        }
    }
    return Array.Empty&amp;lt;TSource&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ToList is much easier to implement, because List&amp;lt;T&amp;gt; has a constructor accepting an IEnumerable&amp;lt;T&amp;gt; source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static List&amp;lt;TSource&amp;gt; ToList&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; new List&amp;lt;TSource&amp;gt;(source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ToDictionary is also easy, because Dictionary&amp;lt;TKey, TValue&amp;gt; has an Add method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        source.ToDictionary(keySelector, value =&amp;gt; value, comparer);

public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{

    Dictionary&amp;lt;TKey, TElement&amp;gt; dictionary = new Dictionary&amp;lt;TKey, TElement&amp;gt;(comparer);
    foreach (TSource value in source)
    {
        dictionary.Add(keySelector(value), elementSelector(value));
    }
    return dictionary;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As previously discussed, a lookup is a dictionary of key and sequence pairs, and each key and sequence pair is just a group represented by IGrouping&amp;lt;TKey, TElement&amp;gt;, which can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Grouping&amp;lt;TKey, TElement&amp;gt; : IGrouping&amp;lt;TKey, TElement&amp;gt;
{
    private readonly List&amp;lt;TElement&amp;gt; values = new List&amp;lt;TElement&amp;gt;();

    public Grouping(TKey key) =&amp;gt; this.Key = key;

    public TKey Key { get; }

    public IEnumerator&amp;lt;TElement&amp;gt; GetEnumerator() =&amp;gt; this.values.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();

    internal void Add(TElement value) =&amp;gt; this.values.Add(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides a public lookup type, but there is no public API to instantiate it, except the ToLookup query method itself. For demonstration purpose, with the previous discussion of dictionary and lookup, a custom lookup can be quickly implemented with dictionary, where each dictionary value is a group, and each dictionary key is the has code of group key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Lookup&amp;lt;TKey, TElement&amp;gt; : ILookup&amp;lt;TKey, TElement&amp;gt;
{
    private readonly Dictionary&amp;lt;int, Grouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; groups =
        new Dictionary&amp;lt;int, Grouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;();

    private readonly IEqualityComparer&amp;lt;TKey&amp;gt; equalityComparer;

    public Lookup(IEqualityComparer&amp;lt;TKey&amp;gt; equalityComparer = null) =&amp;gt;
        this.equalityComparer = equalityComparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;

    private int GetHashCode(TKey key) =&amp;gt; key == null
        ? -1
        : this.equalityComparer.GetHashCode(key) &amp;amp; int.MaxValue;
        // int.MaxValue is 0b01111111_11111111_11111111_11111111. So the hash code of non-null key is always &amp;gt; -1.

    public IEnumerator&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GetEnumerator() =&amp;gt; this.groups.Values.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();

    public bool Contains(TKey key) =&amp;gt; this.groups.ContainsKey(this.GetHashCode(key));

    public int Count =&amp;gt; this.groups.Count;

    public IEnumerable&amp;lt;TElement&amp;gt; this[TKey key] =&amp;gt;
        this.groups.TryGetValue(this.GetHashCode(key), out Grouping&amp;lt;TKey, TElement&amp;gt; group)
            ? (IEnumerable&amp;lt;TElement&amp;gt;)group
            : Array.Empty&amp;lt;TElement&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The built-in API object.GetHashCode is not directly used to get each value’s hash code, because it does not handle null value very well in some cases. System.Nullable&amp;lt;T&amp;gt;.GetHashCode is such an example. ((int?)0).GetHashCode() and ((int?)null).GetHashCode() both return 0. So the above GetHashCode method reserves -1 for null. And any non-null value’s hash code is converted to a positive int by a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/sbf85k1c.aspx&quot;&gt;bitwise and operation&lt;/a&gt; with int.MaxValue. The above indexer getter return an empty sequence when the specified key does not exist. Similar to Grouping&amp;lt;TKey, TElement&amp;gt;.Add, the following Lookup&amp;lt;TKey, TElement&amp;gt;.AddRange is defined to add data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Lookup&amp;lt;TKey, TElement&amp;gt;
{
    public Lookup&amp;lt;TKey, TElement&amp;gt; AddRange&amp;lt;TSource&amp;gt;(
        IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, TKey&amp;gt; keySelector,
        Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
        bool skipNullKey = false)
    {
        foreach (TSource value in source)
        {
            TKey key = keySelector(value);
            if (key == null &amp;amp;&amp;amp; skipNullKey)
            {
                continue;
            }
            int hashCOde = this.GetHashCode(key);
            if (this.groups.TryGetValue(hashCOde, out Grouping&amp;lt;TKey, TElement&amp;gt; group))
            {
                group.Add(elementSelector(value));
            }
            else
            {
                this.groups.Add(hashCOde, new Grouping&amp;lt;TKey, TElement&amp;gt;(key) { elementSelector(value) });
            }
        }
        return this;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, ToLookup can be implemented by creating a lookup and adding all data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        new Lookup&amp;lt;TKey, TElement&amp;gt;(comparer).AddRange(source, keySelector, elementSelector);

public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        source.ToLookup(keySelector, value =&amp;gt; value, comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;AsEnumerable does nothing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
    source; // Deferred execution.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also implements deferred execution, because calling AsEnumerable does not pull any value from source sequence.&lt;/p&gt;
&lt;p&gt;Cast is very easy to implement with the generator syntactic sugar. Just yield each casted value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    foreach (object value in source)
    {
        yield return (TResult)value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a little optimization can be done as well. If the source is already a generic sequence of the specified result type, it can be directly returned. Logically it should be something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    if (source is IEnumerable&amp;lt;TResult&amp;gt; genericSource)
    {
        return genericSource;
    }

    foreach (object value in source)
    {
        yield return (TResult)value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However the above code cannot be compiled. The yield statement indicates the entire method should be compiled to a generator, so the return statement does not make sense here. Similar to argument check, the solution is to isolate yield statement into another method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    IEnumerable&amp;lt;TResult&amp;gt; CastGenerator()
    {
        foreach (object value in source)
        {
            yield return (TResult)value; // Deferred execution.
        }
    }
    return source is IEnumerable&amp;lt;TResult&amp;gt; genericSource
        ? genericSource
        : CastGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cast also implements deferred execution. When it is called, it returns either the source sequence itself or a generator, without pulling values from source or execute the casting.&lt;/p&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Empty can simply return an empty array::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Empty&amp;lt;TResult&amp;gt;() =&amp;gt; Array.Empty&amp;lt;TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can also be implemented with a single yield break statement, which means yielding nothing to the caller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; EmptyGenerator&amp;lt;TResult&amp;gt;()
{
    yield break;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like yield return statement can be viewed as virtually yielding a value into the generated sequence, yield break statement can also be viewed as virtually end the generated sequence. The first implementation is used by .NET because it can be faster with cache. And creating empty array is less expensive than instantiating generator.&lt;/p&gt;
&lt;p&gt;Range can be simply implemented with a loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count)
{
    if (count &amp;lt; 0 || (((long)start) + count - 1L) &amp;gt; int.MaxValue)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }

    IEnumerable&amp;lt;int&amp;gt; RangeGenerator()
    {
        int end = start + count;
        for (int value = start; value != end; value++)
        {
            yield return value; // Deferred execution.
        }
    }
    return RangeGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And Repeat has been discussed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }

    IEnumerable&amp;lt;TResult&amp;gt; RepeatGenerator()
    {
        for (int index = 0; index &amp;lt; count; index++)
        {
            yield return element; // Deferred execution.
        }
    }
    return RepeatGenerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DefaultIfEmpty can be implemented with a desugared foreach loop on source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, TSource defaultValue = default)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            // source is not empty.
            do
            {
                yield return iterator.Current; // Deferred execution.
            }
            while (iterator.MoveNext());
        }
        else
        {
            // source is empty.
            yield return defaultValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first MoveNext call detects if the source sequence is empty. If so, just yield the default value,, otherwise yield all values in the source sequence.&lt;/p&gt;
&lt;h3&gt;Filtering&lt;/h3&gt;
&lt;p&gt;Where is already discussed. The following are the non-indexed overload and index overload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            yield return value; // Deferred execution.
        }
    }
}

public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
{
    int index = -1;
    foreach (TSource value in source)
    {
        index = checked(index + 1);
        if (predicate(value, index))
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast, OfType has a type check to replace the predicate call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; OfType&amp;lt;TResult&amp;gt;(this IEnumerable source)
{
    foreach (object value in source)
    {
        if (value is TResult)
        {
            yield return (TResult)value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Mapping&lt;/h3&gt;
&lt;p&gt;Select has also been discussed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    foreach (TSource value in source)
    {
        yield return selector(value); // Deferred execution.
    }
}

public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, TResult&amp;gt; selector)
{
    int index = -1;
    foreach (TSource value in source)
    {
        index = checked(index + 1);
        yield return selector(value, index); // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation of SelectMany is also straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector)
{
    foreach (TSource value in source)
    {
        foreach (TResult result in selector(value))
        {
            yield return result; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above code clearly shows its capacity to flatten a hierarchical 2-level-sequence to a flat 1-level-sequence. To implement the overload with resultSelector, just call it and yield its result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
    Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector)
{
    foreach (TSource sourceValue in source)
    {
        foreach (TCollection collectionValue in collectionSelector(sourceValue))
        {
            yield return resultSelector(sourceValue, collectionValue); // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following are the indexed overloads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, int, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector)
{
    int index = -1;
    foreach (TSource value in source)
    {
        index = checked(index + 1);
        foreach (TResult result in selector(value, index))
        {
            yield return result; // Deferred execution.
        }
    }
}

public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, int, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
    Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector)
{
    int index = -1;
    foreach (TSource sourceValue in source)
    {
        index = checked(index + 1);
        foreach (TCollection collectionValue in collectionSelector(sourceValue, index))
        {
            yield return resultSelector(sourceValue, collectionValue); // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;GroupBy’s signature is very close to ToLookup. ToLookup returns a ILookup&amp;lt;TKey, TElement&amp;gt;, which implements IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;. However, directly calling ToLookup pulls the source values and execute the grouping immediately:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupByWithToLookup&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt; 
        source.ToLookup(keySelector, comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement deferred execution, the easiest way is to involve yield statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TSource&amp;gt; lookup = source.ToLookup(keySelector, comparer); // Eager evaluation.
    foreach (IGrouping&amp;lt;TKey, TSource&amp;gt; group in lookup)
    {
        yield return group; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When trying to pull the first value from the returned generator, ToLookup is called to evaluate all source values and group them, so that the first group can be yielded. So GroupBy implements eager evaluation. The overloads with elementSelector and resultSelector can all be implemented in the same pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TElement&amp;gt; lookup = source.ToLookup(keySelector, elementSelector, comparer); // Eager evaluation.
    foreach (IGrouping&amp;lt;TKey, TElement&amp;gt; group in lookup)
    {
        yield return group; // Deferred execution.
    }
}

public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TSource&amp;gt; lookup = source.ToLookup(keySelector, comparer); // Eager evaluation.
    foreach (IGrouping&amp;lt;TKey, TSource&amp;gt; group in lookup)
    {
        yield return resultSelector(group.Key, group); // Deferred execution.
    }
}

public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TElement&amp;gt; lookup = source.ToLookup(keySelector, elementSelector, comparer); // Eager evaluation.
    foreach (IGrouping&amp;lt;TKey, TElement&amp;gt; group in lookup)
    {
        yield return resultSelector(group.Key, group); // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;p&gt;Similar to GroupBy, GroupJoin for outer join can be simply implemented with ToLookup and yield:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoinWithLookup&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; innerLookup = inner.ToLookup(innerKeySelector, comparer); // Eager evaluation.
    foreach (TOuter outerValue in outer)
    {
        yield return resultSelector(outerValue, innerLookup[outerKeySelector(outerValue)]); // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When trying to pull the first value from the returned generator, the inner values are grouped by the keys, and stored in the inner lookup. Then, for each outer value, query the inner lookup by key. Remember when a lookup is queried with a key, it always return a sequence, even when the key does not exist, it returns a empty sequence. So that in GroupJoin, each outer value is always paired with a group of inner values. The above implementation is straightforward, but the inner source is always pulled, even when the outer source is empty. This can be avoided by a little optimization:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    using (IEnumerator&amp;lt;TOuter&amp;gt; outerIterator = outer.GetEnumerator())
    {
        if (outerIterator.MoveNext())
        {
            Lookup&amp;lt;TKey, TInner&amp;gt; innerLookup = new Lookup&amp;lt;TKey, TInner&amp;gt;(comparer).AddRange(
                inner, innerKeySelector, innerValue =&amp;gt; innerValue, skipNullKey: true); // Eager evaluation.
            do
            {
                TOuter outerValue = outerIterator.Current;
                yield return resultSelector(outerValue, innerLookup[outerKeySelector(outerValue)]); // Deferred execution.
            }
            while (outerIterator.MoveNext());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to DefaultIfEmpty, the first MoveNext call detects if the outer source is empty. Only if not, the inner values are pulled and converted to a lookup.&lt;/p&gt;
&lt;p&gt;Join for inner join can also be implemented with the similar pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; JoinWithToLookup&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    ILookup&amp;lt;TKey, TInner&amp;gt; innerLookup = inner.ToLookup(innerKeySelector, comparer); // Eager evaluation.
    foreach (TOuter outerValue in outer)
    {
        TKey key = outerKeySelector(outerValue);
        if (innerLookup.Contains(key))
        {
            foreach (TInner innerValue in innerLookup[key])
            {
                yield return resultSelector(outerValue, innerValue); // Deferred execution.
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It calls the ILookup&amp;lt;TKey, TElement&amp;gt;.Contains filter, because in inner join each outer value has to be paired with a matching inner value. Again, the above implementation can be optimized, so that the inner values are not pulled and converted to lookup even when the outer source is empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    using (IEnumerator&amp;lt;TOuter&amp;gt; outerIterator = outer.GetEnumerator())
    {
        if (outerIterator.MoveNext())
        {
            Lookup&amp;lt;TKey, TInner&amp;gt; innerLookup = new Lookup&amp;lt;TKey, TInner&amp;gt;(comparer).AddRange(
                inner, innerKeySelector, innerValue =&amp;gt; innerValue, skipNullKey: true); // Eager evaluation.
            if (innerLookup.Count &amp;gt; 0)
            {
                do
                {
                    TOuter outerValue = outerIterator.Current;
                    TKey key = outerKeySelector(outerValue);
                    if (innerLookup.Contains(key))
                    {
                        foreach (TInner innerValue in innerLookup[key])
                        {
                            yield return resultSelector(outerValue, innerValue); // Deferred execution.
                        }
                    }
                }
                while (outerIterator.MoveNext());
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;Concat can be implemented by yielding values from the first source sequence, then from the second:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second)
{
    foreach (TSource value in first)
    {
        yield return value; // Deferred execution.
    }
    foreach (TSource value in second)
    {
        yield return value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Append and Prepend can also be implemented with the similar pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Append&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element)
{
    foreach (TSource value in source)
    {
        yield return value;
    }
    yield return element;
}

public static IEnumerable&amp;lt;TSource&amp;gt; Prepend&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element)
{
    yield return element;
    foreach (TSource value in source)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;All the set query methods need to remove duplicate values in the result sequence. So the following hash set is defined to represent a collection of distinct values. The duplication of values can be identified by their hash codes, so a dictionary can be used to store distinct hash code and value pairs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class HashSet&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;
{
    private readonly IEqualityComparer&amp;lt;T&amp;gt; equalityComparer;

    private readonly Dictionary&amp;lt;int, T&amp;gt; dictionary = new Dictionary&amp;lt;int, T&amp;gt;();

    public HashSet(IEqualityComparer&amp;lt;T&amp;gt; equalityComparer = null) =&amp;gt;
        this.equalityComparer = equalityComparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;

    public IEnumerator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt; this.dictionary.Values.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, the following Add and AddRange methods can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class HashSet&amp;lt;T&amp;gt;
{
    private int GetHashCode(T value) =&amp;gt; value == null
        ? -1
        : this.equalityComparer.GetHashCode(value) &amp;amp; int.MaxValue;
        // int.MaxValue is ‭0b01111111_11111111_11111111_11111111‬, so the result of &amp;amp; is always &amp;gt; -1.

    public bool Add(T value)
    {
        int hashCode = this.GetHashCode(value);
        if (this.dictionary.ContainsKey(hashCode))
        {
            return false;
        }
        this.dictionary.Add(hashCode, value);
        return true;
    }

    public HashSet&amp;lt;T&amp;gt; AddRange(IEnumerable&amp;lt;T&amp;gt; values)
    {
        foreach(T value in values)
        {
            this.Add(value);
        }
        return this;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Add is called with a specified value, if there is already a duplicate hash code in the internal dictionary, the specified value is not stored in the dictionary and false is returned; otherwise, the specified value and its hash code are added to the internal dictionary, and true is returned. With above hash set, it is very easy to implement Distinct.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    foreach (TSource value in source)
    {
        if (hashSet.Add(value))
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add filters the values in the source sequence. This foreach-if-yield pattern is the same as Where. So logically the above implementation is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DistinctWithWhere&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    return source.Where(hashSet.Add); // Deferred execution.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this version becomes different, because It does not involve yield statement. As a result, the hash set is instantiated immediately.&lt;/p&gt;
&lt;p&gt;Union can be implemented by filtering the first source sequence with HashSet&amp;lt;T&amp;gt;.Add, then filter the second source sequence with HashSet&amp;lt;T&amp;gt;.Add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; hashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    foreach (TSource firstValue in first)
    {
        if (hashSet.Add(firstValue))
        {
            yield return firstValue; // Deferred execution.
        }
    }
    foreach (TSource secondValue in second)
    {
        if (hashSet.Add(secondValue))
        {
            yield return secondValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Except can be implemented with the same pattern of filtering with HashSet&amp;lt;T&amp;gt;.Add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
    foreach (TSource firstValue in first)
    {
        if (secondHashSet.Add(firstValue))
        {
            yield return firstValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When trying to pull the first value from the returned generator, values in the second sequence are eagerly evaluated to a hash set, which is then used to filter the first sequence.&lt;/p&gt;
&lt;p&gt;And Intersect can also be implemented with this pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; IntersectWithAdd&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
    HashSet&amp;lt;TSource&amp;gt; firstHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer);
    foreach (TSource firstValue in first)
    {
        if (secondHashSet.Add(firstValue))
        {
            firstHashSet.Add(firstValue);
        }
        else if (firstHashSet.Add(firstValue))
        {
            yield return firstValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To simplify above implementation, A Remove method can be defined for hash set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class HashSet&amp;lt;T&amp;gt;
{
    public bool Remove(T value)
    {
        int hasCode = this.GetHashCode(value);
        if (this.dictionary.ContainsKey(hasCode))
        {
            this.dictionary.Remove(hasCode);
            return true;
        }
        return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to Add, here if a value is found and removed, Remove returns true; otherwise, Remove directly returns false. So Intersect can be implemented by filtering with Remove:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    HashSet&amp;lt;TSource&amp;gt; secondHashSet = new HashSet&amp;lt;TSource&amp;gt;(comparer).AddRange(second); // Eager evaluation.
    foreach (TSource firstValue in first)
    {
        if (secondHashSet.Remove(firstValue))
        {
            yield return firstValue; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Convolution&lt;/h3&gt;
&lt;p&gt;Zip is easy to implement with a desugared foreach:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(
    this IEnumerable&amp;lt;TFirst&amp;gt; first,
    IEnumerable&amp;lt;TSecond&amp;gt; second,
    Func&amp;lt;TFirst, TSecond, TResult&amp;gt; resultSelector)
{
    using (IEnumerator&amp;lt;TFirst&amp;gt; firstIterator = first.GetEnumerator())
    using (IEnumerator&amp;lt;TSecond&amp;gt; secondIterator = second.GetEnumerator())
    {
        while (firstIterator.MoveNext() &amp;amp;&amp;amp; secondIterator.MoveNext())
        {
            yield return resultSelector(firstIterator.Current, secondIterator.Current); // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It stops yielding result when one of those 2 source sequences reaches the end..&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Skip is easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    foreach (TSource value in source)
    {
        if (count &amp;gt; 0)
        {
            count--;
        }
        else
        {
            yield return value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be optimized a little bit by desugaring the foreach loop, so that when a value should be skipped, only the source iterator’s MoveNext method is called.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (count &amp;gt; 0 &amp;amp;&amp;amp; iterator.MoveNext())
        {
            count--; // Comparing foreach loop, iterator.Current is not called.
        }
        if (count &amp;lt;= 0)
        {
            while (iterator.MoveNext())
            {
                yield return iterator.Current; // Deferred execution.
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast, SkipWhile has to pull each value from source sequence to call predicate, so there is no need to desugar foreach. The following are the non-index overload and indexed overload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    bool skip = true;
    foreach (TSource value in source)
    {
        if (skip &amp;amp;&amp;amp; !predicate(value))
        {
            skip = false;
        }
        if (!skip)
        {
            yield return value; // Deferred execution.
        }
    }
}

public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
{
    int index = -1;
    bool skip = true;
    foreach (TSource value in source)
    {
        index = checked(index + 1);
        if (skip &amp;amp;&amp;amp; !predicate(value, index))
        {
            skip = false;
        }
        if (!skip)
        {
            yield return value; // Deferred execution.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take is also straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count)
{
    if (count &amp;gt; 0)
    {
        foreach (TSource value in source)
        {
            yield return value; // Deferred execution.
            if (--count == 0)
            {
                break;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following are TakeWhile’s non-indexed overload and indexed overload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (!predicate(value))
        {
            break;
        }
        yield return value; // Deferred execution.
    }
}

public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate)
{
    int index = -1;
    foreach (TSource value in source)
    {
        index = checked(index + 1);
        if (!predicate(value, index))
        {
            break;
        }
        yield return value; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;Reverse has been discussed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Reverse&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    TSource[] array = ToArray(source); // Eager evaluation.
    for (int index = array.Length - 1; index &amp;gt;= 0; index--)
    {
        yield return array[index]; // Deferred execution.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other ordering query methods are different because they involve the IOrderedEnumerable&amp;lt;T&amp;gt; interface. Again here are the signatures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And once again the following is the definition of IOrderedEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(
            Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its implementation is a little complex:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class OrderedSequence&amp;lt;TSource, TKey&amp;gt; : IOrderedEnumerable&amp;lt;TSource&amp;gt;
{
    private readonly IEnumerable&amp;lt;TSource&amp;gt; source;

    private readonly IComparer&amp;lt;TKey&amp;gt; comparer;

    private readonly bool descending;

    private readonly Func&amp;lt;TSource, TKey&amp;gt; keySelector;

    private readonly Func&amp;lt;TSource[], Func&amp;lt;int, int, int&amp;gt;&amp;gt; previousGetComparison;

    internal OrderedSequence(
        IEnumerable&amp;lt;TSource&amp;gt; source,
        Func&amp;lt;TSource, TKey&amp;gt; keySelector,
        IComparer&amp;lt;TKey&amp;gt; comparer,
        bool descending = false,
        // previousGetComparison is only specified in CreateOrderedEnumerable, 
        // and CreateOrderedEnumerable is only called by ThenBy/ThenByDescending.
        // When OrderBy/OrderByDescending is called, previousGetComparison is not specified.
        Func&amp;lt;TSource[], Func&amp;lt;int, int, int&amp;gt;&amp;gt; previousGetComparison = null)
    {
        this.source = source;
        this.keySelector = keySelector;
        this.comparer = comparer ?? Comparer&amp;lt;TKey&amp;gt;.Default;
        this.descending = descending;
        this.previousGetComparison = previousGetComparison;
    }

    public IEnumerator&amp;lt;TSource&amp;gt; GetEnumerator()
    {
        TSource[] values = this.source.ToArray(); // Eager evaluation.
        int count = values.Length;
        if (count &amp;lt;= 0)
        {
            yield break;
        }

        int[] indexMap = new int[count];
        for (int index = 0; index &amp;lt; count; index++)
        {
            indexMap[index] = index;
        }
        // GetComparison is only called once for each generator instance.
        Func&amp;lt;int, int, int&amp;gt; comparison = this.GetComparison(values);
        Array.Sort(indexMap, (index1, index2) =&amp;gt; // index1 &amp;lt; index2
        {
            // Format compareResult. 
            // When compareResult is 0 (equal), return index1 - index2, 
            // so that indexMap[index1] is before indexMap[index2],
            // 2 equal values&apos; original order is preserved.
            int compareResult = comparison(index1, index2);
            return compareResult == 0 ? index1 - index2 : compareResult;
        }); // More eager evaluation.
        for (int index = 0; index &amp;lt; count; index++)
        {
            yield return values[indexMap[index]];
        }
    }

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();

    // Only called by ThenBy/ThenByDescending.
    public IOrderedEnumerable&amp;lt;TSource&amp;gt; CreateOrderedEnumerable&amp;lt;TNextKey&amp;gt;
        (Func&amp;lt;TSource, TNextKey&amp;gt; nextKeySelector, IComparer&amp;lt;TNextKey&amp;gt; nextComparer, bool nextDescending) =&amp;gt;
            new OrderedSequence&amp;lt;TSource, TNextKey&amp;gt;(
                this.source, nextKeySelector, nextComparer, nextDescending, this.GetComparison);

    private TKey[] GetKeys(TSource[] values)
    {
        int count = values.Length;
        TKey[] keys = new TKey[count];
        for (int index = 0; index &amp;lt; count; index++)
        {
            keys[index] = this.keySelector(values[index]);
        }
        return keys;
    }

    private Func&amp;lt;int, int, int&amp;gt; GetComparison(TSource[] values)
    {
        // GetComparison is only called once for each generator instance,
        // so GetKeys is only called once during the ordering query execution.
        TKey[] keys = this.GetKeys(values);
        if (this.previousGetComparison == null)
        {
            // In OrderBy/OrderByDescending.
            return (index1, index2) =&amp;gt;
                // OrderBy/OrderByDescending always need to compare keys of 2 values.
                this.CompareKeys(keys, index1, index2);
        }
        // In ThenBy/ThenByDescending.
        Func&amp;lt;int, int, int&amp;gt; previousComparison = this.previousGetComparison(values);
        return (index1, index2) =&amp;gt;
        {
            // Only when previousCompareResult is 0 (equal), 
            // ThenBy/ThenByDescending needs to compare keys of 2 values.
            int previousCompareResult = previousComparison(index1, index2);
            return previousCompareResult == 0
                ? this.CompareKeys(keys, index1, index2)
                : previousCompareResult;
        };
    }

    private int CompareKeys(TKey[] keys, int index1, int index2)
    {
        // Format compareResult to always be 0, -1, or 1.
        int compareResult = this.comparer.Compare(keys[index1], keys[index2]);
        return compareResult == 0
            ? 0
            : (this.descending ? (compareResult &amp;gt; 0 ? -1 : 1) : (compareResult &amp;gt; 0 ? 1 : -1));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement deferred execution, its constructor does not evaluate any value from source. So that the query methods can just instantiate it and return:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        new OrderedSequence&amp;lt;TSource, TKey&amp;gt;(source, keySelector, comparer);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        new OrderedSequence&amp;lt;TSource, TKey&amp;gt;(source, keySelector, comparer, descending: true);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        source.CreateOrderedEnumerable(keySelector, comparer, descending: false);

public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    IComparer&amp;lt;TKey&amp;gt; comparer = null) =&amp;gt;
        source.CreateOrderedEnumerable(keySelector, comparer, descending: true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OrderedSequence&amp;lt;T&amp;gt; is a sequence wrapping the source data and iteration algorithm of ordering, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the source sequence,&lt;/li&gt;
&lt;li&gt;the keySelector function,&lt;/li&gt;
&lt;li&gt;a bool value indicating the ordering should be descending or ascending&lt;/li&gt;
&lt;li&gt;a previousGetComparison function, which identifies whether current OrderedSequence&amp;lt;T&amp;gt; is created by OrderBy/OrderByDescending, or by ThenBy/ThenByDescending
&lt;ul&gt;
&lt;li&gt;When OrderBy/OrderByDescending are called, they directly instantiate an OrderedSequence&amp;lt;T&amp;gt; with a null previousGetComparison function.&lt;/li&gt;
&lt;li&gt;When ThenBy/ThenByDescending are called, they call CreateOrderedEnumerable to instantiate OrderedSequence&amp;lt;T&amp;gt;, and pass its OrderedSequence&amp;lt;T&amp;gt;’s GetComparison method as the previousGetComparison function for the new OrderedSequence&amp;lt;T&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OrderedSequence’s GetEnumeraor method uses yield statement to return an iterator (not generator this time). Eager evaluation is implemented, because it has to pull all values in the source sequence and sort them, in order to know which value is the first one to yield. For performance consideration, instead of sorting the values from source sequence, here the indexes of values are sorted. For example, in the values array, if indexes { 0, 1, 2 } become { 2, 0, 1 } after sorting, then the values are yielded in the order of { values[2], values[0], values[1] }.&lt;/p&gt;
&lt;p&gt;When the eager evaluation starts, GetComparison is called. It evaluates all keys of the values, and returns a comparison function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If previousGetComparison function is null, it returns a comparison function to represent an OrderBy/OrderByDescending query, which just compares the keys.&lt;/li&gt;
&lt;li&gt;if previousGetComparison function is not null, it returns a comparison function to represents an ThenBy/ThenByDescending query, which first check the previous compare result, and only compare the keys when previous compare result is equal.&lt;/li&gt;
&lt;li&gt;In both cases, comparison function calls CompareKeys to compare 2 keys. CompareKeys calls IComparer&amp;lt;TKey&amp;gt;.Compare, and format the compare result to 0, -1, or 1 to represent less then, equal to, greater than. If the descending field is true, 1 and -1 are swapped.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eventually, the returned comparison function is used during GetEnumerator’s eager evaluation, to sort the indexes of values. When comparing keys for index1 and index2, index1 is always less than index2. In another word, values[index1] is before values[index2] before the ordering query execution. If the result from comparison function is equal, index1 - index2 is used instead of 0. So that the relative positions of values at index1 and index2 are preserved, values[index1] is still before values[index2] after the ordering query execution.&lt;/p&gt;
&lt;h2&gt;Value queries&lt;/h2&gt;
&lt;p&gt;This category of query methods iterate the source sequence, and cannot implement deferred execution.&lt;/p&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;To implement First, just pull the source sequence once. But if the source already supports index, then source[0] can be pulled, which is cheaper than calling the GetEnumerator, MoveNext, and Current methods. The index support can be identified by detecting if source also implements IList&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IList&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        T this[int index] { get; set; }

        int IndexOf(T item);

        void Insert(int index, T item);

        void RemoveAt(int index);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, IList&amp;lt;T&amp;gt; is implemented by T[] array, List&amp;lt;T&amp;gt;, and Collection&amp;lt;T&amp;gt;, etc. So the following is an optimized implementation of First:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        if (list.Count &amp;gt; 0)
        {
            return list[0];
        }
    }
    else
    {
        foreach (TSource value in source)
        {
            return value;
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload with predicate is also easy to implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            return value;
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation of FirstOrDefault is very similar. When source is empty, just return the default value instead of throwing exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        if (list.Count &amp;gt; 0)
        {
            return list[0];
        }
    }
    else
    {
        foreach (TSource value in source)
        {
            return value;
        }
    }
    return default;
}

public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            return value;
        }
    }
    return default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Last and LastOrDefault can be implemented in the similar pattern, with desugared foreach loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        int count = list.Count;
        if (count &amp;gt; 0)
        {
            return list[count - 1];
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            if (iterator.MoveNext())
            {
                TSource last;
                do
                {
                    last = iterator.Current;
                }
                while (iterator.MoveNext());
                return last;
            }
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
}

public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        for (int index = list.Count - 1; index &amp;gt;= 0; index--)
        {
            TSource value = list[index];
            if (predicate(value))
            {
                return value;
            }
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            while (iterator.MoveNext())
            {
                TSource last = iterator.Current;
                if (predicate(last))
                {
                    while (iterator.MoveNext())
                    {
                        TSource value = iterator.Current;
                        if (predicate(value))
                        {
                            last = value;
                        }
                    }
                    return last;
                }
            }
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
}

public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        int count = list.Count;
        if (count &amp;gt; 0)
        {
            return list[count - 1];
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            if (iterator.MoveNext())
            {
                TSource last;
                do
                {
                    last = iterator.Current;
                }
                while (iterator.MoveNext());
                return last;
            }
        }
    }
    return default;
}

public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        for (int index = list.Count - 1; index &amp;gt;= 0; index--)
        {
            TSource value = list[index];
            if (predicate(value))
            {
                return value;
            }
        }
        return default;
    }
    TSource last = default;
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            last = value;
        }
    }
    return last;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And ElementAt and ElementAtOrDefault too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        return list[index];
    }

    if (index &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(index));
    }

    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            if (index-- == 0)
            {
                return iterator.Current;
            }
        }
    }
    throw new ArgumentOutOfRangeException(nameof(index));
}

public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index)
{
    if (index &amp;gt;= 0)
    {
        if (source is IList&amp;lt;TSource&amp;gt; list)

        {
            if (index &amp;lt; list.Count)
            {
                return list[index];
            }
        }
        else
        {
            using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
            {
                while (iterator.MoveNext())
                {
                    if (index-- == 0)
                    {
                        return iterator.Current;
                    }
                }
            }
        }
    }
    return default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single and SingleOrDefault is more strict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        switch (list.Count)
        {
            case 0:
                throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
            case 1:
                return list[0];
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            if (!iterator.MoveNext()) // source is empty.
            {
                throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
            }

            TSource first = iterator.Current;
            if (!iterator.MoveNext())
            {
                return first;
            }
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains more than one element.&quot;);
}

public static TSource Single&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            TSource value = iterator.Current;
            if (predicate(value))
            {
                while (iterator.MoveNext())
                {
                    if (predicate(iterator.Current))
                    {
                        throw new InvalidOperationException(&quot;Sequence contains more than one matching element.&quot;);
                    }
                }
                return value;
            }
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains no matching element.&quot;);
}

public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    if (source is IList&amp;lt;TSource&amp;gt; list)
    {
        switch (list.Count)
        {
            case 0:
                return default;
            case 1:
                return list[0];
        }
    }
    else
    {
        using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
        {
            if (iterator.MoveNext())
            {
                TSource first = iterator.Current;
                if (!iterator.MoveNext())
                {
                    return first;
                }
            }
            else
            {
                return default;
            }
        }
    }
    throw new InvalidOperationException(&quot;Sequence contains more than one element.&quot;);
}

public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            TSource value = iterator.Current;
            if (predicate(value))
            {
                while (iterator.MoveNext())
                {
                    if (predicate(iterator.Current))
                    {
                        throw new InvalidOperationException(&quot;Sequence contains more than one matching element.&quot;);
                    }
                }

                return value;
            }
        }
    }
    return default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Aggregation pulls all values from source and accumulate them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TAccumulate seed,
    Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func,
    Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector)
{
    TAccumulate accumulate = seed;
    foreach (TSource value in source)
    {
        accumulate = func(accumulate, value);
    }
    return resultSelector(accumulate);
}

public static TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func)
{
    TAccumulate accumulate = seed;
    foreach (TSource value in source)
    {
        accumulate = func(accumulate, value);
    }
    return accumulate;
}

public static TSource Aggregate&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
        }

        TSource accumulate = iterator.Current;
        while (iterator.MoveNext())
        {
            accumulate = func(accumulate, iterator.Current);
        }
        return accumulate;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Count can be implemented by iterating the source sequence. And if the source sequence is a collection, then it has a Count property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    switch (source)
    {
        case ICollection&amp;lt;TSource&amp;gt; genericCollection:
            return genericCollection.Count;
        case ICollection collection:
            return collection.Count;
        default:
            int count = 0;
            using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
            {
                while (iterator.MoveNext())
                {
                    count = checked(count + 1); // Comparing foreach loop, iterator.Current is never called.
                }
            }
            return count;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the overload with predicate can be implemented by filtering with the predicate function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    int count = 0;
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            count = checked(count + 1);
        }
    }
    return count;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LongCount cannot use collections’ Count property because it returns int. It simply counts the values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    long count = 0L;
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            count = checked(count + 1L); // Comparing foreach loop, iterator.Current is never called.
        }
    }
    return count;
}

public static long LongCount&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    long count = 0L;
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            count = checked(count + 1L);
        }
    }
    return count;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BTW – &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms229042.aspx&quot;&gt;.NET Framework Design Guidelines’&lt;/a&gt; &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms229045.aspx&quot;&gt;General Naming Conventions&lt;/a&gt; says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DO use a generic CLR type name, rather than a language-specific name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It would be more consistent if LongCount was named as Int64Count, just like Convert.ToInt64, etc.&lt;/p&gt;
&lt;p&gt;Min has 22 overloads, the following is the overload for decimal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Min(this IEnumerable&amp;lt;decimal&amp;gt; source)
{
    decimal min;
    using (IEnumerator&amp;lt;decimal&amp;gt; iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
        }
        min = iterator.Current;
        while (iterator.MoveNext())
        {
            decimal value = iterator.Current;
            if (value &amp;lt; min)
            {
                min = value;
            }
        }
    }
    return min;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the decimal overload with selector can be implemented with Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Min&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt; selector) =&amp;gt; source.Select(selector).Min();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max also has 22 overloads. The overload for decimal without and with selector can be implemented with the same pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Max(this IEnumerable&amp;lt;decimal&amp;gt; source)
{
    decimal max;
    using (IEnumerator&amp;lt;decimal&amp;gt; iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
        }

        max = iterator.Current;
        while (iterator.MoveNext())
        {
            decimal value = iterator.Current;
            if (value &amp;gt; max)
            {
                max = value;
            }
        }
    }
    return max;
}

public static decimal Max&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt; selector) =&amp;gt; source.Select(selector).Max();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sum/Average has 20 overloads each. Also take the decimal overloads as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static long Sum&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, long&amp;gt; selector) =&amp;gt;
    source.Select(selector).Sum();

public static decimal Sum(this IEnumerable&amp;lt;decimal&amp;gt; source)
{
    decimal sum = 0;
    foreach (decimal value in source)
    {
        sum += value;
    }
    return sum;
}

public static decimal Average&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, decimal&amp;gt; selector)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException(&quot;Sequence contains no elements.&quot;);
        }
        decimal sum = selector(iterator.Current);
        long count = 1L;
        while (iterator.MoveNext())
        {
            sum += selector(iterator.Current);
            count++;
        }
        return sum / count;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;All, Any, and Contains return a bool result. They can be implemented in a similar foreach-if pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool All&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (!predicate(value))
        {
            return false;
        }
    }
    return true;
}

public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            return true;
        }
    }
    return false;
}

public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator())
    {
        return iterator.MoveNext(); // Not needed to call iterator.Current.
    }
}

public static bool Contains&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    TSource value,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    if (comparer == null &amp;amp;&amp;amp; source is ICollection&amp;lt;TSource&amp;gt; collection)
    {
        return collection.Contains(value);
    }
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    foreach (TSource sourceValue in source)
    {
        if (comparer.Equals(sourceValue, value))
        {
            return true;
        }
    }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Contains can b optimized a little bit because collection already has a Contains method.&lt;/p&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;The implementation of SequenceEqual is a little similar to Zip, where 2 sequences are iterated at the same time. They are equal only when their counts are equal, and their values at each index are equal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first,
    IEnumerable&amp;lt;TSource&amp;gt; second,
    IEqualityComparer&amp;lt;TSource&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TSource&amp;gt;.Default;
    if (first is ICollection&amp;lt;TSource&amp;gt; firstCollection &amp;amp;&amp;amp; second is ICollection&amp;lt;TSource&amp;gt; secondCollection
        &amp;amp;&amp;amp; firstCollection.Count != secondCollection.Count)
    {
        return false;
    }
    using (IEnumerator&amp;lt;TSource&amp;gt; firstIterator = first.GetEnumerator())
    using (IEnumerator&amp;lt;TSource&amp;gt; secondIterator = second.GetEnumerator())
    {
        while (firstIterator.MoveNext())
        {
            if (!secondIterator.MoveNext() || !comparer.Equals(firstIterator.Current, secondIterator.Current))
            {
                return false;
            }
        }
        return !secondIterator.MoveNext();
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (4) Deferred Execution, Lazy Evaluation and Eager Evaluation</title><link>https://dixin.github.io/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation-7/</guid><description>As fore mentioned, when a generator method (method contains yield statement and returns IEnumerable&lt;T&gt;) is compiled to a pure function, which constructs a generator and return it to caller. So at runt</description><pubDate>Sat, 07 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As fore mentioned, when a generator method (method contains yield statement and returns IEnumerable&amp;lt;T&amp;gt;) is compiled to a pure function, which constructs a generator and return it to caller. So at runtime, when a generator method is called, the values in output sequence is not pulled or evaluated. This is called deferred execution.&lt;/p&gt;
&lt;h2&gt;Deferred execution vs. immediate execution&lt;/h2&gt;
&lt;p&gt;To demonstrate how the deferred execution work, take the Select query method as example, with tracing of the control flow:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DeferredExecution
{
    internal static IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator&amp;lt;TSource, TResult&amp;gt;(
        this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
    {
        &quot;Select query starts.&quot;.WriteLine();
        foreach (TSource value in source)
        {
            $&quot;Select query is calling selector with {value}.&quot;.WriteLine();
            TResult result = selector(value);
            $&quot;Select query is yielding {result}.&quot;.WriteLine();
            yield return result;
        }
        &quot;Select query ends.&quot;.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The foreach loop can be desugared:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; DesugaredSelectGenerator&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    &quot;Select query starts.&quot;.WriteLine();
    IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null; // start.
    try
    {
        sourceIterator = source.GetEnumerator(); // start.
        while (sourceIterator.MoveNext()) // moveNext.
        {
            $&quot;Select query is calling selector with {sourceIterator.Current}.&quot;.WriteLine(); // getCurrent.
            TResult result = selector(sourceIterator.Current); // getCurrent.
            $&quot;Select query is yielding {result}.&quot;.WriteLine(); // getCurrent.
            yield return result; // getCurrent.
        }
    }
    finally
    {
        sourceIterator?.Dispose(); // dispose.
    }
    &quot;Select query ends.&quot;.WriteLine(); // end.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After compilation, it is equivalent to the following generator creation and return:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CompiledSelectGenerator&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
        new Generator&amp;lt;TResult, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TResult&amp;gt;(
                start: () =&amp;gt;
                {
                    &quot;Select query starts.&quot;.WriteLine();
                    sourceIterator = source.GetEnumerator();
                },
                moveNext: () =&amp;gt; sourceIterator.MoveNext(),
                getCurrent: () =&amp;gt;
                {
                    $&quot;Select query is calling selector with {sourceIterator.Current}.&quot;.WriteLine();
                    TResult result = selector(sourceIterator.Current);
                    $&quot;Select query is yielding {result}.&quot;.WriteLine();
                    return result;
                },
                dispose: () =&amp;gt; sourceIterator?.Dispose(),
                end: () =&amp;gt; &quot;Select query ends.&quot;.WriteLine()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also demonstrates how the tracing is triggered. The returned generator represents the output sequence and wraps the the data and algorithm of query. When SelectGenerator is called, the output sequence is returned to caller, the query logic is not executed, and the values in the output sequence are not evaluated.&lt;/p&gt;
&lt;p&gt;In contrast, the following query is implemented with traditional collection instead of generator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectList&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    &quot;Select query starts.&quot;.WriteLine();
    List&amp;lt;TResult&amp;gt; resultSequence = new List&amp;lt;TResult&amp;gt;();
    foreach (TSource value in source)
    {
        $&quot;Select query is calling selector with {value}.&quot;.WriteLine();
        TResult result = selector(value);
        $&quot;Select query is storing {result}.&quot;.WriteLine();
        resultSequence.Add(result);
    }

    &quot;Select query ends.&quot;.WriteLine();
    return resultSequence;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output sequence is represented by a list with known values. So when the output sequence is returned to caller, the query algorithm of mapping is already executed, and the values in the output sequence are evaluated. This is immediate execution. Calling these 2 methods shows the difference at runtime:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachSelect()
{
    IEnumerable&amp;lt;string&amp;gt; deferredQuery = Enumerable.Range(1, 5)
        .SelectGenerator(int32 =&amp;gt; new string(&apos;*&apos;, int32));
    foreach (string result in deferredQuery) // Execute query.
    {
        // Select query starts.
        // Select query is calling selector with 1.
        // Select query is yielding *.
        // Select query is calling selector with 2.
        // Select query is yielding **.
        // Select query is calling selector with 3.
        // Select query is yielding ***.
        // Select query is calling selector with 4.
        // Select query is yielding ****.
        // Select query is calling selector with 5.
        // Select query is yielding *****.
        // Select query ends.
    }

    IEnumerable&amp;lt;string&amp;gt; immediateQuery = Enumerable.Range(1, 5)
        .SelectList(int32 =&amp;gt; new string(&apos;*&apos;, int32)); // Execute query.
    // Select query starts.
    // Select query is calling selector with 1.
    // Select query is storing *.
    // Select query is calling selector with 2.
    // Select query is storing **.
    // Select query is calling selector with 3.
    // Select query is storing ***.
    // Select query is calling selector with 4.
    // Select query is storing ****.
    // Select query is calling selector with 5.
    // Select query is storing *****.
    // Select query ends.
    foreach (string result in immediateQuery) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When SelectorGenerator is called, its query logic of mapping is not executed, and its result values are not available yet. Later when trying to pull result values from the returned sequence, the query logic of mapping is executed, and each result value is evaluated sequentially. When SelectList is called, its query logic of mapping is executed, and its result values are evaluated and stored in the returned sequence, which is a list. Since any method with yield statement is compiled to construct and return a generator, any method with yield statement implements deferred execution.&lt;/p&gt;
&lt;p&gt;In LINQ to Objects, the query methods returning IEnumerable&amp;lt;T&amp;gt; sequence all implement deferred execution. Apparently, the other query methods returning a collection (like ToArray, ToList, etc.) or a single value (like Single, First, etc.) must implement immediate execution to start result value evaluation All the query methods implementation will be discussed later in this chapter.&lt;/p&gt;
&lt;h3&gt;Cold sequence vs. hot sequence&lt;/h3&gt;
&lt;p&gt;In above examples, one function returns a generator, which is a sequence wraps data and iteration algorithms instead of evaluated values. This kind of sequence is called cold sequence. The other method returns a collection, which is is a sequence wraps values already evaluated from data and iteration algorithms. This kind of sequence is called hot sequence. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;double&amp;gt; AbsAndSqrtGenerator(double @double)
{
    yield return Math.Abs(@double);
    yield return Math.Sqrt(@double);
}

internal static IEnumerable&amp;lt;double&amp;gt; AbsAndSqrtArray(double @double) =&amp;gt; new double[]
{
    Math.Abs(@double),
    Math.Sqrt(@double)
};

internal static void Sequences(double @double)
{
    IEnumerable&amp;lt;double&amp;gt; cold = AbsAndSqrtGenerator(@double); // Deferred execution.
    // Math.Abs and Math.Sqrt are not executed.
    foreach (double result in cold) { }
    // Math.Abs and Math.Sqrt are executed.

    IEnumerable&amp;lt;double&amp;gt; hot = AbsAndSqrtArray(@double); // Immediate execution.
    // Math.Abs and Math.Sqrt are executed.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET, the convention is that all sequences returned by query methods (like Select, Where, etc.) are cold.&lt;/p&gt;
&lt;h2&gt;Lazy evaluation vs. eager evaluation&lt;/h2&gt;
&lt;p&gt;There are 2 types of deferred execution. Take Select as example, the query execution is deferred until values are pulled from the result sequence. When trying to pull the first result value, the query executes until the first result value is evaluated, at this moment the rest result values remain not evaluated. When trying to pull the second result value, the query executes until the second result value is evaluated, and at this moment the rest result values remain not evaluated, and so on. If the pulling stops in the middle, the rest result values remain not evaluated. This behavior is called lazy evaluation. Besides above Select query, Where query is also an example of lazy evaluation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; WhereGenerator&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    &quot;Where query starts.&quot;.WriteLine();
    foreach (TSource value in source)
    {
        $&quot;Where query is calling predicate with {value}.&quot;.WriteLine();
        if (predicate(value))
        {
            $&quot;Where query is yielding {value}.&quot;.WriteLine();
            yield return value;
        }
    }
    &quot;Where query ends.&quot;.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its compilation is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledWhereGenerator&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate) =&amp;gt;
        new Generator&amp;lt;TSource, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
                start: () =&amp;gt;
                {
                    &quot;Where query starts.&quot;.WriteLine();
                    sourceIterator = source.GetEnumerator();
                },
                moveNext: () =&amp;gt;
                {
                    while (sourceIterator.MoveNext())
                    {
                        $&quot;Where query is calling predicate with {sourceIterator.Current}.&quot;.WriteLine();
                        if (predicate(sourceIterator.Current))
                        {
                            return true;
                        }
                    }
                    return false;
                },
                getCurrent: () =&amp;gt;
                {
                    $&quot;Where query is yielding {sourceIterator.Current}.&quot;.WriteLine();
                    return sourceIterator.Current;
                },
                dispose: () =&amp;gt; sourceIterator?.Dispose(),
                end: () =&amp;gt; &quot;Where query ends.&quot;.WriteLine()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example pulls values from the composition of Where and Select queries, to demonstrate how the lazy evaluation works for each result value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachWhereAndSelect()
{
    IEnumerable&amp;lt;string&amp;gt; deferredQuery = Enumerable.Range(1, 5)
        .WhereGenerator(int32 =&amp;gt; int32 &amp;gt; 2) // Deferred execution.
        .SelectGenerator(int32 =&amp;gt; new string(&apos;*&apos;, int32)); // Deferred execution.
    foreach (string result in deferredQuery)
    {
        // Select query starts.
        // Where query starts.
        // Where query is calling predicate with 1.
        // Where query is calling predicate with 2.
        // Where query is calling predicate with 3.
        // Where query is yielding 3.
        // Select query is calling selector with 3.
        // Select query is yielding ***.
        // Where query is calling predicate with 4.
        // Where query is yielding 4.
        // Select query is calling selector with 4.
        // Select query is yielding ****.
        // Where query is calling predicate with 5.
        // Where query is yielding 5.
        // Select query is calling selector with 5.
        // Select query is yielding *****.
        // Where query ends.
        // Select query ends.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final query is a generator created by Select query, when foreach loop pulls the first result value, the Select query starts execution and pulls the first value from its source sequence, which is another generator created by Where query. So Where query starts execution too. Where query pulls values from its source sequence, until its first result value 3 is yielded. Therefore, Select pulls the first value 3, and yields its first result value ***. Then, the pulling and evaluation continues. The foreach loop pulls the next result value from generator created by Select, which pulls the next result value from generator created by Where, and the generator created by Where yields its next result value 4 to the generator created by Select, which yields its next value **** to the foreach loop. This goes on, and when there is no result value to pull, the query execution ends.&lt;/p&gt;
&lt;p&gt;The opposition of lazy evaluation, is eager evaluation, where trying to pull a result value for the first time causes all result values evaluated. For example, Reverse query implements deferred execution. When its result sequence is pulled for the first time, it stars execution. It has to evaluate all the result values, in order to know what is the last source value, and yield it as its first result value. The following code demonstrates how Reserve is implemented::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; ReverseGenerator&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
{
    &quot;Reverse query starts.&quot;.WriteLine();
    TSource[] values = source.ToArray();
    $&quot;Reverse query evaluated all {values.Length} value(s) in source sequence.&quot;.WriteLine();
    for (int index = values.Length - 1; index &amp;gt;= 0; index--)
    {
        $&quot;Reverse query is yielding index {index} of input sequence.&quot;.WriteLine();
        yield return values[index];
    }
    &quot;Reverse query ends.&quot;.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its compilation is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledReverseGenerator&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt;
    new Generator&amp;lt;TSource, (TSource[] Values, int Index)&amp;gt;(
        data: default, // (TSource[] Values, int Index) data = default;
        iteratorFactory: data =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
            start: () =&amp;gt;
            {
                &quot;Reverse query starts.&quot;.WriteLine();
                TSource[] values = source.ToArray();
                $&quot;Reverse query evaluated all {values.Length} value(s) in input sequence.&quot;.WriteLine();
                data = (values, values.Length);
            },
            moveNext: () =&amp;gt;
            {
                data = (data.Values, data.Index - 1);
                return data.Index &amp;gt;= 0;
            },
            getCurrent: () =&amp;gt;
            {
                $&quot;Reverse query is yielding index {data.Index} of input sequence.&quot;.WriteLine();
                return data.Values[data.Index];
            },
            end: () =&amp;gt; &quot;Reverse query ends.&quot;.WriteLine()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example pulls values from the composition of Select and Reverse queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachSelectAndReverse()
{
    IEnumerable&amp;lt;string&amp;gt; deferredQuery = Enumerable.Range(1, 5)
        .SelectGenerator(int32 =&amp;gt; new string(&apos;*&apos;, int32)) // Deferred execution.
        .ReverseGenerator(); // Deferred execution.
    using (IEnumerator&amp;lt;string&amp;gt; reverseIterator = deferredQuery.GetEnumerator())
    {
        if (reverseIterator.MoveNext()) // Eager evaluation.
        {
            // Reverse query starts.
            // Select query starts.
            // Select query is calling selector with 1.
            // Select query is yielding *.
            // Select query is calling selector with 2.
            // Select query is yielding **.
            // Select query is calling selector with 3.
            // Select query is yielding ***.
            // Select query is calling selector with 4.
            // Select query is yielding ****.
            // Select query is calling selector with 5.
            // Select query is yielding *****.
            // Select query ends.
            // Reverse query evaluated all 5 value(s) in source sequence.
            // Reverse query is yielding index 4 of source sequence.
            reverseIterator.Current.WriteLine();
            while (reverseIterator.MoveNext())
            {
                // Reverse query is yielding index 3 of source sequence.
                // Reverse query is yielding index 2 of source sequence.
                // Reverse query is yielding index 1 of source sequence.
                // Reverse query is yielding index 0 of source sequence.
                reverseIterator.Current.WriteLine();
            } // Reverse query ends.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final query is a generator created by Reverse query, when foreach loop pulls the first result value, the Reverse query starts execution and pulls the all values from its source sequence, which is a generator created by Select query. So Select query starts execution too. Therefore, all its result values are yielded to the generator created by Reverse, which then yield its first result (its last source value). Then, the pulling continues. The foreach loop pulls the next result value from generator created by Reverse, which directly yields its next result value (its second last source value). This goes on, and when there is no result value to pull, the query execution ends.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (3) Generator</title><link>https://dixin.github.io/posts/linq-to-objects-generator-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-generator-7/</guid><description>After understanding how to use LINQ to Objects, starting from this part, the implementation of query methods is discussed. Most LINQ to Object query methods are implemented with iteration pattern and</description><pubDate>Thu, 05 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-generator&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-generator&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;After understanding how to use LINQ to Objects, starting from this part, the implementation of query methods is discussed. Most LINQ to Object query methods are implemented with iteration pattern and generators.&lt;/p&gt;
&lt;h2&gt;Implement iterator pattern&lt;/h2&gt;
&lt;p&gt;The iterator pattern can decouple data can algorithm, where the sequence (also called container of items, or aggregate of elements) encapsulates the data to iterate, and the iterator encapsulates the algorithms of iterating the data, and return each value to the caller. As fore mentioned, iterator is imperative and stateful. The following is a general purpose iterator implemented as an &lt;a href=&quot;https://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;finite-state machine&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum IteratorState
{
    Create = -2,
    Start = 0,
    MoveNext = 1,
    End = -1,
    Error = -3
}

public class Iterator&amp;lt;T&amp;gt; : IEnumerator&amp;lt;T&amp;gt;
{
    private readonly Action start;

    private readonly Func&amp;lt;bool&amp;gt; moveNext;

    private readonly Func&amp;lt;T&amp;gt; getCurrent;

    private readonly Action dispose;

    private readonly Action end;

    public Iterator(
        Action start = null,
        Func&amp;lt;bool&amp;gt; moveNext = null,
        Func&amp;lt;T&amp;gt; getCurrent = null,
        Action dispose = null,
        Action end = null)
    {
        this.start = start;
        this.moveNext = moveNext;
        this.getCurrent = getCurrent;
        this.dispose = dispose;
        this.end = end;
    }

    public T Current { get; private set; }

    object IEnumerator.Current =&amp;gt; this.Current;

    internal IteratorState State { get; private set; } = IteratorState.Create; // IteratorState: Create.

    internal Iterator&amp;lt;T&amp;gt; Start()
    {
        this.State = IteratorState.Start;  // IteratorState: Create =&amp;gt; Start.
        return this;
    }

    public bool MoveNext()
    {
        try
        {
            switch (this.State)
            {
                case IteratorState.Start:
                    this.start?.Invoke();
                    this.State = IteratorState.MoveNext; // IteratorState: Start =&amp;gt; MoveNext.
                    goto case IteratorState.MoveNext;
                case IteratorState.MoveNext:
                    if (this.moveNext?.Invoke() ?? false)
                    {
                        this.Current = this.getCurrent != null ? this.getCurrent() : default;
                        return true; // IteratorState: MoveNext =&amp;gt; MoveNext.
                    }
                    this.State = IteratorState.End; // IteratorState: MoveNext =&amp;gt; End.
                    this.dispose?.Invoke();
                    this.end?.Invoke();
                    break;
            }
            return false;
        }
        catch
        {
            this.State = IteratorState.Error; // IteratorState: Start, MoveNext, End =&amp;gt; Error.
            this.Dispose();
            throw;
        }
    }

    public void Dispose()
    {
        if (this.State == IteratorState.Error || this.State == IteratorState.MoveNext)
        {
            try { }
            finally
            {
                // Unexecuted finally blocks are executed before the thread is aborted.
                this.State = IteratorState.End; // IteratorState: Error =&amp;gt; End.
                this.dispose?.Invoke();
            }
        }
    }

    public void Reset() =&amp;gt; throw new NotSupportedException();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is a general purpose sequence implementation as above iterator’s factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Sequence&amp;lt;T, TData&amp;gt; : IEnumerable&amp;lt;T&amp;gt;
{
    private readonly TData data;

    private readonly Func&amp;lt;TData, Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory;

    public Sequence(TData data, Func&amp;lt;TData, Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory)
    {
        this.data = data;
        this.iteratorFactory = iteratorFactory;
    }

    public IEnumerator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt;
        this.iteratorFactory(this.data).Start(); // IteratorState: Create =&amp;gt; Start.

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above iterator encapsulates traversal algorithm represented by 5 functions: start, moveNext, getCurrent, end, dispose, and manages 5 states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create: if a iterator is constructed on the fly, its initial state is Create.&lt;/li&gt;
&lt;li&gt;Start: if an iterator is created by sequence’s factory method, its state is Start. Later, if its MoveNext is called for the first time, the start function is called to do the initialization work. Then, the state changes to MoveNext&lt;/li&gt;
&lt;li&gt;MoveNext: After its MoveNext method being called for the first time, its state is MoveNext. Each time its MoveNext method is called, the moveNext function is called to return a bool value
&lt;ul&gt;
&lt;li&gt;If true is returned, there is a value available, and getCurrent function can be called through its Current property to pull that value; The state remains MoveNext.&lt;/li&gt;
&lt;li&gt;If false, there is no value available to pull from its Current property. The state changes to End, and the dispose function is called to release resources, then end functions is called to do the cleanup work;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;End: if its MoveNext method is called and the state is End, false is directly returned to indicate caller that the sequential traversal ended, there is no value available to pull.&lt;/li&gt;
&lt;li&gt;Error: if its MoveNext method throws an exception, the state changes to Error. Then its Dispose method is called to do the cleanup work, and eventually its state is changed to End.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/LINQ-to-Objects-3-Generator_891E/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/LINQ-to-Objects-3-Generator_891E/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The above sequence encapsulates the data to generate the values from, and also provides the iterator factory method. When its GetEnumerator method is called, an iterator is created with state changes from Create to Start.&lt;/p&gt;
&lt;h2&gt;Generate sequence and iterator&lt;/h2&gt;
&lt;p&gt;Now the Sequence&amp;lt;T&amp;gt; and Iterator&amp;lt;T&amp;gt; types can be used to create sequence with specific data and specific iteration algorithm. A simple example is to create a singleton sequence with only 1 value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class IteratorPattern
{
    internal static IEnumerable&amp;lt;TSource&amp;gt; FromValue&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt;
        new Sequence&amp;lt;TSource, bool&amp;gt;(
            data: false, // bool isValueIterated = false;
            iteratorFactory: isValueIterated =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
                moveNext: () =&amp;gt;
                    {
                        while (!isValueIterated)
                        {
                            isValueIterated = true;
                            return true;
                        }
                        return false;
                    },
                getCurrent: () =&amp;gt; value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a bool flag is used to indicate if the value is already iterated. The iterator’s moveNext function checks that bool flag and updates it, so that the value is made available only once. The created sequence can be consumed by foreach loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEachFromValue&amp;lt;TSource&amp;gt;(TSource value)
{
    foreach (TSource result in FromValue(value)) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, foreach loop is compiled to while loop. The following code demonstrates the underlying imperative control flow of iteration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEachFromValue&amp;lt;TSource&amp;gt;(TSource value)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = FromValue(value).GetEnumerator())
    {
        // bool isValueIterated = false;
        while (iterator.MoveNext()) // moveNext: while (!isValueIterated)
        {
            // moveNext: isValueIterated = true;
            TSource result = iterator.Current; // getCurrent: TSource result = value;
        }
    }

    // Virtual control flow when iterating the returned sequence:
    // bool isValueIterated = false;
    // try
    // {
    //    while (!isValueIterated)
    //    {
    //        isValueIterated = true;
    //        TSource result = value;
    //    }
    // }
    // finally { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is to create a sequence by repeating a specified value for specified times, which is the Repeat query method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; Repeat&amp;lt;TSource&amp;gt;(TSource value, int count) =&amp;gt; 
    new Sequence&amp;lt;TSource, int&amp;gt;(
        data: 0, // int index = 0;
        iteratorFactory: index =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
            moveNext: () =&amp;gt; index++ &amp;lt; count,
            getCurrent: () =&amp;gt; value));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the sequence created by Repeat can be consumed by foreach loop, which can be desugared to while loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEachRepeat&amp;lt;TSource&amp;gt;(TSource value, int count)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = Repeat(value, count).GetEnumerator())
    {
        // int index = 0;
        while (iterator.MoveNext()) // moveNext: while (index++ &amp;lt; count)
        {
            TSource result = iterator.Current; // getCurrent: TSource result = value;
        }
    }

    // Virtual control flow when iterating the returned sequence:
    // int index = 0;
    // try
    // {
    //    while (index++ &amp;lt; count)
    //    {
    //        TSource result = value; 
    //    }
    // }
    // finally { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example creates a new sequence from another source sequence, by mapping each value to another result with a selector function, which is the Select query method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
        new Sequence&amp;lt;TResult, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TResult&amp;gt;(
                start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
                moveNext: () =&amp;gt; sourceIterator.MoveNext(),
                getCurrent: () =&amp;gt; selector(sourceIterator.Current),
                dispose: () =&amp;gt; sourceIterator?.Dispose()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the sequence created by Select can be consumed by foreach loop, which can be desugared to while loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEachSelect&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    using (IEnumerator&amp;lt;TResult&amp;gt; iterator = Select(source, selector).GetEnumerator())
    {
        // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
        // start: sourceIterator = source.GetEnumerator();
        while (iterator.MoveNext()) // moveNext: while (sourceIterator.MoveNext())
        {
            TResult result = iterator.Current; // getCurrent: TResult result = selector(sourceIterator.Current);
        }
    } // dispose: sourceIterator?.Dispose();

    // Virtual control flow when iterating the returned sequence:
    // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    // try
    // {
    //    sourceIterator = source.GetEnumerator();
    //    while (sourceIterator.MoveNext())
    //    {
    //        TResult result = selector(sourceIterator.Current);
    //    }
    // }
    // finally
    // {
    //    sourceIterator?.Dispose();
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here iterator’s start function retrieves source sequence’s iterator, and moveNext function use that source iterator to determine whether there is a next value from the source sequence. If yes, getCurrent function calls selector function to map each source value to a result value.&lt;/p&gt;
&lt;p&gt;The last example is to create a sequence by filtering another source sequence with a predicate function, which is the Where query method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate) =&amp;gt;
        new Sequence&amp;lt;TSource, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
                start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
                moveNext: () =&amp;gt;
                {
                    while (sourceIterator.MoveNext())
                    {
                        if (predicate(sourceIterator.Current))
                        {
                            return true;
                        }
                    }
                    return false;
                },
                getCurrent: () =&amp;gt; sourceIterator.Current,
                dispose: () =&amp;gt; sourceIterator?.Dispose()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, the sequence created by Where can be consumed by foreach loop, which can be desugared to while loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEachWhere&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    using (IEnumerator&amp;lt;TSource&amp;gt; iterator = Where(source, predicate).GetEnumerator())
    { // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
        // start: sourceIterator = source.GetEnumerator();
        while (iterator.MoveNext()) // moveNext: while (sourceIterator.MoveNext())
        { // moveNext: if (predicate(sourceIterator.Current))
            TSource result = iterator.Current; // getCurrent: TResult result = sourceIterator.Current;
        }
    } // dispose: sourceIterator?.Dispose();

    // Virtual control flow when iterating the returned sequence:
    // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    // try
    // {
    //    sourceIterator = source.GetEnumerator();
    //    while (sourceIterator.MoveNext())
    //    {
    //        if (predicate(sourceIterator.Current))
    //        {
    //            TResult result = selector(sourceIterator.Current);
    //        }
    //    }
    // }
    // finally
    // {
    //    sourceIterator?.Dispose();
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As demonstrated, following the iterator pattern, it is not that straightforward to create sequences and iterators from scratch. To simplify the work, C# provides a yield keyword.&lt;/p&gt;
&lt;h2&gt;Yield statement and generator&lt;/h2&gt;
&lt;p&gt;C# 2.0 introduces the yield keyword to simplify the creation of sequence and iterator. The following example create an sequence equivalent to above FromValue method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; FromValueGenerator&amp;lt;TSource&amp;gt;(TSource value)
{
    // Virtual control flow when iterating the returned sequence:
    // bool isValueIterated = false;
    // try
    // {
    //    while (!isValueIterated)
    //    {
    //        isValueIterated = true;
    //        TSource result = value;
    //    }
    // }
    // finally { }

    bool isValueIterated = false;
    try
    {
        while (!isValueIterated) // moveNext.
        {
            isValueIterated = true; // moveNext.
            yield return value; // getCurrent.
        }
    }
    finally { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The start, moveNext, getCurrent, end, dispose functions are merged into a natural and intuitive control flow. Similarly, the above Repeat, Select, Where can be implemented with yield following the control flow too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatGenerator&amp;lt;TSource&amp;gt;(TSource value, int count)
{
    // Virtual control flow when iterating the returned sequence:
    // int index = 0;
    // try
    // {
    //    while (index++ &amp;lt; count)
    //    {
    //        TSource result = value; 
    //    }
    // }
    // finally { }

    int index = 0;
    try
    {
        while (index++ &amp;lt; count) // moveNext.
        {
            yield return value; // getCurrent.
        }
    }
    finally { }
}

internal static IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    // Virtual control flow when iterating the returned sequence:
    // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    // try
    // {
    //    sourceIterator = source.GetEnumerator();
    //    while (sourceIterator.MoveNext())
    //    {
    //        TResult result = selector(sourceIterator.Current);
    //    }
    // }
    // finally
    // {
    //    sourceIterator?.Dispose();
    // }

    IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    try
    {
        sourceIterator = source.GetEnumerator(); // start.
        while (sourceIterator.MoveNext()) // moveNext.
        {
            yield return selector(sourceIterator.Current); // getCurrent.
        }
    }
    finally
    {
        sourceIterator?.Dispose(); // dispose.
    }
}

internal static IEnumerable&amp;lt;TSource&amp;gt; WhereGenerator&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    // Virtual control flow when iterating the returned sequence:
    // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    // try
    // {
    //    sourceIterator = source.GetEnumerator();
    //    while (sourceIterator.MoveNext())
    //    {
    //        if (predicate(sourceIterator.Current))
    //        {
    //            TResult result = selector(sourceIterator.Current);
    //        }
    //    }
    // }
    // finally
    // {
    //    sourceIterator?.Dispose();
    // }

    IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    try
    {
        sourceIterator = source.GetEnumerator(); // start.
        while (sourceIterator.MoveNext()) // moveNext.
        {
            if (predicate(sourceIterator.Current)) // moveNext.
            {
                yield return sourceIterator.Current; // getCurrent.
            }
        }
    }
    finally
    {
        sourceIterator?.Dispose(); // dispose.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So yield statement simplified the implementation of iterator pattern, it enables describing the algorithm that how the values are iterated (yielded), without explicitly creating a sequence or iterator. Actually, above control flow can be further simplified. In FromValueGenerator, the bool state is unnecessary. All needed is to yield a single value to the caller. So FromValueGenerator is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; FromValueGenerator&amp;lt;TSource&amp;gt;(TSource value)
{
    yield return value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In RepeatGenerator, the while loop can be replaced by a for loop to improve the readability a little bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; RepeatGenerator&amp;lt;TSource&amp;gt;(TSource value, int count)
{
    for (int index = 0; index &amp;lt; count; index++)
    {
        yield return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In SelectGenerator and WhereGenerator, the using statement and while loop can be replaced by the foreach syntactic sugar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; SelectGenerator&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    foreach (TSource value in source)
    {
        yield return selector(value);
    }
}

internal static IEnumerable&amp;lt;TSource&amp;gt; WhereGenerator&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            yield return value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# compiler actually goes a little further when compiling function with yield syntactic sugar. Such a function with yield statement must return either sequence (represented by IEnumerable or IEnumerable&amp;lt;T&amp;gt;) or iterator (represented by IEnumerator or IEnumerator&amp;lt;T&amp;gt;). When such function returns IEnumerable&amp;lt;T&amp;gt; sequence, the entire function body is compiled to &lt;a href=&quot;https://en.wikipedia.org/wiki/Generator_(computer_programming)&quot;&gt;generator&lt;/a&gt; creation. A generator is both a sequence and a iterator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IGenerator&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerator&amp;lt;T&amp;gt; { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With above sequence and iterator definition, a general purpose generator can be implemented easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Generator&amp;lt;T, TData&amp;gt; : IGenerator&amp;lt;T&amp;gt;
{
    private readonly int initialThreadId = Environment.CurrentManagedThreadId;

    private readonly TData data;

    private readonly Func&amp;lt;TData, Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory;

    private readonly Iterator&amp;lt;T&amp;gt; initialIterator;

    public Generator(TData data, Func&amp;lt;TData, Iterator&amp;lt;T&amp;gt;&amp;gt; iteratorFactory)
    {
        this.data = data;
        this.iteratorFactory = iteratorFactory;
        this.initialIterator = iteratorFactory(data);
    }

    public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()
    {
        if (this.initialThreadId == Environment.CurrentManagedThreadId
            &amp;amp;&amp;amp; this.initialIterator.State == IteratorState.Create)
        {
            // When called by the same initial thread and iteration is not started, reuse self with initial iterator.
            this.initialIterator.Start();
            return this;
        }
        // If the iteration is already started, or the iteration is requested from a different thread, create new generator with new iterator.
        Generator&amp;lt;T, TData&amp;gt; generator = new Generator&amp;lt;T, TData&amp;gt;(this.data, this.iteratorFactory);
        generator.initialIterator.Start();
        return generator;
    }

    IEnumerator IEnumerable.GetEnumerator() =&amp;gt; this.GetEnumerator();

    public void Dispose() =&amp;gt; this.initialIterator.Dispose();

    public bool MoveNext() =&amp;gt; this.initialIterator.MoveNext();

    public void Reset() =&amp;gt; this.initialIterator.Reset();

    public T Current =&amp;gt; this.initialIterator.Current;

    object IEnumerator.Current =&amp;gt; this.Current;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above FromValueGenerator, RepeatGenerator, SelectGenerator, WhereGenerator methods return IEnumerable&amp;lt;T&amp;gt; sequence, their compilation are equivalent to the following methods, where sequence creation is replaced by generator creation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledFromValueGenerator&amp;lt;TSource&amp;gt;(TSource value) =&amp;gt;
    new Generator&amp;lt;TSource, bool&amp;gt;(
        data: false, // bool isValueIterated = false;
        iteratorFactory: isValueIterated =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
            moveNext: () =&amp;gt;
            {
                while (!isValueIterated)
                {
                    isValueIterated = true;
                    return true;
                }
                return false;
            },
            getCurrent: () =&amp;gt; value));

internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledRepeatGenerator&amp;lt;TSource&amp;gt;(TSource value, int count) =&amp;gt;
    new Generator&amp;lt;TSource, int&amp;gt;(
        data: 0, // int index = 0;
        iteratorFactory: index =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
            moveNext: () =&amp;gt; index++ &amp;lt; count,
            getCurrent: () =&amp;gt; value));

internal static IEnumerable&amp;lt;TResult&amp;gt; CompiledSelectGenerator&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt;
        new Generator&amp;lt;TResult, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TResult&amp;gt;(
                start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
                moveNext: () =&amp;gt; sourceIterator.MoveNext(),
                getCurrent: () =&amp;gt; selector(sourceIterator.Current),
                dispose: () =&amp;gt; sourceIterator?.Dispose()));

internal static IEnumerable&amp;lt;TSource&amp;gt; CompiledWhereGenerator&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate) =&amp;gt;
        new Generator&amp;lt;TSource, IEnumerator&amp;lt;TSource&amp;gt;&amp;gt;(
            data: null, // IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
            iteratorFactory: sourceIterator =&amp;gt; new Iterator&amp;lt;TSource&amp;gt;(
                start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
                moveNext: () =&amp;gt;
                {
                    while (sourceIterator.MoveNext())
                    {
                        if (predicate(sourceIterator.Current))
                        {
                            return true;
                        }
                    }
                    return false;
                },
                getCurrent: () =&amp;gt; sourceIterator.Current,
                dispose: () =&amp;gt; sourceIterator?.Dispose()));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods can also return IEnumerator&amp;lt;T&amp;gt; iterator instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerator&amp;lt;TSource&amp;gt; FromValueIterator&amp;lt;TSource&amp;gt;(TSource value)
{
    yield return value;
}

internal static IEnumerator&amp;lt;TSource&amp;gt; RepeatIterator&amp;lt;TSource&amp;gt;(TSource value, int count)
{
    for (int index = 0; index &amp;lt; count; index++)
    {
        yield return value;
    }
}

internal static IEnumerator&amp;lt;TResult&amp;gt; SelectIterator&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    foreach (TSource value in source)
    {
        yield return selector(value);
    }
}

internal static IEnumerator&amp;lt;TSource&amp;gt; WhereIterator&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource value in source)
    {
        if (predicate(value))
        {
            yield return value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the above methods are compiled to iterator creation, which are equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerator&amp;lt;TSource&amp;gt; CompiledFromValueIterator&amp;lt;TSource&amp;gt;(TSource value)
{
    bool isValueIterated = false;
    return new Iterator&amp;lt;TSource&amp;gt;(
        moveNext: () =&amp;gt;
        {
            while (!isValueIterated)
            {
                isValueIterated = true;
                return true;
            }
            return false;
        },
        getCurrent: () =&amp;gt; value).Start();
}

internal static IEnumerator&amp;lt;TSource&amp;gt; CompiledRepeatIterator&amp;lt;TSource&amp;gt;(TSource value, int count)
{
    int index = 0;
    return new Iterator&amp;lt;TSource&amp;gt;(
        moveNext: () =&amp;gt; index++ &amp;lt; count,
        getCurrent: () =&amp;gt; value).Start();
}

internal static IEnumerator&amp;lt;TResult&amp;gt; CompiledSelectIterator&amp;lt;TSource, TResult&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector)
{
    IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    return new Iterator&amp;lt;TResult&amp;gt;(
        start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
        moveNext: () =&amp;gt; sourceIterator.MoveNext(),
        getCurrent: () =&amp;gt; selector(sourceIterator.Current),
        dispose: () =&amp;gt; sourceIterator?.Dispose()).Start();
}

internal static IEnumerator&amp;lt;TSource&amp;gt; CompiledWhereIterator&amp;lt;TSource&amp;gt;(
    IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    IEnumerator&amp;lt;TSource&amp;gt; sourceIterator = null;
    return new Iterator&amp;lt;TSource&amp;gt;(
        start: () =&amp;gt; sourceIterator = source.GetEnumerator(),
        moveNext: () =&amp;gt;
        {
            while (sourceIterator.MoveNext())
            {
                if (predicate(sourceIterator.Current))
                {
                    return true;
                }
            }
            return false;
        },
        getCurrent: () =&amp;gt; sourceIterator.Current,
        dispose: () =&amp;gt; sourceIterator?.Dispose()).Start();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Iterator and generator in other languages&lt;/h2&gt;
&lt;p&gt;Other languages also have similar design for iterator pattern and generator. The following table compares similar APIs/language features of C#, F#, &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-Foldable.html&quot;&gt;Haskell&lt;/a&gt; and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn858237.aspx&quot;&gt;JavaScript&lt;/a&gt; (&lt;a href=&quot;http://www.ecma-international.org/ecma-262/6.0/#sec-iteration&quot;&gt;ECMAScript 2015, 6th&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;692&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;F#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;Haskell&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;JavaScript&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Sequence/Container&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;IEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;seq&amp;lt;&apos;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;Foldable t&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;Iterable protocol&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Get iterator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;GetEnumerator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;GetEnumerator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;Symbol.iterator&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Iterator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;IEnumerator&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;IEnumerator&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;iterator protocol&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Has next value&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;MoveNext&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;MoveNext&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;next().done&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Get value&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;Current&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;Current&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;next().value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Iteration&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;foeach…in&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;for…in&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;for_, traverse_, forM_, mapM_&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;for…of&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Generator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;yield return&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;yield&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;yield&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;158&quot;&amp;gt;Merge&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;137&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;130&quot;&amp;gt;yield!&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;125&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;yield*&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;As fore mentioned, iterator pattern involves an iterator with mutable states, so it is more suitable for OOP languages, like C#. F# is a functional language but impure, so it gets along with mutable states, and has all the facilities for iterator and generator. In contrast, Haskell is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Purely_functional&quot;&gt;purely functional&lt;/a&gt; language, and does not support mutable states. Haskell just has a few APIs that might look similar to C#’s foreach. For example, In &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-Foldable.html&quot;&gt;Data.Foldable module&lt;/a&gt;, there are a few iteration functions for Foldable type class:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Applicative functions for_ and traverse_: map each element of a Foldable to an function, evaluate and ignore the results.&lt;/li&gt;
&lt;li&gt;Monadic functions: forM_ and mapM_: map each element of a Foldable to a monadic function, evaluate and ignore the results.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Haskell list is &lt;a href=&quot;https://hackage.haskell.org/package/base-4.8.1.0/docs/src/Data.Foldable.html#line-225&quot;&gt;an instance of Foldable type class&lt;/a&gt;, its design and implementation is different from iterator pattern. For iterator in functional programming, please see this paper: &lt;a href=&quot;http://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf&quot;&gt;The Essence of the Iterator Pattern&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (2) Query Methods (Operators) and Query Expressions</title><link>https://dixin.github.io/posts/linq-to-objects-query-methods-operators-and-query-expressions-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-query-methods-operators-and-query-expressions-7/</guid><description>This part discusses the usages of built-in LINQ to Objects query methods and query expressions. As fore mentioned, these query methods (also called [standard query operators](http://msdn.microsoft.com</description><pubDate>Tue, 03 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-query-methods-operators-and-query-expressions&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-query-methods-operators-and-query-expressions&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This part discusses the usages of built-in LINQ to Objects query methods and query expressions. As fore mentioned, these query methods (also called &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb397896.aspx&quot;&gt;standard query operators&lt;/a&gt;) are provided in System.Linq.Enumerable type, most of which are IEnumerable&amp;lt;T&amp;gt; extension methods. They can be categorized by return type:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sequence queries: return a new IEnumerable&amp;lt;T&amp;gt; sequence:
&lt;ul&gt;
&lt;li&gt;Generation: Empty , Range, Repeat, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where*, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select*, SelectMany*&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy*&lt;/li&gt;
&lt;li&gt;Join: SelectMany, Join*, GroupJoin*&lt;/li&gt;
&lt;li&gt;Concatenation: Concat, Append, Prepend&lt;/li&gt;
&lt;li&gt;Set: Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: Zip&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy*, ThenBy*, OrderByDescending*, ThenByDescending*, Reverse*&lt;/li&gt;
&lt;li&gt;Conversion: Cast*, AsEnumerable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection queries: return a new collection:
&lt;ul&gt;
&lt;li&gt;Conversion: ToArray, ToList, ToDictionary, ToLookup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value queries: return a single value:
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, Last, LastOrDefault, ElementAt, ElementAtOrDefault, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These LINQ query methods are very functional. They are functions that can be composed by fluent chaining. Many of them are higher-order functions accepting function parameters, so that anonymous functions (lambda expressions) or named functions can be passed to them. The query methods returning IEnumerable&amp;lt;T&amp;gt; are pure functions. They are referential transparency and side effect free. When they are called, they only create and return a new sequence wrapping the input sequence and the query logic, with the query logic not executed, so there is no state changes, data mutation, I/O, etc. The query logic execution is deferred until the result values are pulled from the returned sequence. The other query methods (returning a new collection or a single value) are impure functions. When they are called, they immediately evaluate the values of the input source sequence, and execute the query logic.&lt;/p&gt;
&lt;p&gt;As discussed in the Functional Programming chapter, The query methods marked with * are supported with query expressions syntax.&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;577&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Query expression&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Query method&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;single from clause with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;multiple from clauses with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;SelectMany&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Type in from/join clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Cast&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause without into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause with into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;GroupJoin&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;let clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;where clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Where&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with or without ascending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;OrderBy, ThenBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;OrderByDescending, ThenByDescending&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;group clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;into with continuation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;278&quot;&amp;gt;Nested query&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;Sequence queries&lt;/h2&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;Enumerable type’s Empty , Range, Repeat methods can generate an IEnumerable&amp;lt;T&amp;gt; sequence. They are just normal static methods instead of extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TResult&amp;gt; Empty&amp;lt;TResult&amp;gt;();

        public static IEnumerable&amp;lt;int&amp;gt; Range(int start, int count);

        public static IEnumerable&amp;lt;TResult&amp;gt; Repeat&amp;lt;TResult&amp;gt;(TResult element, int count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Empty just generates an IEnumerable&amp;lt;T&amp;gt; sequence, which contains no value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
{
    internal static void Empty()
    {
        IEnumerable&amp;lt;string&amp;gt; empty = Enumerable.Empty&amp;lt;string&amp;gt;(); // Define query.
        int count = 0;
        foreach (string result in empty) // Execute query by pulling the results.
        {
            count++; // Not executed.
        }
        count.WriteLine(); // 0
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Range generates an int sequence with the specified initial int value and range:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Range()
{
    IEnumerable&amp;lt;int&amp;gt; range = Enumerable.Range(-1, 5); // Define query.
    range.WriteLines(); // Execute query. -1 0 1 2 3
    // Equivalent to:
    // foreach (int int32 in range)
    // {
    //    int32.WriteLine();
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example creates a sequence with large number of int values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxRange()
{
    IEnumerable&amp;lt;int&amp;gt; range = Enumerable.Range(1, int.MaxValue); // Define query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As just mentioned, calling above MaxRange just defines a query. A large sequence is created, but each actual value in the large sequence is not generated.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Repeat()
{
    IEnumerable&amp;lt;string&amp;gt; repeat = Enumerable.Repeat(&quot;*&quot;, 5); // Define query.
    repeat.WriteLines(); // Execute query. * * * * *
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DefaultIfEmpty generates a sequence based on the source sequence. If the source sequence is not empty, the returned sequence contains the same values from the source sequence. If the source sequence is empty, the returned sequence contains a single value, which is the default value of TSource type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload of DefaultIfEmpty allows to specify what default value to use if the source sequence is empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; DefaultIfEmpty&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, TSource defaultValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmpty()
{
    IEnumerable&amp;lt;int&amp;gt; souce = Enumerable.Empty&amp;lt;int&amp;gt;();
    IEnumerable&amp;lt;int&amp;gt; singletonIfEmpty = souce.DefaultIfEmpty(); // Define query.
    singletonIfEmpty.WriteLines(); // Execute query: 0
}

internal static void DefaultIfEmptyWithDefaultValue()
{
    IEnumerable&amp;lt;int&amp;gt; souce = Enumerable.Empty&amp;lt;int&amp;gt;();
    IEnumerable&amp;lt;int&amp;gt; singletonIfEmpty = souce.DefaultIfEmpty(1);
    singletonIfEmpty.WriteLines(); // Execute query. 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DefaultIfEmpty is also commonly used in left outer join, which will be discussed later.&lt;/p&gt;
&lt;h3&gt;Filtering (restriction)&lt;/h3&gt;
&lt;p&gt;As demonstrated earlier, Where filters the values in the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other predicate parameter is a callback function. When the query is executed, predicate is called with each value in the source sequence, and return a bool value. If true is returned, this value is in the query result sequence; if false is returned, this value is filtered out. For example, the following query filters all types in .NET core library to get all primitive type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static readonly Assembly CoreLibrary = typeof(object).Assembly;

internal static void Where()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;Type&amp;gt; primitives = source.Where(type =&amp;gt; type.IsPrimitive); // Define query.
    primitives.WriteLines(); // Execute query. System.Boolean System.Byte System.Char System.Double ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the equivalent query expression has a where clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Where()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;Type&amp;gt; primitives = from type in source
                                   where type.IsPrimitive
                                   select type;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload of Where has a indexed predicate function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here each time predicate is called with 2 parameters, the current value in source sequence, and the current value’s index in source sequence. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithIndex()
{
    IEnumerable&amp;lt;string&amp;gt; source = new string[] { &quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot; };
    IEnumerable&amp;lt;string&amp;gt; even = source.Where((value, index) =&amp;gt; index % 2 == 0); // Define query.
    even.WriteLines(); // Execute query. zero two four
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The indexed Where overload is not supported in query expression syntax.&lt;/p&gt;
&lt;p&gt;The other filtering query method is OfType. It filters values by type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OfType()
{
    IEnumerable&amp;lt;object&amp;gt; source = new object[] { 1, 2, &apos;a&apos;, &apos;b&apos;, &quot;aa&quot;, &quot;bb&quot;, new object() };
    IEnumerable&amp;lt;string&amp;gt; strings = source.OfType&amp;lt;string&amp;gt;();  // Define query.
    strings.WriteLines(); // Execute query. aa bb
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OfType is not supported in query expression either.&lt;/p&gt;
&lt;h3&gt;Mapping (projection)&lt;/h3&gt;
&lt;p&gt;Similar to Where, Select has 2 overloads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the query is executed, the selector function is called with each TSource value, and map it to a TResult result in the returned sequence. And in the indexed overload, selector is also called with TSource value’s index. For example, the following Select query maps each integer to a formatted string representing the integer’s square root:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Select()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;string&amp;gt; squareRoots = source.Select(int32 =&amp;gt; $&quot;{Math.Sqrt(int32):0.00}&quot;); // Define query.
    squareRoots.WriteLines(); // Execute query. 0.00 1.00 1.41 1.73 2.00
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The equivalent query expression is a select clause with a single from clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Select()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;string&amp;gt; squareRoots = from int32 in source
                                      select $&quot;{Math.Sqrt(int32):0.00}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Query expression must end with either a select clause, or group clause (will be discussed below). If there are other clauses between the starting from clause and the ending select clause, and the ending select clause simply has the value from the source sequencce, then that ending select clause is ignored and is not compiled to a Select query method call. Above where query expression is such an example.&lt;/p&gt;
&lt;p&gt;The following is an example of the indexed overload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;string&amp;gt; Words() =&amp;gt; new string[] { &quot;Zero&quot;, &quot;one&quot;, &quot;Two&quot;, &quot;three&quot;, &quot;four&quot; };

[SuppressMessage(&quot;Microsoft.Globalization&quot;, &quot;CA1308:NormalizeStringsToUppercase&quot;)]
internal static void SelectWithIndex()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    var mapped = source.Select((value, index) =&amp;gt; new
    {
        Index = index,
        Word = value.ToLowerInvariant()
    }); // Define query: IEnumerable&amp;lt;(string Word, int Index)&amp;gt;
    mapped.WriteLines(result =&amp;gt; $&quot;{result.Index}:{result.Word}&quot;); // Execute query. 
    // 0:zero 1:one 2:two 3:three 4:four
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here selector returns anonymous type. As a result, Select returns a sequence of anonymous type, and var has to be used.&lt;/p&gt;
&lt;p&gt;As discussed in the Functional Programming chapter, let clause is also compiled to Select query with a selector function returning anonymous type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Let()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(-2, 5);
    IEnumerable&amp;lt;string&amp;gt; absoluteValues = from int32 in source
                                         let abs = Math.Abs(int32)
                                         where abs &amp;gt; 0
                                         select $&quot;Math.Abs({int32}) == {abs}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiled Select query returns a (int int32, int abs) anonymous type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLet()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(-2, 5);
    IEnumerable&amp;lt;string&amp;gt; absoluteValues = source
        .Select(int32 =&amp;gt; new { int32 = int32, abs = Math.Abs(int32) })
        .Where(anonymous =&amp;gt; anonymous.abs &amp;gt; 0)
        .Select(anonymous =&amp;gt; $&quot;Math.Abs({anonymous.int32}):{anonymous.abs}&quot;); // Define query.
    absoluteValues.WriteLines(); // Execute query.
    // Math.Abs(-2):2 Math.Abs(-1):1 Math.Abs(1):1 Math.Abs(2):2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SelectMany has 4 overloads. Similar to Where and Select, the following 2 overloads accept unindexed and indexed selector:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);

public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, IEnumerable&amp;lt;TResult&amp;gt;&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast with Select, SelectMany’s selector is a one to many mapping. If there are N values from the source sequence, then they are mapped to N sequences. And eventually, SelectMany concatenates these N sequences into one single sequence. The following example calls SelectMany to query all members of all types in .NET core library, then filter the obsolete members (members with [Obsolete]):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static MemberInfo[] GetDeclaredMembers(this Type type) =&amp;gt;
    type.GetMembers(
        BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

internal static bool IsObsolete(this MemberInfo member) =&amp;gt;
    member.IsDefined(attributeType: typeof(ObsoleteAttribute), inherit: false);

internal static void SelectMany()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;MemberInfo&amp;gt; oneToManymapped = source.SelectMany(type =&amp;gt; type.GetDeclaredMembers()); // Define query.
    IEnumerable&amp;lt;MemberInfo&amp;gt; filtered = oneToManymapped.Where(member =&amp;gt; member.IsObsolete()); // Define query.
    filtered.WriteLines(obsoleteMember =&amp;gt; $&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;); // Execute query.
    // Equivalent to:
    // foreach (MemberInfo obsoleteMember in filtered)
    // {
    //    Trace.WriteLine($&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;);
    // }
    // ...
    // System.Enum:System.String ToString(System.String, System.IFormatProvider)
    // System.Enum:System.String ToString(System.IFormatProvider)
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, the above SelectMany, Where, and are both extension methods for IEnumerable&amp;lt;T&amp;gt;, and they both return IEnumerable&amp;lt;T&amp;gt;, so that above LINQ query can be fluent, as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FluentSelectMany()
{
    IEnumerable&amp;lt;MemberInfo&amp;gt; mappedAndFiltered = CoreLibrary
        .GetExportedTypes()
        .SelectMany(type =&amp;gt; type.GetDeclaredMembers())
        .Where(member =&amp;gt; member.IsObsolete()); // Define query.
    mappedAndFiltered.WriteLines(obsoleteMember =&amp;gt; $&quot;{obsoleteMember.DeclaringType}:{obsoleteMember}&quot;); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the equivalent query expression has 2 from clauses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectMany()
{
    IEnumerable&amp;lt;MemberInfo&amp;gt; mappedAndFiltered =
        from type in CoreLibrary.GetExportedTypes()
        from member in type.GetPublicDeclaredMembers()
        where member.IsObsolete()
        select member;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, SelectMany can flatten a hierarchical 2-level-sequence into a flat 1-level-sequence. In these examples, the source sequence is hierarchical – it has many types, and each type can have a sequence of many members. SelectMany flattens the hierarchy, and concatenates many sequences of members into a single sequence of members.&lt;/p&gt;
&lt;p&gt;The other 2 SelectMany overloads accept 2 selector functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource,
    IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector,
    Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector);

public static IEnumerable&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSource, TCollection, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, 
    Func&amp;lt;TSource, int, IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt; collectionSelector, 
    Func&amp;lt;TSource, TCollection, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They accept 2 selector functions. The collection selector (non indexed and index) maps source sequence’s each TSource value to many TCollection values (a IEnumerable&amp;lt;TCollection&amp;gt; sequence), and the result selector maps each TCollection value and its original TSource value to a TResult value. So eventually they still return a sequence of TResult values. For example, the following example use result selector to map type and member to string representation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectManyWithResultSelector()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;string&amp;gt; obsoleteMembers = source
        .SelectMany(
            collectionSelector: type =&amp;gt; type.GetDeclaredMembers(),
            resultSelector: (type, member) =&amp;gt; new { Type = type, Member = member })
        .Where(typeAndMember =&amp;gt; typeAndMember.Member.IsObsolete())
        .Select(typeAndMember =&amp;gt; $&quot;{typeAndMember.Type}:{typeAndMember.Member}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The equivalent query expression has 2 from clauses for the SelectMany query, a where clause for Where, and 1 select query for Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectManyWithResultSelector()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;string&amp;gt; obsoleteMembers =
        from type in source
        from member in type.GetDeclaredMembers()
        where member.IsObsolete()
        select $&quot;{type}:{member}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The collection selector function returns a sequence, which can be queried too. Here the Where query logically filters the obsolete member can be equivalently applied to the collection selector, which is called a subquery:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectManyWithResultSelectorAndSubquery()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;string&amp;gt; obsoleteMembers = source.SelectMany(
        collectionSelector: type =&amp;gt; type.GetDeclaredMembers().Where(member =&amp;gt; member.IsObsolete()),
        resultSelector: (type, obsoleteMember) =&amp;gt; $&quot;{type}:{obsoleteMember}&quot;); // Define query.
    obsoleteMembers.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The equivalent query expression has a sub query expression for Where:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectManyWithResultSelectorAndSubquery()
{
    IEnumerable&amp;lt;Type&amp;gt; source = CoreLibrary.GetExportedTypes();
    IEnumerable&amp;lt;string&amp;gt; obsoleteMembers =
        from type in source
        from obsoleteMember in (from member in type.GetDeclaredMembers()
                                where member.IsObsolete()
                                select member)
        select $&quot;{type}:{obsoleteMember}&quot;; // Define query.
    obsoleteMembers.WriteLines(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SelectMany is a very powerful query method, and the multiple from clauses is also a powerful syntax to build a functional workflow. This will be discussed in the Category Theory chapter.&lt;/p&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;The GroupBy method has 8 overloads. The minimum requirement is to specified a key selector function, which is called with each value in the source sequence, and return a key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each value from he source sequence is mapped to a key by calling the keys elector. If 2 keys are equal, these 2 source values are in the same group. Take the following persons as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Person
{
    internal Person(string name, string placeOfBirth)
    {
        this.Name = name;
        this.PlaceOfBirth = placeOfBirth;
    }

    internal string Name { get; }

    internal string PlaceOfBirth { get; }
}

internal static partial class QueryMethods
{
    internal static IEnumerable&amp;lt;Person&amp;gt; Persons() =&amp;gt; new Person[]
    {
        new Person(name: &quot;Robert Downey Jr.&quot;, placeOfBirth: &quot;US&quot;),
        new Person(name:  &quot;Tom Hiddleston&quot;, placeOfBirth: &quot;UK&quot;),
        new Person(name: &quot;Chris Hemsworth&quot;, placeOfBirth: &quot;AU&quot;),
        new Person(name: &quot;Chris Evans&quot;, placeOfBirth: &quot;US&quot;),
        new Person(name: &quot;Paul Bettany&quot;, placeOfBirth:  &quot;UK&quot;)
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These Person instances represents actors of &lt;a href=&quot;https://en.wikipedia.org/wiki/Marvel_Cinematic_Universe&quot;&gt;Marvel Cinematic Universe&lt;/a&gt;. They can be simply grouped by their place of birth:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupBy()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt; groups = source.GroupBy(person =&amp;gt; person.PlaceOfBirth); // Define query.
    foreach (IGrouping&amp;lt;string, Person&amp;gt; group in groups) // Execute query.
    {
        $&quot;{group.Key}: &quot;.Write();
        foreach (Person person in group)
        {
            $&quot;{person.Name}, &quot;.Write();
        }
        Environment.NewLine.Write();
    }
    // US: Robert Downey Jr., Chris Evans,
    // UK: Tom Hiddleston, Paul Bettany,
    // AU: Chris Hemsworth,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupBy returns IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt;. The following is the definition of IGrouping&amp;lt;TKey, TElement&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IGrouping&amp;lt;out TKey, out TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        TKey Key { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is just an IEnumerable&amp;lt;T&amp;gt; sequence with an additional Key property. So, above GroupBy returns a hierarchical sequence. It is a sequence of groups, where each group is a sequence of values. The equivalent query expression is a group clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupBy()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt; groups = from person in source
                                                    group person by person.PlaceOfBirth;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupBy can also accepts a result selector function to map each group and its key to a result in the returned sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This overload, does not return of hierarchical sequence of groups, but flattened sequence of result values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithResultSelector()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; groups = source
        .GroupBy(
            keySelector: person =&amp;gt; person.PlaceOfBirth,
            resultSelector: (key, group) =&amp;gt; $&quot;{key}:{group.Count()}&quot;); // Define query.
    groups.WriteLines(); // Execute query. US:2 UK:2 AU:1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This overload is directly not supported by query expression. However, its result selector can be equivalently applied with an additional Select query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByAndSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt; groups = source.GroupBy(person =&amp;gt; person.PlaceOfBirth);
    IEnumerable&amp;lt;string&amp;gt; mapped = groups.Select(group =&amp;gt; $&quot;{group.Key}: {group.Count()}&quot;); // Define query.
    groups.WriteLines(); // Execute query. US:2 UK:2 AU:1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As just demonstrated, this GroupBy overload is equivalent to query expression with a group clause, and Select can be compiled from a select clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByAndSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, Person&amp;gt;&amp;gt; groups = from person in source
                                                    group person by person.PlaceOfBirth;
    IEnumerable&amp;lt;string&amp;gt; mapped = from @group in groups
                                 select $&quot;{@group.Key}: {@group.Count()}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here @ is prepended to the @group identifier, because group is a query keyword. By removing the groups variable, the first query expression becomes the second query expression’s subquery:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FluentGroupByAndSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; mapped = from @group in (from person in source
                                                 group person by person.PlaceOfBirth)
                                 select $&quot;{@group.Key}: {@group.Count()}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above expression is nested rather than fluent. So a into query keyword is provided for continuation like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByAndSelectWithInto()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; mapped = from person in source
                                 group person by person.PlaceOfBirth into @group
                                 select $&quot;{@group.Key}: {@group.Count()}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compilation of the above 2 query expressions are identical.&lt;/p&gt;
&lt;p&gt;GroupBy can also accept an element selector function to map each value in he source sequence in the source sequence to a result value in the group:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithElementSelector()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, string&amp;gt;&amp;gt; groups = source
        .GroupBy(
            keySelector: person =&amp;gt; person.PlaceOfBirth,
            elementSelector: person =&amp;gt; person.Name); // Define query.
    foreach (IGrouping&amp;lt;string, string&amp;gt; group in groups) // Execute query.
    {
        $&quot;{group.Key}: &quot;.Write();
        foreach (string name in group)
        {
            $&quot;{name}, &quot;.Write();
        }
        Environment.NewLine.Write();
    }
    // US: Robert Downey Jr., Chris Evans,
    // UK: Tom Hiddleston, Paul Bettany,
    // AU: Chris Hemsworth,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In query expression, the element selector can be specified after the group keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithElementSelector()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;IGrouping&amp;lt;string, string&amp;gt;&amp;gt; groups = from person in source
                                                    group person.Name by person.PlaceOfBirth;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And element selector can be used with result selector:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, result selector can flatten the hierarchical sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithElementAndResultSelector()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; groups = source.GroupBy(
        keySelector: person =&amp;gt; person.PlaceOfBirth,
        elementSelector: person =&amp;gt; person.Name,
        resultSelector: (key, group) =&amp;gt; $&quot;{key}: {string.Join(&quot;, &quot;, group)}&quot;); // Define query.
    groups.WriteLines(); // Execute query.
    // US: Robert Downey Jr., Chris Evans
    // UK: Tom Hiddleston, Paul Bettany
    // AU: Chris Hemsworth
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to SelectMany, GroupBy with both element selector and result selector is not directly supported in query expression. The result selector logic can be done with a select continuation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithElementSelectorAndSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; groups = from person in source
                                 group person.Name by person.PlaceOfBirth into @group
                                 select $&quot;{@group.Key}: {string.Join(&quot;,&quot;, @group)}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rest 4 overloads accept an IEqualityComparer&amp;lt;TKey&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TSource&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TSource&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static IEnumerable&amp;lt;TResult&amp;gt; GroupBy&amp;lt;TSource, TKey, TElement, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    Func&amp;lt;TKey, IEnumerable&amp;lt;TElement&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEqualityComparer&amp;lt;TKey&amp;gt; provides the methods to determine whether 2 keys are equal when grouping all keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IEqualityComparer&amp;lt;in T&amp;gt;
    {
        bool Equals(T x, T y);

        int GetHashCode(T obj);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithEqualityComparer()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;string&amp;gt; groups = source.GroupBy(
        keySelector: person =&amp;gt; person.PlaceOfBirth,
        elementSelector: person =&amp;gt; person.Name,
        resultSelector: (key, group) =&amp;gt; $&quot;{key}:{string.Join(&quot;,&quot;, group)}&quot;,
        comparer: StringComparer.OrdinalIgnoreCase); // Define query.
    groups.WriteLines(); // Execute query. US:2 UK: 2 AU: 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 4 overloads is not supported by query expression.&lt;/p&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;h3&gt;Inner join&lt;/h3&gt;
&lt;p&gt;Join is designed for &lt;a href=&quot;http://en.wikipedia.org/wiki/Inner_join#Inner_join&quot;&gt;inner join&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, 
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, 
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector)

IEnumerable&amp;lt;TResult&amp;gt; Join&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, 
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, 
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector, 
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each outer value from the outer source is mapped to an outer key by calling the outer key selector, and each inner value from the inner source is mapped to an inner key. When a outer key is equal to an inner key, the source outer value and the matching source inner value are paired, and mapped to a result by calling the result selector. So each outer value with a matching inner value is mapped to a result in the returned sequence, and each outer value without a matching inner value is ignored. Take the following characters as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Character
{
    internal Character(string name, string placeOfBirth, string starring)
    {
        this.Name = name;
        this.PlaceOfBirth = placeOfBirth;
        this.Starring = starring;
    }

    internal string Name { get; }

    internal string PlaceOfBirth { get; }

    internal string Starring { get; }
}

internal static partial class QueryMethods
{
    internal static IEnumerable&amp;lt;Character&amp;gt; Characters() =&amp;gt; new Character[]
    {
        new Character(name: &quot;Tony Stark&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Robert Downey Jr.&quot;),
        new Character(name: &quot;Thor&quot;, placeOfBirth: &quot;Asgard&quot;, starring: &quot;Chris Hemsworth&quot;),
        new Character(name: &quot;Steve Rogers&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Chris Evans&quot;),
        new Character(name: &quot;Vision&quot;, placeOfBirth: &quot;KR&quot;, starring: &quot;Paul Bettany&quot;),
        new Character(name: &quot;JARVIS&quot;, placeOfBirth: &quot;US&quot;, starring: &quot;Paul Bettany&quot;)
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These Character instances represents characters in the movie &lt;a href=&quot;https://en.wikipedia.org/wiki/Avengers:_Age_of_Ultron&quot;&gt;Avengers 2&lt;/a&gt;, and can be joined with actors. When a character from outer sequence matches an actor from inner sequence by &lt;a href=&quot;https://en.wikipedia.org/wiki/Avengers:_Age_of_Ultron#Cast&quot;&gt;cast&lt;/a&gt;, these 2 values are paired and mapped to the result sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoin()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin = outer.Join(
        inner: inner,
        outerKeySelector: person =&amp;gt; person.Name,
        innerKeySelector: character =&amp;gt; character.Starring,
        resultSelector: (person, character) =&amp;gt; $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;); // Define query.
    innerJoin.WriteLines(); // Execute query.
    // Robert Downey Jr. (US): Tony Stark
    // Chris Hemsworth (AU): Thor
    // Chris Evans (US): Steve Rogers
    // Paul Bettany (UK): Vision
    // Paul Bettany (UK): JARVIS
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the inner join results, the name “Tom Hiddleston” does not exist in the results, because the person with this name cannot match with any character’s starring (&lt;a href=&quot;https://en.wikipedia.org/wiki/Tom_Hiddleston&quot;&gt;Tom Hiddleston&lt;/a&gt; is the actor of &lt;a href=&quot;https://en.wikipedia.org/wiki/Loki_(comics)&quot;&gt;Loki&lt;/a&gt;, who is in &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Avengers_(2012_film)&quot;&gt;Avengers 1&lt;/a&gt; but not in Avengers 2). And the name “Paul Bettany” appears twice in the results, because the person with this name matches 2 characters’ starring (&lt;a href=&quot;https://en.wikipedia.org/wiki/Paul_Bettany&quot;&gt;Paul Bettany&lt;/a&gt; is the voice of &lt;a href=&quot;https://en.wikipedia.org/wiki/Edwin_Jarvis#J.A.R.V.I.S.&quot;&gt;JARVIS&lt;/a&gt; and the actor of &lt;a href=&quot;https://en.wikipedia.org/wiki/Vision_(Marvel_Comics)&quot;&gt;Vision&lt;/a&gt;). The equivalent query expression has a join clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoin()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin =
        from person in outer
        join character in inner on person.Name equals character.Starring
        select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, the outer value and the inner value are matched with a single key - Person.Name property and Character.Starring property. To match with multiple keys, just have both outer key selector and inner key selector return the same anonymous type with multiple properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithMultipleKeys()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin = outer.Join(
        inner: inner,
        outerKeySelector: person =&amp;gt; new { Starring = person.Name, PlaceOfBirth = person.PlaceOfBirth },
        innerKeySelector: character =&amp;gt; new { Starring = character.Starring, PlaceOfBirth = character.PlaceOfBirth },
        resultSelector: (person, character) =&amp;gt;
            $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name} ({character.PlaceOfBirth})&quot;); // Define query.
    innerJoin.WriteLines(); // Execute query.
    // Robert Downey Jr. (US): Tony Stark (US)
    // Chris Evans (US): Steve Rogers (US)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anonymous type can be also used with join clause in query expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithMultiKeys()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin =
        from person in outer
        join character in inner
            on new { Starring = person.Name, PlaceOfBirth = person.PlaceOfBirth }
            equals new { Starring = character.Starring, PlaceOfBirth = character.PlaceOfBirth }
        select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name} ({character.PlaceOfBirth})&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Left outer join&lt;/h3&gt;
&lt;p&gt;GroupJoin is designed for &lt;a href=&quot;https://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join&quot;&gt;left outer join&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, 
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, 
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector)

IEnumerable&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer, IEnumerable&amp;lt;TInner&amp;gt; inner, 
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector, Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector, 
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector, 
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each outer value from the outer source is mapped to an outer key by calling the outer key selector, and each inner value from the inner source is mapped to an inner key. When a outer key is equal to zero, one, or more inner key, the source outer value and all the matching source inner values are paired, and mapped to a result by calling the result selector. So each outer value with or without matching inner values is mapped to a result in the returned sequence. It is called GroupJoin, because each outer value is paired with a group of matching inner values. If there is no matching inner values, the outer value is paired with an empty group:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoin()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin = outer.GroupJoin(
        inner: inner,
        outerKeySelector: person =&amp;gt; person.Name,
        innerKeySelector: character =&amp;gt; character.Starring,
        resultSelector: (person, charactersGroup) =&amp;gt; 
            new { Person = person, Characters = charactersGroup }); // Define query.
    foreach (var result in leftOuterJoin) // Execute query.
    {
        $&quot;{result.Person.Name} ({result.Person.PlaceOfBirth}): &quot;.Write();
        foreach (Character character in result.Characters)
        {
            $&quot;{character.Name} ({character.PlaceOfBirth}), &quot;.Write();
        }
        Environment.NewLine.Write();
    }
    // Robert Downey Jr. (US): Tony Stark (US),
    // Tom Hiddleston (UK):
    // Chris Hemsworth (AU): Thor (Asgard),
    // Chris Evans (US): Steve Rogers (US),
    // Paul Bettany (UK): Vision (KR), JARVIS (US),
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here result selector is called with each actor, and a group of matching characters, then it returns anonymous type consists of both the actor and the matching characters. So eventually GroupJoin returns a hierarchical sequence. In the results, the person with name “Tom Hiddleston” matches no character, so it is paired with an empty Character group, and each other person matches 1 or more characters, so is paired with a non-empty Character group. In query expression, GroupJoin is equivalent to join clause with the into keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoin()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin =
        from person in outer
        join character in inner on person.Name equals character.Starring into charactersGroup
        select new { Person = person, Characters = charactersGroup };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the join clause, into does not mean a continuation. it is a a part of the join.&lt;/p&gt;
&lt;p&gt;The hierarchical sequence returned by GroupJoin can be flattened by SelectMany. In this kind of flatenning scenario, DefaultIfEmpty is usually used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithDefaultIfEmpty()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin = outer
        .GroupJoin(
            inner: inner,
            outerKeySelector: person =&amp;gt; person.Name,
            innerKeySelector: character =&amp;gt; character.Starring,
            resultSelector: (person, charactersGroup) =&amp;gt; new { Person = person, Characters = charactersGroup })
        .SelectMany(
            collectionSelector: group =&amp;gt; group.Characters.DefaultIfEmpty(),
            resultSelector: (group, character) =&amp;gt; new { Person = group.Person, Character = character }); // Define query.
    leftOuterJoin.WriteLines(result =&amp;gt; $&quot;{result.Person.Name}: {result.Character?.Name}&quot;);
    // Robert Downey Jr.: Tony Stark
    // Tom Hiddleston:
    // Chris Hemsworth: Thor
    // Chris Evans: Steve Rogers
    // Paul Bettany: Vision
    // Paul Bettany: JARVIS
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without the DefaultIfEmpty call, the second result “Tom Hiddleston” is ignored in the result sequence. The equivalent query expression has 2 from clauses for SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithDefaultIfEmpty()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin =
        from person in outer
        join character in inner on person.Name equals character.Starring into charactersGroup
        from character in charactersGroup.DefaultIfEmpty()
        select new { Person = person, Character = character };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is already a from clause before join clause, so, just add one more from clause after join clause.&lt;/p&gt;
&lt;p&gt;Left outer join can also implement by mapping each outer value with all filtered matching inner values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin = outer.Select(person =&amp;gt; new
    {
        Person = person,
        Characters = inner.Where(character =&amp;gt;
            EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring))
    }); // Define query.
    foreach (var result in leftOuterJoin) // Execute query.
    {
        $&quot;{result.Person.Name} ({result.Person.PlaceOfBirth}): &quot;.Write();
        foreach (Character character in result.Characters)
        {
            $&quot;{character.Name} ({character.PlaceOfBirth}), &quot;.Write();
        }
        Environment.NewLine.Write();
    }
    // Robert Downey Jr. (US): Tony Stark (US),
    // Tom Hiddleston (UK):
    // Chris Hemsworth (AU): Thor (Asgard),
    // Chris Evans (US): Steve Rogers (US),
    // Paul Bettany (UK): Vision (KR), JARVIS (US),
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice here the Where subquery filters all inner values for each outer value. Generally, left outer join can be implemented with mapping query and filtering subquery:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; LeftOuterJoinWithSelect&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
    return outer.Select(outerValue =&amp;gt; resultSelector(
        outerValue,
        inner.Where(innerValue =&amp;gt; comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue)))));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In query expression, it just a simple query expression with a select clause containing a subquery with a where clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithSelect()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    var leftOuterJoin =
        from person in outer
        select new
        {
            Person = person,
            Characters = from character in inner
                         where EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring)
                         select character
        };
}

internal static IEnumerable&amp;lt;TResult&amp;gt; LeftOuterJoinWithSelect&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, IEnumerable&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
    return from outerValue in outer
           select resultSelector(
                outerValue,
                (from innerValue in inner
                 where comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue))
                 select innerValue));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, for N outer values, GroupJoin pull all inner values once and cache them, Select and Where does not cache anything and pull all inner values N times. The internal implementation of these query methods are discussed later in this chapter.&lt;/p&gt;
&lt;h3&gt;Cross Join&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Join_(SQL)#Cross_join&quot;&gt;Cross join&lt;/a&gt; 2 sequences is to return the &lt;a href=&quot;https://en.wikipedia.org/wiki/Cartesian_product&quot;&gt;Cartesian product&lt;/a&gt; of values in those 2 sequences. The easiest way for cross join is SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static readonly int[] rows = { 1, 2, 3 };

private static readonly string[] columns = { &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot; };

internal static void CrossJoin()
{
    IEnumerable&amp;lt;string&amp;gt; cells = rows
        .SelectMany(row =&amp;gt; columns, (row, column) =&amp;gt; $&quot;{column}{row}&quot;); // Define query.

    int cellIndex = 0;
    int columnCount = columns.Length;
    foreach (string cell in cells) // Execute query.
    {
        $&quot;{cell} &quot;.Write();
        if (++cellIndex % columnCount == 0)
        {
            Environment.NewLine.Write();
        }
    }
    // A1 B1 C1 D1
    // A2 B2 C2 D2
    // A3 B3 C3 D3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice here all inner values are pulled for each outer value. If outer sequence has N outer values, then the inner sequence are iterated N times. In query expression, as fore mentioned, 2 from clauses are compiled to SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoin()
{
    IEnumerable&amp;lt;string&amp;gt; cells = from row in rows
                                from column in columns
                                select $&quot;{column}{row}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A general CrossJoin query method can be implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector) =&amp;gt;
        outer.SelectMany(outerValue =&amp;gt; inner, resultSelector);
        // Equivalent to:
        // from outerValue in outer
        // from innerValue in inner
        // select resultSelector(outerValue, innerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cross join can also be done with Join, with inner key always equal to outer key, so that each outer value matches all inner values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithJoin()
{
    IEnumerable&amp;lt;string&amp;gt; cells = rows.Join(
        inner: columns,
        outerKeySelector: row =&amp;gt; true,
        innerKeySelector: column =&amp;gt; true,
        resultSelector: (row, column) =&amp;gt; $&quot;{column}{row}&quot;); // Define query.
    int cellIndex = 0;
    int columnCount = columns.Length;
    foreach (string cell in cells) // Execute query.
    {
        $&quot;{cell} &quot;.Write();
        if (++cellIndex % columnCount == 0)
        {
            Environment.NewLine.Write();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And generally, cross join can be implemented by Join as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoinWithJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector) =&amp;gt;
        outer.Join(
            inner: inner,
            outerKeySelector: outerValue =&amp;gt; true,
            innerKeySelector: innerValue =&amp;gt; true,
            resultSelector: resultSelector); // Equivalent to:
        // Equivalent to:
        // from outerValue in outer
        // join innerValue in inner on true equals true
        // select resultSelector(outerValue, innerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In query expression, again, Join is just a join clause without into:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithJoin()
{
    IEnumerable&amp;lt;string&amp;gt; cells = from row in rows
                                join column in columns on true equals true
                                select $&quot;{column}{row}&quot;;
}

internal static IEnumerable&amp;lt;TResult&amp;gt; CrossJoinWithJoin&amp;lt;TOuter, TInner, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector) =&amp;gt;
        from outerValue in outer
        join innerValue in inner on true equals true
        select resultSelector(outerValue, innerValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above inner join can be logically viewed as cross join with filtering the matching outer value and inner value. The above inner join of persons and characters can be implemented with SelectMany and Where as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithSelectMany()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin = outer
        .SelectMany(
            collectionSelector: person =&amp;gt; inner,
            resultSelector: (person, character) =&amp;gt; new { Person = person, Character = character })
        .Where(crossJoinValue =&amp;gt; EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(
            crossJoinValue.Person.Name, crossJoinValue.Character.Starring))
        .Select(innerJoinValue =&amp;gt;
            $&quot;{innerJoinValue.Person.Name} ({innerJoinValue.Person.PlaceOfBirth}): {innerJoinValue.Character.Name}&quot;);
    // Define query.
    innerJoin.WriteLines(); // Execute query.
    // Robert Downey Jr. (US): Tony Stark
    // Chris Hemsworth (AU): Thor
    // Chris Evans (US): Steve Rogers
    // Paul Bettany (UK): Vision
    // Paul Bettany (UK): JARVIS
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, inner join and be implemented with cross join and filtering:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;TResult&amp;gt; InnerJoinWithSelectMany&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
    return outer
        .SelectMany(
            collectionSelector: outerValue =&amp;gt; inner,
            resultSelector: (outerValue, innerValue) =&amp;gt; new { OuterValue = outerValue, InnerValue = innerValue })
        .Where(
            crossJoinValue =&amp;gt; comparer.Equals(
                outerKeySelector(crossJoinValue.OuterValue),
                innerKeySelector(crossJoinValue.InnerValue)))
        .Select(innerJoinValue =&amp;gt; resultSelector(innerJoinValue.OuterValue, innerJoinValue.InnerValue));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In query expression, as fore mentioned, SelectMany is 2 from clauses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithSelectMany()
{
    IEnumerable&amp;lt;Person&amp;gt; outer = Persons();
    IEnumerable&amp;lt;Character&amp;gt; inner = Characters();
    IEnumerable&amp;lt;string&amp;gt; innerJoin =
        from person in outer
        from character in inner
        where EqualityComparer&amp;lt;string&amp;gt;.Default.Equals(person.Name, character.Starring)
        select $&quot;{person.Name} ({person.PlaceOfBirth}): {character.Name}&quot;;
}

internal static IEnumerable&amp;lt;TResult&amp;gt; InnerJoinWithSelectMany&amp;lt;TOuter, TInner, TKey, TResult&amp;gt;(
    this IEnumerable&amp;lt;TOuter&amp;gt; outer,
    IEnumerable&amp;lt;TInner&amp;gt; inner,
    Func&amp;lt;TOuter, TKey&amp;gt; outerKeySelector,
    Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
    Func&amp;lt;TOuter, TInner, TResult&amp;gt; resultSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer = null)
{
    comparer = comparer ?? EqualityComparer&amp;lt;TKey&amp;gt;.Default;
    return from outerValue in outer, 
           from innerValue in inner
           where comparer.Equals(outerKeySelector(outerValue), innerKeySelector(innerValue))
           select resultSelector(outerValue, innerValue);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, for N outer values, Join pull all inner values once and cache them, SelectMany does not cache anything and pull all inner values N times. Again the internal implementation of these query methods are discussed later in this chapter.&lt;/p&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;Concat merges 2 sequences by putting the second sequence’s values after the first sequence’s values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int[] First() =&amp;gt; new int[] { 1, 2, 3, 4, 4 };

internal static int[] Second() =&amp;gt; new int[] { 3, 4, 5, 6 };

internal static void Concat()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; second = Second();
    IEnumerable&amp;lt;int&amp;gt; concat = first.Concat(second); // Define query.
    concat.WriteLines(); // Execute query. 1 2 3 4 4 3 4 5 6
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET Core provides Prepend/Append, which merge the specified value to the beginning/end of the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Prepend&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element);

public static IEnumerable&amp;lt;TSource&amp;gt; Append&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource element);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AppendPrepend()
{
    IEnumerable&amp;lt;int&amp;gt; prepend = Enumerable.Range(0, 5).Prepend(-1); // Define query.
    prepend.WriteLines(); // Execute query. -1 0 1 2 3 4

    IEnumerable&amp;lt;int&amp;gt; append = Enumerable.Range(0, 5).Append(-1); // Define query.
    append.WriteLines(); // Execute query. 0 1 2 3 4 -1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;Distinct accepts a source sequence, and returns a &lt;a href=&quot;https://en.wikipedia.org/wiki/Set_(mathematics)&quot;&gt;set&lt;/a&gt;, where duplicate values are removed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Distinct()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; distinct = first.Distinct(); // Define query.
    distinct.WriteLines(); // Execute query. 1 2 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following query methods accepts 2 sequences and returns a set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);

public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);

public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast to Concat, Union adds 2 sequences as if they are sets, and returns their &lt;a href=&quot;https://en.wikipedia.org/wiki/Union_(set_theory)&quot;&gt;set union&lt;/a&gt;, which is equivalent to concatenating 2 sequences with duplicate values removed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Union()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; second = Second();
    IEnumerable&amp;lt;int&amp;gt; union = first.Union(second); // Define query.
    union.WriteLines(); // Execute query. 1 2 3 4 5 6
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Intersect returns 2 sequences’ &lt;a href=&quot;https://en.wikipedia.org/wiki/Intersection_(set_theory)&quot;&gt;set intersection&lt;/a&gt;, the distinct values that 2 sequences have in common:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Intersect()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; second = Second();
    IEnumerable&amp;lt;int&amp;gt; intersect = first.Intersect(second); // Define query.
    intersect.WriteLines(); // Execute query. 3 4
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Except returns the &lt;a href=&quot;https://en.wikipedia.org/wiki/Complement_(set_theory)&quot;&gt;set complement&lt;/a&gt; of 2 sequences, by subtracting the second sequence from the first one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Except()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; second = Second();
    IEnumerable&amp;lt;int&amp;gt; except = first.Except(second); // Define query.
    except.WriteLines(); // Execute query. 1 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are other overloads that accepts a comparer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Distinct&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);

public static IEnumerable&amp;lt;TSource&amp;gt; Union&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);

public static IEnumerable&amp;lt;TSource&amp;gt; Intersect&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);

public static IEnumerable&amp;lt;TSource&amp;gt; Except&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctWithComparer()
{
    IEnumerable&amp;lt;string&amp;gt; source = new string[] { &quot;aa&quot;, &quot;AA&quot;, &quot;Aa&quot;, &quot;aA&quot;, &quot;bb&quot; };
    IEnumerable&amp;lt;string&amp;gt; distinctWithComparer = source.Distinct(StringComparer.OrdinalIgnoreCase); // Define query.
    distinctWithComparer.WriteLines(); // Execute query. aa bb
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Convolution&lt;/h3&gt;
&lt;p&gt;Zip is provided since .NET Framework 4.0. It accepts 2 sequences and returns their &lt;a href=&quot;https://en.wikipedia.org/wiki/Convolution_(computer_science)&quot;&gt;convolution&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Zip&amp;lt;TFirst, TSecond, TResult&amp;gt;(
    this IEnumerable&amp;lt;TFirst&amp;gt; first, IEnumerable&amp;lt;TSecond&amp;gt; second, Func&amp;lt;TFirst, TSecond, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It calls result selector to map 2 values (each value from each sequence) to a result in the returned sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Zip()
{
    IEnumerable&amp;lt;int&amp;gt; first = First();
    IEnumerable&amp;lt;int&amp;gt; second = Second();
    IEnumerable&amp;lt;int&amp;gt; zip = first.Zip(second, (a, b) =&amp;gt; a + b); // Define query.
    zip.WriteLines(); // Execute query. 4 6 8 10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When one input sequence has more values than the other, those values are ignored. Here the first sequence { 1, 2, 3, 4, 4 } and second sequence { 3, 4, 5, 6 } are zipped to a new sequence { 1 + 3, 2 + 4, 3 + 5, 4 + 6 }. The first sequence has one more value than the second, so its last value 4 is ignored.&lt;/p&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Partitioning query methods are straightforward. Skip/Take simply skips/takes the specified number of values in the source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SkipTake()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, 5);

    IEnumerable&amp;lt;int&amp;gt; partition1 = source.Skip(2); // Define query.
    partition1.WriteLines(); // Execute query. 2 3 4

    IEnumerable&amp;lt;int&amp;gt; partition2 = source.Take(2); // Define query.
    partition2.WriteLines(); // Execute query. 0 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SkipWhile/TakeWhile accept a predicate function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SkipWhile/TakeWhile skips/takes values while predicate is called with each value and returns true. Once predicate is called with a value and returns false, SkipWhile/TakeWhile stop partitioning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TakeWhileSkipWhile()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 1, 2, 3, -1, 4, 5 };

    IEnumerable&amp;lt;int&amp;gt; partition1 = source.TakeWhile(int32 =&amp;gt; int32 &amp;gt; 0); // Define query.
    partition1.WriteLines(); // Execute query. 1 2 3

    IEnumerable&amp;lt;int&amp;gt; partition2 = source.SkipWhile(int32 =&amp;gt; int32 &amp;gt; 0); // Define query.
    partition2.WriteLines(); // Execute query. -1 4 5
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like Where and Select, SkipWhile/TakeWhile also have the indexed overload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; SkipWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);

public static IEnumerable&amp;lt;TSource&amp;gt; TakeWhile&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TakeWhileSkipWhileWithIndex()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 5 };

    IEnumerable&amp;lt;int&amp;gt; partition1 = source.TakeWhile((int32, index) =&amp;gt; int32 &amp;gt;= index); // Define query.
    partition1.WriteLines();  // Execute query. 4 3 2

    IEnumerable&amp;lt;int&amp;gt; partition2 = source.SkipWhile((int32, index) =&amp;gt; int32 &amp;gt;= index); // Define query.
    partition2.WriteLines();  // Execute query. 1 5
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;The ordering methods are OrderBy and OrderByDescending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)

IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)

IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)

IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key selector specifies what should be compared to determine the order of values in the result sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderBy()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    IEnumerable&amp;lt;string&amp;gt; ordered = source.OrderBy(word =&amp;gt; word); // Define query.
    ordered.WriteLines(); // Execute query. four one three Two Zero
    source.WriteLines(); // Original sequence. Zero one Two three four
}

internal static void OrderByDescending()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    IEnumerable&amp;lt;string&amp;gt; ordered = source.OrderByDescending(word =&amp;gt; word); // Define query.
    ordered.WriteLines(); // Execute query. Zero Two three one four
    source.WriteLines(); // Original sequence. Zero one Two three four
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here each value from the source sequence uses itself as the key for ordering. Also, as demonstrated above, OrderBy returns a new sequence, so OrderBy/OrderByDescending does not impact the source sequence. The equivalent query expression has a orderby clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderBy()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    IEnumerable&amp;lt;string&amp;gt; ordered = from word in source
                                  orderby word ascending // ascending can be omitted.
                                  select word;
}

internal static void OrderByDescending()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    IEnumerable&amp;lt;string&amp;gt; ordered = from word in source
                                  orderby word descending
                                  select word;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The comparer can be specified to provides the method to compare 2 keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IComparer&amp;lt;in T&amp;gt;
    {
        int Compare(T x, T y);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compare returns an integer to determine the 2 values’ relative position in the ordered sequence. If x is less than y, Compare returns negative int value; If x is equal to y, Compare returns 0; If x is greater than y, Compare returns positive int value. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByWithComparer()
{
    IEnumerable&amp;lt;string&amp;gt; source = Words();
    IEnumerable&amp;lt;string&amp;gt; ordered = source.OrderBy(
        keySelector: word =&amp;gt; word, comparer: StringComparer.Ordinal); // Define query.
    ordered.WriteLines(); // Execute query. Two Zero four one three
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here StringComparer.Ordinal provides a case-sensitive comparison. “Zero” comes to the first position of the result sequence, because upper case letter is less than lower case letter. This overload with comparer is not supported in query expression. When using the other overload without comparer, OrderBy/OrderByDescending uses System.Collections.Generic.Comparer&amp;lt;TKey&amp;gt;.Default. In the first OrderBy example, Comparer&amp;lt;string&amp;gt;.Default is used, which is equivalent to StringComparer.CurrentCulture.&lt;/p&gt;
&lt;p&gt;As fore mentioned, ThenBy/ThenByDescending are extension methods of IOrderedEnumerable&amp;lt;T&amp;gt;, not IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)

IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)

IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)

IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So they can be composed right after OrderBy/OrderByDescending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ThenBy()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered = source // IEnumerable&amp;lt;Person&amp;gt;
        .OrderBy(person =&amp;gt; person.PlaceOfBirth) // IOrderedEnumerable&amp;lt;Person&amp;gt;
        .ThenBy(person =&amp;gt; person.Name); // IOrderedEnumerable&amp;lt;Person&amp;gt;
    ordered.WriteLines(person =&amp;gt; $&quot;{person.PlaceOfBirth}: {person.Name}&quot;); // Execute query.
    // AU: Chris Hemsworth
    // UK: Paul Bettany
    // UK: Tom Hiddleston
    // US: Chris Evans
    // US: Robert Downey Jr.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, persons are ordered by place of birth. If there are Person objects with the same PlaceOfBirth, they are ordered by Name. The query expression can have multiple key selectors in the orderby clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ThenBy()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered = from person in source
                                  orderby person.PlaceOfBirth, person.Name
                                  select person;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice OrderBy can also be called after calling OrderBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndOrderBy()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered = source
        .OrderBy(person =&amp;gt; person.PlaceOfBirth)
        .OrderBy(person =&amp;gt; person.Name); // Define query.
    ordered.WriteLines(person =&amp;gt; $&quot;{person.PlaceOfBirth}: {person.Name}&quot;); // Execute query.
    // US: Chris Evans
    // AU: Chris Hemsworth
    // UK: Paul Bettany
    // US: Robert Downey Jr.
    // UK: Tom Hiddleston
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OrderBy with OrderBy is totally different from OrderBy with ThenBy. Here persons are ordered by place of birth. Then, all persons are ordered again by name. The equivalent query expression is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByOrderBy1()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered = from person in source
                                  orderby person.PlaceOfBirth

                                  orderby person.Name
                                  select person;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To makes it more intuitive, it can be separated to 2 query expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByOrderBy2()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered1 = from person in source
                                   orderby person.PlaceOfBirth
                                   select person;
    IEnumerable&amp;lt;Person&amp;gt; ordered2 = from person in ordered1
                                   orderby person.Name
                                   select person;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, both orderby clauses work on the entire input sequence. As fore mentioned, the into query keyword is for this kind scenario of continuation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByOrderBy3()
{
    IEnumerable&amp;lt;Person&amp;gt; source = Persons();
    IEnumerable&amp;lt;Person&amp;gt; ordered = from person in source
                                  orderby person.PlaceOfBirth
                                  select person into person
                                  orderby person.Name
                                  select person;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compilation of the above 3 queries are identical.&lt;/p&gt;
&lt;p&gt;Reverse simply reverses the positions of values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Reverse&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Reverse()
{
    IEnumerable&amp;lt;int&amp;gt; source = Enumerable.Range(0, 5);
    IEnumerable&amp;lt;int&amp;gt; reversed = source.Reverse(); // Define query.
    reversed.WriteLines(); // Execute query. 4 3 2 1 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Cast converts each value in source sequence to the specified type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TResult&amp;gt; Cast&amp;lt;TResult&amp;gt;(this IEnumerable source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unlike other query methods, Cast is an extension method of non-generic sequence, so it can work with types implementing either IEnumerable or IEnumerable&amp;lt;T&amp;gt;. So it can enable LINQ query for legacy types. The following example calls Microsoft Team Foundation Service (TFS) client APIs to query work items, where Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection is returned. WorkItemCollection is a collection of Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem, but it only implements IEnumerable, so it can be casted to a generic IEnumerable&amp;lt;WorkItem&amp;gt; safely, and further LINQ query can be applied. The following example execute a WIQL (Work Item Query Language of TFS) statement to query work items from TFS. Since WIQL does not support GROUP BY clause, the work items can be grouped locally with LINQ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#if NETFX
internal static void CastNonGeneric(VssCredentials credentials)
{
    using (TfsTeamProjectCollection projectCollection = new TfsTeamProjectCollection(
        new Uri(&quot;https://dixin.visualstudio.com/DefaultCollection&quot;), credentials))
    {
        // WorkItemCollection implements IEnumerable.
        const string Wiql = &quot;SELECT * FROM WorkItems WHERE [Work Item Type] = &apos;Bug&apos; AND State != &apos;Closed&apos;&quot;; // WIQL does not support GROUP BY.
        WorkItemStore workItemStore = (WorkItemStore)projectCollection.GetService(typeof(WorkItemStore));
        WorkItemCollection workItems = workItemStore.Query(Wiql);

        IEnumerable&amp;lt;WorkItem&amp;gt; genericWorkItems = workItems.Cast&amp;lt;WorkItem&amp;gt;(); // Define query.
        IEnumerable&amp;lt;IGrouping&amp;lt;string, WorkItem&amp;gt;&amp;gt; workItemGroups = genericWorkItems
            .GroupBy(workItem =&amp;gt; workItem.CreatedBy); // Group work items locally.
        // ...
    }
}
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other non-generic sequences, like System.Resources.ResourceSet, System.Resources.ResourceReader, can be casted in the same way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastMoreNonGeneric()
{
    // ResourceSet implements IEnumerable.
    ResourceSet resourceSet = new ResourceManager(typeof(Resources))
        .GetResourceSet(CultureInfo.CurrentCulture, createIfNotExists: true, tryParents: true);
    IEnumerable&amp;lt;DictionaryEntry&amp;gt; entries1 = resourceSet.Cast&amp;lt;DictionaryEntry&amp;gt;();

    // ResourceReader implements IEnumerable.
    Assembly assembly = typeof(QueryMethods).Assembly;
    using (Stream stream = assembly.GetManifestResourceStream(assembly.GetManifestResourceNames()[0]))
    using (ResourceReader resourceReader = new ResourceReader(stream))
    {
        IEnumerable&amp;lt;DictionaryEntry&amp;gt; entries2 = resourceReader.Cast&amp;lt;DictionaryEntry&amp;gt;();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In query expression syntax, just specify the type in from clause before the value name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#if NETFX
internal static void CastNonGeneric(VssCredentials credentials)
{
    // WorkItemCollection implements IEnumerable.
    using (TfsTeamProjectCollection projectCollection = new TfsTeamProjectCollection(
        new Uri(&quot;https://dixin.visualstudio.com/DefaultCollection&quot;), credentials))
    {
        const string Wiql = &quot;SELECT * FROM WorkItems WHERE [Work Item Type] = &apos;Bug&apos; AND State != &apos;Closed&apos;&quot;; // WIQL does not support GROUP BY.
        WorkItemStore workItemStore = (WorkItemStore)projectCollection.GetService(typeof(WorkItemStore));
        WorkItemCollection workItems = workItemStore.Query(Wiql);

        IEnumerable&amp;lt;IGrouping&amp;lt;string, WorkItem&amp;gt;&amp;gt; workItemGroups =
            from WorkItem workItem in workItems // Cast.
            group workItem by workItem.CreatedBy; // Group work items in local memory.
        // ...
    }
}
#endif

internal static void CastMoreNonGenericI()
{
    // ResourceSet implements IEnumerable.
    ResourceSet resourceSet = new ResourceManager(typeof(Resources))
        .GetResourceSet(CultureInfo.CurrentCulture, createIfNotExists: true, tryParents: true);
    IEnumerable&amp;lt;DictionaryEntry&amp;gt; entries1 =
        from DictionaryEntry entry in resourceSet // Cast.
        select entry;

    // ResourceReader implements IEnumerable.
    Assembly assembly = typeof(QueryMethods).Assembly;
    using (Stream stream = assembly.GetManifestResourceStream(assembly.GetManifestResourceNames()[0]))
    using (ResourceReader resourceReader = new ResourceReader(stream))
    {
        IEnumerable&amp;lt;DictionaryEntry&amp;gt; entries2 =
            from DictionaryEntry entry in resourceReader // Cast.
            select entry;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And of course Cast can be used to generic IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastGenericIEnumerable()
{
    IEnumerable&amp;lt;Base&amp;gt; source = new Base[] { new Derived(), new Derived() };
    IEnumerable&amp;lt;Derived&amp;gt; casted = source.Cast&amp;lt;Derived&amp;gt;(); // Define query.
    casted.WriteLines(result =&amp;gt; result.GetType().Name); // Execute query. Derived Derived
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the query expression syntax is the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastGenericIEnumerable()
{
    IEnumerable&amp;lt;Base&amp;gt; source = new Base[] { new Derived(), new Derived() };
    IEnumerable&amp;lt;Derived&amp;gt; casted = from Derived derived in source
                                  select derived;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cast must be used with caution, because type conversion can fail at runtime, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastGenericIEnumerableWithException()
{
    IEnumerable&amp;lt;Base&amp;gt; source = new Base[] { new Derived(), new Base() };
    IEnumerable&amp;lt;Derived&amp;gt; casted = source.Cast&amp;lt;Derived&amp;gt;(); // Define query.
    casted.WriteLines(result =&amp;gt; result.GetType().Name); // Execute query. Derived InvalidCastException
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An InvalidCastException is thrown because the second value is of Base type, and cannot be casted to Derived.&lt;/p&gt;
&lt;p&gt;The same query expression cast syntax can also be used in join clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastWithJoin()
{
    IEnumerable outer = new int[] { 1, 2, 3 };
    IEnumerable inner = new string[] { &quot;a&quot;, &quot;bb&quot;, &quot;ccc&quot; };
    IEnumerable&amp;lt;string&amp;gt; innerJoin = from int int32 in outer
                                    join string @string in inner on int32 equals @string.Length
                                    select $&quot;{int32}: {@string}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastWithJoin()
{
    IEnumerable outer = new int[] { 1, 2, 3 };
    IEnumerable inner = new string[] { string.Empty, &quot;a&quot;, &quot;bb&quot;, &quot;ccc&quot;, &quot;dddd&quot; };
    IEnumerable&amp;lt;string&amp;gt; innerJoin = outer.Cast&amp;lt;int&amp;gt;().Join(
        inner: inner.Cast&amp;lt;string&amp;gt;(),
        outerKeySelector: int32 =&amp;gt; int32,
        innerKeySelector: @string =&amp;gt; @string.Length, // on int32 equal @string.Length
        resultSelector: (int32, @string) =&amp;gt; $&quot;{int32}:{@string}&quot;); // Define query.
    innerJoin.WriteLines(); // Execute query. 1:a 2:bb 3:ccc
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cast looks similar to the fore mentioned OfType method, which also can have the result type specified. However, they are very different, OfType filters the values of the specified type. If there are values not of the specified type, they are simply ignored. There no conversion so there is no chance of InvalidCastException.&lt;/p&gt;
&lt;p&gt;AsEnumerable is a query method doing nothing. It accepts a source sequence, then return the source sequence itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its purpose is to make more derived type be visible only as IEnumerable&amp;lt;T&amp;gt;, and hide additional members of that more derived type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsEnumerable()
{
    List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;();
    list.Add(0);
    IEnumerable&amp;lt;int&amp;gt; sequence = list.AsEnumerable(); // Add method is no longer available.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the more derived source has method with the same signature as IEnumerable&amp;lt;T&amp;gt;’s extension method, after calling AsEnumerable, that IEnumerable&amp;lt;T&amp;gt; extension method is called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsEnumerableReverse()
{
    List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;();
    list.Reverse(); // List&amp;lt;T&amp;gt;.Reverse.
    list
        .AsEnumerable() // IEnumerable&amp;lt;T&amp;gt;.
        .Reverse(); // Enumerable.Reverse.

    SortedSet&amp;lt;int&amp;gt; sortedSet = new SortedSet&amp;lt;int&amp;gt;();
    sortedSet.Reverse(); // SortedSet&amp;lt;T&amp;gt;.Reverse.
    sortedSet.AsEnumerable().Reverse(); // Enumerable.Reverse.

    ReadOnlyCollectionBuilder&amp;lt;int&amp;gt; readOnlyCollection = new ReadOnlyCollectionBuilder&amp;lt;int&amp;gt;();
    readOnlyCollection.Reverse(); // ReadOnlyCollectionBuilder&amp;lt;T&amp;gt;.Reverse.
    readOnlyCollection.AsEnumerable().Reverse(); // Enumerable.Reverse.

    IQueryable&amp;lt;int&amp;gt; queryable = new EnumerableQuery&amp;lt;int&amp;gt;(Enumerable.Empty&amp;lt;int&amp;gt;());
    queryable.Reverse(); // Queryable.Reverse.
    queryable.AsEnumerable().Reverse(); // Enumerable.Reverse.

    ImmutableList&amp;lt;int&amp;gt; immutableList = ImmutableList.Create(0);
    immutableList.Reverse(); // ImmutableSortedSet&amp;lt;T&amp;gt;.Reverse.
    immutableList.AsEnumerable().Reverse(); // Enumerable.Reverse.

    ImmutableSortedSet&amp;lt;int&amp;gt; immutableSortedSet = ImmutableSortedSet.Create(0);
    immutableSortedSet.Reverse(); // ImmutableSortedSet&amp;lt;T&amp;gt;.Reverse.
    immutableSortedSet.AsEnumerable().Reverse(); // Enumerable.Reverse.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsEnumerable will be revisited when introducing IQueryable&amp;lt;T&amp;gt; in the LINQ to Entities chapter.&lt;/p&gt;
&lt;p&gt;As fore mentioned, local parallel LINQ queries are represented by ParallelQuery&amp;lt;T&amp;gt; and remote LINQ queries are represented by IQueryable&amp;lt;T&amp;gt;. They both implement IEnumerable&amp;lt;T&amp;gt;, so they both have AsEnumerable available. Since AsEnumerable returns IEnumerable&amp;lt;T&amp;gt;, it opt-out local parallel query and remote query back to local sequential query. These scenarios are discussed in Parallel LINQ chapter and LINQ to Entities chapter.&lt;/p&gt;
&lt;h2&gt;Collection queries&lt;/h2&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;The collection query methods convert source sequence to a collection by pulling all the values from the source sequence. ToArray and ToList are straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource[] ToArray&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static List&amp;lt;TSource&amp;gt; ToList&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They pull all values from the source sequence, and simply store them into a new array/list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ToArrayToList()
{
    int[] array = Enumerable
        .Range(0, 5) // Define query, return IEnumerable&amp;lt;T&amp;gt;.
        .ToArray(); // Execute query.

    List&amp;lt;int&amp;gt; list = Enumerable
        .Range(0, 5) // Define query, return IEnumerable&amp;lt;T&amp;gt;.
        .ToList(); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, when collection query methods are called for an IEnumerable&amp;lt;T&amp;gt; sequence representing LINQ query, that LINQ query is executed immediately. Similarly, ToDictionary/ToLookup also pulls all values from source sequence, and store those values into a new dictionary/lookup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, Func&amp;lt;TSource, TElement&amp;gt; elementSelector);

public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, Func&amp;lt;TSource, TElement&amp;gt; elementSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the definition of dictionary and lookup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public class Dictionary&amp;lt;TKey, TValue&amp;gt; : IEnumerable&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;, IEnumerable, 
        IDictionary&amp;lt;TKey, TValue&amp;gt;, IDictionary, ICollection&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;, ICollection, 
        IReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;, IReadOnlyCollection&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt;, 
        ISerializable, IDeserializationCallback { }
}

namespace System.Linq
{
    public interface ILookup&amp;lt;TKey, TElement&amp;gt; : IEnumerable&amp;lt;IGrouping&amp;lt;TKey, TElement&amp;gt;&amp;gt;, IEnumerable
    {
        IEnumerable&amp;lt;TElement&amp;gt; this[TKey key] { get; }

        int Count { get; }

        bool Contains(TKey key);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference between dictionary and lookup is, a dictionary is a flatten collection of key-value pairs, where each key is paired with one single value, and a lookup is a hierarchical collection of key-sequence pairs, where each key is a sequence of paired with one or more values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ToDictionaryToLookup()
{
    Dictionary&amp;lt;int, string&amp;gt; dictionary = Enumerable
        .Range(0, 5) // Define query.
        .ToDictionary(
            keySelector: int32 =&amp;gt; int32,
            elementSelector: int32 =&amp;gt; Math.Sqrt(int32).ToString(&quot;F&quot;, CultureInfo.InvariantCulture)); // Execute query.
    foreach (KeyValuePair&amp;lt;int, string&amp;gt; squareRoot in dictionary)
    {
        $&quot;√{squareRoot.Key}:{squareRoot.Value}&quot;.WriteLine();
    }
    // √0: 0.00
    // √1: 1.00
    // √2: 1.41
    // √3: 1.73
    // √4: 2.00

    ILookup&amp;lt;int, int&amp;gt; lookup = Enumerable
        .Range(-2, 5) // Define query.
        .ToLookup(int32 =&amp;gt; int32 * int32); // Execute query.
    foreach (IGrouping&amp;lt;int, int&amp;gt; squareRoots in lookup)
    {
        $&quot;√{squareRoots.Key}: &quot;.Write();
        foreach (int squareRoot in squareRoots)
        {
            $&quot;{squareRoot}, &quot;.Write();
        }
        Environment.NewLine.Write();
    }
    // √4: -2, 2,
    // √1: -1, 1,
    // √0: 0,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each value from source sequence is mapped to a key by calling the key selector function. If element selector is provided, each value from source sequence is mapped to a value in the result dictionary/lookup. In above example, if ToDictionary is called in the second query, an ArgumentException is thrown because dictionary cannot have multiple key and single value pairs with the same key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ToDictionaryWithException()
{
    Dictionary&amp;lt;int, int&amp;gt; lookup = Enumerable
        .Range(-2, 5) // Define query.
        .ToDictionary(int32 =&amp;gt; int32 * int32); // Execute query.
    // ArgumentException: An item with the same key has already been added.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another difference between dictionary and lookup is, at runtime, if querying a dictionary with a non-existing key, dictionary throws KeyNotFoundException, but if querying a lookup with a non-existing key, lookup returns a empty sequence peacefully.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LookupDictionary()
{
    ILookup&amp;lt;int, int&amp;gt; lookup = Enumerable
        .Range(0, 5) // Define query.
        .ToLookup(int32 =&amp;gt; int32); // Execute query.
    int count = 0;
    IEnumerable&amp;lt;int&amp;gt; group = lookup[10];
    foreach (int value in group)
    {
        count++;
    }
    count.WriteLine(); // 0

    Dictionary&amp;lt;int, int&amp;gt; dictionary = Enumerable
        .Range(0, 5) // Define query.
        .ToDictionary(int32 =&amp;gt; int32); // Execute query.
    int result = dictionary[10];
    // KeyNotFoundException: The given key was not present in the dictionary.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last difference is dictionary cannot have null key, while lookup can:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LookupDictionaryNullKey()
{
    ILookup&amp;lt;string, string&amp;gt; lookup = new string[] { &quot;a&quot;, &quot;b&quot;, null }.ToLookup(@string =&amp;gt; @string);
    int count = 0;
    IEnumerable&amp;lt;string&amp;gt; group = lookup[null];
    foreach (string value in group)
    {
        count++;
    }
    count.WriteLine(); // 1

    Dictionary&amp;lt;string, string&amp;gt; dictionary = new string[] { &quot;a&quot;, &quot;b&quot;, null }
        .ToDictionary(@string =&amp;gt; @string);
    // ArgumentNullException: Value cannot be null. Parameter name: key.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ToDictionary/ToLookup has other overloads to accept a key comparer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Dictionary&amp;lt;TKey, TSource&amp;gt; ToDictionary&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static ILookup&amp;lt;TKey, TSource&amp;gt; ToLookup&amp;lt;TSource, TKey&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector, IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static Dictionary&amp;lt;TKey, TElement&amp;gt; ToDictionary&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer);

public static ILookup&amp;lt;TKey, TElement&amp;gt; ToLookup&amp;lt;TSource, TKey, TElement&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source,
    Func&amp;lt;TSource, TKey&amp;gt; keySelector,
    Func&amp;lt;TSource, TElement&amp;gt; elementSelector,
    IEqualityComparer&amp;lt;TKey&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ToLookupWithComparer()
{
    ILookup&amp;lt;string, string&amp;gt; lookup = new string[] { &quot;aa&quot;, &quot;AA&quot;, &quot;Aa&quot;, &quot;aA&quot;, &quot;bb&quot; }
        .ToLookup(@string =&amp;gt; @string, StringComparer.OrdinalIgnoreCase);
    foreach (IGrouping&amp;lt;string, string&amp;gt; group in lookup)
    {
        $&quot;{group.Key}: &quot;.Write();
        foreach (string @string in group)
        {
            $&quot;{@string}, &quot;.Write();
        }
        Environment.NewLine.Write();
        // aa: aa, AA, Aa, aA,
        // bb: bb,
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Value queries&lt;/h2&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;Element query methods returns a single value from the source sequence. When they are called, they immediately execute the query, trying to pull values until the expected value is pulled. First/Last immediately pulls the first/last value of the source sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And InvalidOperationException is thrown if the source sequence is empty.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;int&amp;gt; Int32Source() =&amp;gt; new int[] { -1, 1, 2, 3, -4 };

internal static IEnumerable&amp;lt;int&amp;gt; SingleInt32Source() =&amp;gt; Enumerable.Repeat(5, 1);

internal static IEnumerable&amp;lt;int&amp;gt; EmptyInt32Source() =&amp;gt; Enumerable.Empty&amp;lt;int&amp;gt;();

internal static void FirstLast()
{
    int firstOfSource = Int32Source().First().WriteLine(); // -1
    int lastOfSource = Int32Source().Last().WriteLine(); // -4

    int firstOfSingleSOurce = SingleInt32Source().First().WriteLine(); // 5
    int lastOfSingleSOurce = SingleInt32Source().Last().WriteLine(); // 5

    int firstOfEmptySOurce = EmptyInt32Source().First(); // InvalidOperationException.
    int lastOfEmptySOurce = EmptyInt32Source().Last(); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other First/Last overload accept a predicate function. They immediately call the predicate function immediately with the values, and return the first/last value where predicate function returns true:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Logically, source.First(predicate) is equivalent to source.Where(predicate).First(), and source.Last(predicate) is equivalent to source.Where(predicate).Last():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FirstLastWithPredicate()
{
    int firstPositiveOfSource = Int32Source().First(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
    int lastNegativeOfSource = Int32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // -4

    int firstPositiveOfSingleSOurce = SingleInt32Source().First(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
    int lastNegativeOfSingleSOurce = SingleInt32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.

    int firstPositiveOfEmptySOurce = EmptyInt32Source().First(int32 =&amp;gt; int32 &amp;gt; 0); // InvalidOperationException.
    int lastNegativeOfEmptySOurce = EmptyInt32Source().Last(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are also FirstOrDefault/LastOrDefault methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource FirstOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource LastOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When there is no first/last value available, these methods return a default value instead of throwing exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FirstOrDefaultLastOrDefault()
{
    int firstOrDefaultOfEmptySOurce = EmptyInt32Source().FirstOrDefault().WriteLine(); // 0
    int lastOrDefaultOfEmptySOurce = EmptyInt32Source().LastOrDefault().WriteLine(); // 0

    int lastNegativeOrDefaultOfSingleSOurce = SingleInt32Source().LastOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0

    int firstPositiveOrDefaultOfEmptySOurce = EmptyInt32Source().FirstOrDefault(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 0
    int lastNegativeOrDefaultOfEmptySOurce = EmptyInt32Source().LastOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0

    Character lokiOrDefault = Characters()
        .FirstOrDefault(character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal));
    (lokiOrDefault == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ElementAt returns the value at the specified index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource ElementAt&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the specified index is out of range, ArgumentOutOfRangeException is thrown.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ElementAt()
{
    int elementAt2OfSource = Int32Source().ElementAt(2).WriteLine(); // 2
    int elementAt9OfSource = Int32Source().ElementAt(9); // ArgumentOutOfRangeException.
    int elementAtNegativeIndex = Int32Source().ElementAt(-5); // ArgumentOutOfRangeException.

    int elementAt0OfSingleSource = SingleInt32Source().ElementAt(0).WriteLine(); // 5
    int elementAt1OfSingleSource = SingleInt32Source().ElementAt(1); // ArgumentOutOfRangeException.

    int elementAt0OfEmptySource = EmptyInt32Source().ElementAt(0); // ArgumentOutOfRangeException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, there is ElementAtOrDefault:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource ElementAtOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int index);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When there is no value available at the specified index, a default value is returned:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ElementAtOrDefault()
{
    int elementAt9OrDefaultOfSource = Int32Source().ElementAtOrDefault(9).WriteLine(); // 0
    int elementAtNegativeIndexOrDefault = Int32Source().ElementAtOrDefault(-5).WriteLine(); // 0

    int elementAt1OrDefaultOfSingleSource = SingleInt32Source().ElementAtOrDefault(1).WriteLine(); // 0

    int elementAt0OrDefaultOfEmptySource = EmptyInt32Source().ElementAtOrDefault(0).WriteLine(); // 0

    Character characterAt5OrDefault = Characters().ElementAtOrDefault(5);
    (characterAt5OrDefault == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single is more strict. It pulls the single value from a singleton sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource Single&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If source sequence has no value or has more than one values, InvalidOperationException is thrown:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Single()
{
    int singleOfSource = Int32Source().Single(); // InvalidOperationException.
    int singleGreaterThan2OfSource = Int32Source().Single(int32 =&amp;gt; int32 &amp;gt; 2).WriteLine(); // 3
    int singleNegativeOfSource = Int32Source().Single(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.

    int singleOfSingleSource = SingleInt32Source().Single().WriteLine(); // 5
    int singleNegativeOfSingleSource = SingleInt32Source().Single(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.

    int singleOfEmptySource = EmptyInt32Source().Single(); // InvalidOperationException.
    int singlePositiveOfEmptySource = EmptyInt32Source().Single(int32 =&amp;gt; int32 == 0);  // InvalidOperationException.

    Character singleCharacter = Characters().Single(); // InvalidOperationException.
    Character fromAsgard = Characters()
        .Single(character =&amp;gt; &quot;Asgard&quot;.Equals(character.PlaceOfBirth, StringComparison.Ordinal))
        .WriteLine();  // Thor

    Character loki = Characters().Single(
        character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal)); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SingleOrDefault is just slightly less strict than Single:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource SingleOrDefault&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When source sequence has no value, it returns a default value. When source sequence has more than one values, it still throws InvalidOperationException:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SingleOrDefault()
{
    int singleOrDefaultOfSource = Int32Source().SingleOrDefault(); // InvalidOperationException.
    int singleNegativeOrDefaultOfSource = Int32Source().SingleOrDefault(int32 =&amp;gt; int32 &amp;lt; 0); // InvalidOperationException.

    int singleNegativeOrDefaultOfSingleSource = SingleInt32Source().SingleOrDefault(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // 0

    int singleOrDefaultOfEmptySource = EmptyInt32Source().SingleOrDefault().WriteLine(); // 0
    int singlePositiveOrDefaultOfEmptySource = EmptyInt32Source().SingleOrDefault(int32 =&amp;gt; int32 == 0); // 0

    Character singleCharacterOrDefault = Characters().SingleOrDefault(); // InvalidOperationException.
    Character lokiOrDefault = Characters()
        .SingleOrDefault(character =&amp;gt; &quot;Loki&quot;.Equals(character.Name, StringComparison.Ordinal));
    (lokiOrDefault == null).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Aggregate query methods pull all values from source sequence, and repeatedly call a function to accumulate those value. The easiest overload accepts a accumulator function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Aggregate&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TSource, TSource&amp;gt; func);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aggregate requires the source sequence to be not empty. When the source sequence is empty, it throws InvalidOperationException. When there is only 1 single value in he source sequence, it returns that value. When there are more than 1 values, it calls the accumulator function to accumulate the first and second values to a result, and then call the accumulator function again to accumulate the previous result and the the third value to another result, and so on, until all values are accumulated, eventually it returns the result of the last accumulator function call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Aggregate()
{
    int productOfSource = Int32Source()
        .Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32)
        .WriteLine(); // ((((-1 * 1) * 2) * 3) * -4) = 24.
    int productOfSingleSource = SingleInt32Source()
        .Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32).WriteLine(); // 5
    int productOfEmptySource = EmptyInt32Source()
        .Aggregate((currentProduct, int32) =&amp;gt; currentProduct * int32); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is another overload accepts a seed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TAccumulate Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TAccumulate seed, Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the seed provided, Aggregate does not require the source sequence to be not empty. When the source sequence is empty, it returns the seed. When the source sequence is not empty, it calls the accumulator function to accumulate the seed value and the first values to a result, and then call the accumulator function again to accumulate the previous result and the second to another result, and so on, until all values are accumulated, eventually it also returns the result of the last accumulator function call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AggregateWithSeed()
{
    int sumOfSquaresOfSource = Int32Source()
        .Aggregate(
            seed: 0,
            func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
        .WriteLine(); // 31
    int sumOfSquaresOfSingleSource = SingleInt32Source()
        .Aggregate(
            seed: 0,
            func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
        .WriteLine(); // 25
    int sumOfSquaresOfEmptySource = EmptyInt32Source()
        .Aggregate(
            seed: 0,
            func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32)
        .WriteLine(); // 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last overload accepts an additional result selector function, which is called with the last result of accumulate function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static TResult Aggregate&amp;lt;TSource, TAccumulate, TResult&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, 
    TAccumulate seed, 
    Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; func, Func&amp;lt;TAccumulate, TResult&amp;gt; resultSelector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So source.Aggregate(seed, accumulation, resultSelector) is equivalent to resultSelector(source.Aggregate(seed, accumulation)):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AggregateWithSeedAndResultSelector()
{
    string sumOfSquaresMessage = Int32Source()
        .Aggregate(
            seed: 0,
            func: (currentSumOfSquares, int32) =&amp;gt; currentSumOfSquares + int32 * int32,
            resultSelector: result =&amp;gt; $&quot;Sum of squares: {result}&quot;)
        .WriteLine(); // Sum of squares: 31
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Count returns the number of values in source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is one of the most intuitive query methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Count()
{
    int countOfSource = Int32Source().Count().WriteLine(); // 5
    int countOfSingleSource = SingleInt32Source().Count().WriteLine(); // 1
    int countOfEmptySource = EmptyInt32Source().Count().WriteLine(); // 0
    int countOfCharacters = Characters().Count().WriteLine(); // 5
    int countOfTypesInCoreLibrary = CoreLibrary.GetExportedTypes().Count().WriteLine(); // 1523
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload accepts a predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Count&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to First/Last, source.Count(predicate) is equivalent to ource.Where(predicate).Count():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CountWithPredicate()
{
    int positiveCountOfSource = Int32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 3
    int positiveCountOfSingleSource = SingleInt32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 1
    int positiveCountOfEmptySource = EmptyInt32Source().Count(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // 0
    int countOfConcat = Enumerable
        .Repeat(0, int.MaxValue)
        .Concat(Enumerable.Repeat(0, int.MaxValue))
        .Count(); // OverflowException.
    int countOfCharactersFromUS = Characters()
        .Count(character =&amp;gt; &quot;US&quot;.Equals(character.PlaceOfBirth))
        .WriteLine(); // 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LongCount is similar to Count. It can be used for large sequence, and returns a long (System.Int64) value instead of int (System.Int32):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static long LongCount&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LongCount()
{
    long longCountOfSource = Int32Source().LongCount().WriteLine(); // 5L
    long countOfConcat = Enumerable
        .Repeat(0, int.MaxValue)
        .Concat(Enumerable.Repeat(0, int.MaxValue))
        .LongCount()
        .WriteLine(); // int.MaxValue + int.MaxValue = 4294967294L
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max/Min also pulls all values from the source sequence of int values, and returns the minimum/maximum value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Max(this IEnumerable&amp;lt;int&amp;gt; source);

public static int Min(this IEnumerable&amp;lt;int&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max/Min throw InvalidOperationException if the source sequence is empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MinMax()
{
    int minOfSource = Int32Source().Min().WriteLine(); // -4
    int maxOfSource = Int32Source().Max().WriteLine(); // 3

    int minOfSingleSource = SingleInt32Source().Min().WriteLine(); // 5
    int maxOfSingleSource = SingleInt32Source().Max().WriteLine(); // 5

    int minOfEmptySource = EmptyInt32Source().Min(); // InvalidOperationException.
    int maxOfEmptySource = EmptyInt32Source().Max(); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload accepts a sequence of arbitrary type, and a selector function which maps each value to a int value for comparison:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Max&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);

public static int Min&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example queries the maximum type (type with the largest number of public members declared) in the .NET core library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxWithSelector()
{
    int mostDeclaredMembers = CoreLibrary.GetExportedTypes()
        .Max(type =&amp;gt; type.GetDeclaredMembers().Length).WriteLine(); // 311
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here each public type is mapped the count of its public members’ count number. The maximum type in .NET core library has 311 public members. Here Max returns the maximum count of members, but does not tell which type is that count from. To query the maximum type along with the the member count, Aggregate can be used to pull all types and accumulate by the maximum member count:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AggregateWithAnonymousTypeSeed()
{
    (List&amp;lt;Type&amp;gt; Types, int MaxMemberCount) maxTypes = CoreLibrary.GetExportedTypes().Aggregate(
        seed: (Types: new List&amp;lt;Type&amp;gt;(), MaxMemberCount: 0),
        func: (currentMax, type) =&amp;gt;
        {
            List&amp;lt;Type&amp;gt; currentMaxTypes = currentMax.Types;
            int currentMaxMemberCount = currentMax.MaxMemberCount;
            int memberCount = type.GetDeclaredMembers().Length;
            if (memberCount &amp;gt; currentMaxMemberCount)
            {
                currentMaxTypes.Clear();
                currentMaxTypes.Add(type);
                currentMaxMemberCount = memberCount;
            }
            else if (memberCount == currentMaxMemberCount)
            {
                // If multiple types have the same maximum member count, take all those types.
                currentMaxTypes.Add(type);
            }
            return (Types: currentMaxTypes, MaxMemberCount: currentMaxMemberCount);
        }); // Define query.
    maxTypes.Types.WriteLines(maxType =&amp;gt; $&quot;{maxType.FullName}:{maxTypes.MaxMemberCount}&quot;); 
    // Execute query. System.Convert:311
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the core library, System.Convert is the winner, with 311 public members declared.&lt;/p&gt;
&lt;p&gt;Besides int, Max/Min has overloads for int?, long, long?, double, double?, float, float?, decimal, decimal?. There are also overloads for arbitrary comparable type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Max&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

public static TSource Min&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They use Comparer&amp;lt;TSource&amp;gt;.Default to compare values in source sequence to determine the minimum/maximum value. Comparer&amp;lt;TSource&amp;gt;.Default requires TSource to implement at least one of IComparable and IComparable&amp;lt;TSource&amp;gt;; otherwise ArgumentException is thrown at runtime. Still take Character type as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Character : IComparable&amp;lt;Character&amp;gt;
{
    public int CompareTo(Character other) =&amp;gt;
        string.Compare(this.Name, other.Name, StringComparison.Ordinal);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Max/Min can be used with character sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxMinGeneric()
{
    Character maxCharacter = Characters().Max().WriteLine(); // Vision
    Character minCharacter = Characters().Min().WriteLine(); // JAVIS
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max/Min also have overload for arbitrary type, with a selector function to maps each value to a comparable result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TResult Max&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

public static TResult Min&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MaxMinGenericWithSelector()
{
    string maxName = Characters().Max(character =&amp;gt; character.Name).WriteLine(); // Vision
    string minName = Characters().Min(character =&amp;gt; character.Name).WriteLine(); // JAVIS
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, source.Max(selector) is equivalent to source.Select(selector),Max, and source.Min(selector) is equivalent to source.Select(selector).Min().&lt;/p&gt;
&lt;p&gt;Sum/Average pulls all int values from the source sequence, and calculate the sum/average of all the values. The signatures are similar to Max/Min:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Sum(this IEnumerable&amp;lt;int&amp;gt; source);

public static double Average(this IEnumerable&amp;lt;int&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Average returns double instead of int. Also, when called with empty source sequence, Sum returns 0, while Average throws InvalidOperationException:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SumAverage()
{
    int sumOfSource = Int32Source().Sum().WriteLine(); // 1
    double averageOfSource = Int32Source().Average().WriteLine(); // 0.2

    int sumOfSingleSource = SingleInt32Source().Sum().WriteLine(); // 5
    double averageOfSingleSource = SingleInt32Source().Average().WriteLine(); // 5.0

    int sumOfEmptySource = EmptyInt32Source().Sum().WriteLine(); // 0
    double averageOfEmptySource = EmptyInt32Source().Average().WriteLine(); // InvalidOperationException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sum/Average has overload for arbitrary type, with a selector function to map each value to int value for calculation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static int Sum&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);

public static double Average&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int&amp;gt; selector);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example calculate the average count of public members declared on types in the core library, and the average count of all public members.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AverageWithSelector()
{
    double averageMemberCount = CoreLibrary.GetExportedTypes()
        .Average(type =&amp;gt; type.GetMembers().Length)
        .WriteLine(); // 22.0766378244747
    double averageDeclaredMemberCount = CoreLibrary.GetExportedTypes()
        .Average(type =&amp;gt; type.GetDeclaredMembers().Length)
        .WriteLine(); // 11.7527812113721
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, Sum/Average also has overloads for int?, long, long?, double, double?, float, float?, decimal, decimal?.&lt;/p&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;Any determines whether the source sequence is not empty, by immediately trying to pull the first value from source sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Any()
{
    bool anyInSource = Int32Source().Any().WriteLine(); // True
    bool anyInSingleSource = SingleInt32Source().Any().WriteLine(); // True
    bool anyInEmptySource = EmptyInt32Source().Any().WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload accepts a predicate function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Any&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Logically, source.Any(predicate) is equivalent to source.Where(predicate).Any().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnyWithPredicate()
{
    bool anyNegative = Int32Source().Any(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // True
    bool anyPositive = SingleInt32Source().Any(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // True
    bool any0 = EmptyInt32Source().Any(_ =&amp;gt; true).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All accepts a predicate. It also tries to pull values from the source sequence, and calls predicate function with each value. It returns true if predicate returns true for all values; otherwise, it returns false:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool All&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All always returns true for empty source.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void All()
{
    bool allNegative = Int32Source().All(int32 =&amp;gt; int32 &amp;lt; 0).WriteLine(); // False
    bool allPositive = SingleInt32Source().All(int32 =&amp;gt; int32 &amp;gt; 0).WriteLine(); // True
    bool allGreaterThanMax = EmptyInt32Source().All(int32 =&amp;gt; int32 &amp;gt; int.MaxValue).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Contains determines whether source sequence contains the specified value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Contains&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, TSource value);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Contains()
{
    bool contains5InSource = Int32Source().Contains(5).WriteLine(); // False
    bool contains5InSingleSource = SingleInt32Source().Contains(5).WriteLine(); // True
    bool contains5InEmptySource = EmptyInt32Source().Contains(5).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload of Contains accepts a comparer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Contains&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, TSource value, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ContainsWithComparer()
{
    bool containsTwo = Words().Contains(&quot;two&quot;, StringComparer.Ordinal).WriteLine(); // False
    bool containsTwoIgnoreCase = Words().Contains(&quot;two&quot;, StringComparer.OrdinalIgnoreCase).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to other query methods, the first overload without comparer uses EqualityComparer&amp;lt;TSource&amp;gt;.Default.&lt;/p&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;.NET has many ways to determine equality for objects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd183759.aspx&quot;&gt;Reference equality&lt;/a&gt;/identity: object.ReferenceEquals, == operator without override&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd183755.aspx&quot;&gt;Value equality&lt;/a&gt;/equivalence: static object.Equals, instance object.Equals, object.GetHashCode, overridden == operator, IEquatable&amp;lt;T&amp;gt;.Equals, IEqualityComparer.Equals, IEqualityComparer&amp;lt;T&amp;gt;.Equals, IComparable.Compare, IComparable&amp;lt;T&amp;gt;.Compare, IComparer.Compare, IComparer&amp;lt;T&amp;gt;.Compare&lt;/li&gt;
&lt;li&gt;Sequential equality: Enumerable.SequentialEqual&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SequentialEqual query method is provided to compares the sequential equality of 2 IEnumerable&amp;lt;T&amp;gt; sequences:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2 sequences are sequentially equal if their length are equal, and for each index, 2 values from both sequences are equal (determined by EqualityComparer&amp;lt;TSource&amp;gt;.Default).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SequentialEqual()
{
    IEnumerable&amp;lt;object&amp;gt; first = new object[] { null, 1, &quot;2&quot;, CoreLibrary };
    IEnumerable&amp;lt;object&amp;gt; second = new List&amp;lt;object&amp;gt;() { null, 1, $&quot;{1 + 1}&quot;, CoreLibrary };
    bool valueEqual = first.Equals(second).WriteLine(); // False
    bool referenceEqual = object.ReferenceEquals(first, second).WriteLine(); // False
    bool sequentialEqual = first.SequenceEqual(second.Concat(Enumerable.Empty&amp;lt;object&amp;gt;())).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Empty sequences with the same TSource type are sequentially equal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SequentialEqualOfEmpty()
{
    IEnumerable&amp;lt;Derived&amp;gt; emptyfirst = new ConcurrentQueue&amp;lt;Derived&amp;gt;();
    IEnumerable&amp;lt;Base&amp;gt; emptysecond = ImmutableHashSet.Create&amp;lt;Base&amp;gt;();
    bool sequentialEqual = emptyfirst.SequenceEqual(emptysecond).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload accepts a comparer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second, IEqualityComparer&amp;lt;TSource&amp;gt; comparer);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SequentialEqualWithComparer()
{
    IEnumerable&amp;lt;string&amp;gt; first = new string[] { null, string.Empty, &quot;ss&quot;, };
    IEnumerable&amp;lt;string&amp;gt; second = new string[] { null, string.Empty, &quot;ß&quot;, };
    CultureInfo.CurrentCulture = new CultureInfo(&quot;en-US&quot;);
    bool sequentialEqual1 = first.SequenceEqual(second, StringComparer.CurrentCulture).WriteLine(); // True
    bool sequentialEqual2 = first.SequenceEqual(second, StringComparer.Ordinal).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the first overload without comparer uses EqualityComparer&amp;lt;TSource&amp;gt;.Default.&lt;/p&gt;
&lt;h2&gt;Queries in other languages&lt;/h2&gt;
&lt;p&gt;The following table compares similar APIs/language features of&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LINQ to Objects query methods in &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx&quot;&gt;System.Linq.Enumerable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb310804.aspx&quot;&gt;query keywords&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;F# &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee353635.aspx&quot;&gt;Seq Module&lt;/a&gt; and &lt;a href=&quot;https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/Query.fsi&quot;&gt;QueryBuilder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Haskell &lt;a href=&quot;https://www.haskell.org/hugs/pages/libraries/base/Data-List.html&quot;&gt;Data.List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;JavaScript &lt;a href=&quot;https://msdn.microsoft.com/en-us/LIBRary/k4h76zbx.aspx&quot;&gt;Array.prototype&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please notice JavaScript methods are not deferred.&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;922&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Enumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;F# Seq&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;F# query builder&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;Haskell&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;JavaScript&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Aggregate&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;fold, reduce&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;foldl&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;reduce&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;foldr&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;reduceRight&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;All&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;forAll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;all&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;all&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;every&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Any&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;exists&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;exists&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;null, any&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;some&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Average&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;average, averageBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;averageBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Cast&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;from/join T … in …&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;cast&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Concat&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;append&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;++&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;concat&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Contains&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;contains&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;elem&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;includes&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Count&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;length&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;count&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;length&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;length&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Distinct&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;dictinct, dictinctBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;distinct&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;nub, nubBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ElementAt&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;nth&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;nth&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;!!&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Empty&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;empty&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;[]&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Except&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;\&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;First&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;find, head, pick&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;find, head&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;head&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;FirstOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;tryFind, tryPick&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;headOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;find&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;find&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;group … by&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;groupBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;groupBy, groupValBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;groupBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;GroupJoin&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;join … into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;groupJoin, leftOuterJoin&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Intersect&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;intersect, intersectBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;join&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;join&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Last&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;last&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;last&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;last&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;LastOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;lastOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Max&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;max, maxBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;maxBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;maximum, maximumBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Min&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;min, minBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;minBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;minimum, minimumBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;OrderBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;orderby … (ascending)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;sort, sortBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;sortBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;sort, sortOn, sortBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;sort&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;OrferByDescending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;orderby … descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;sortByDescending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Range&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;..&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;…&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Repeat&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;replicate&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Reverse&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;reverse&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;reverse&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;from … select, let&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;map&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;select&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;map&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;map&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;SelectMany&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;from … from … select&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;collect&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;bind, &amp;gt;&amp;gt;=&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;SequenceEqual&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Single&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;exactlyOne&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;exactlyOne&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;SingleOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;exactlyOneOrDefault&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Skip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;skip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;skip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;drop&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;SkipWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;skipWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;skipWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;dropWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Sum&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;sum, sumBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;sum&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Take&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;take, truncate&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;take&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;take&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;TakeWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;takeWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;takeWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;takeWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ThenBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;orderby … (ascending)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;thenBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ThenByDescending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;orderby … descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;thenByDescending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ToArray&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;toArray&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ToDictionary&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;entries&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;ToList&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;toList&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Union&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;union, unionBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Where&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;where&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;filter, where&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;where&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;filter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;filter&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;135&quot;&amp;gt;Zip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;165&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;150&quot;&amp;gt;zip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;183&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;179&quot;&amp;gt;zipWith&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;108&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;There are connections among LINQ, C#, F#, and Haskell. As &lt;a href=&quot;http://ericlippert.com/&quot;&gt;Eric Lippert&lt;/a&gt; &lt;a href=&quot;http://stackoverflow.com/questions/4683506/are-there-any-connections-between-haskell-and-linq&quot;&gt;said&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yes, the design of LINQ query comprehensions was heavily influenced by the design of Haskell.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For F# and C#/Haskell, &lt;a href=&quot;https://en.wikipedia.org/wiki/Don_Syme&quot;&gt;Don Syme&lt;/a&gt; (designer and architect of F#) &lt;a href=&quot;https://www.simple-talk.com/opinion/geek-of-the-week/don-syme-geek-of-the-week/&quot;&gt;said&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As it developed, F# borrowed more ideas from other languages: Haskell was influential in many ways, from basic syntax elements such as the ‘light’ syntax, to rich constructs such as sequence expressions and computation expressions, which are ways of generating and composing data structures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Microsoft also directly experimented Haskell on .NET. In &lt;a href=&quot;http://www.infoq.com/interviews/F-Sharp-Don-Syme&quot;&gt;an interview&lt;/a&gt;, Don Syme mentioned:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;During this time we had a go doing Haskell for .NET, we actually got a long way in doing that, but in the end there is quite a lot of dissonance between Haskell and .NET.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>LINQ to Objects in Depth (1) Local Sequential Query</title><link>https://dixin.github.io/posts/linq-to-objects-local-sequential-query-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-to-objects-local-sequential-query-7/</guid><description>LINQ to Objects queries sequences of .NET objects in local memory of current .NET application or service. Its data source and the queries are represented by IEnumerable&lt;T&gt;.</description><pubDate>Sun, 01 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects in Depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/linq-to-objects-local-sequential-query&quot;&gt;https://weblogs.asp.net/dixin/linq-to-objects-local-sequential-query&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;LINQ to Objects queries sequences of .NET objects in local memory of current .NET application or service. Its data source and the queries are represented by IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Iteration pattern and foreach statement&lt;/h2&gt;
&lt;p&gt;C#/.NET follows &lt;a href=&quot;http://en.wikipedia.org/wiki/Iterator_pattern&quot;&gt;iterator pattern&lt;/a&gt; to define sequence of values, and implement sequential access to the values in sequence in a unified approach. Iteration pattern consists of a sequence (also called container of items, or aggregate of elements) and an iterator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class Sequence
{
    public abstract Iterator GetEnumerator(); // Must be public.
}

internal abstract class Iterator
{
    public abstract bool MoveNext(); // Must be public.

    public abstract object Current { get; } // Must be public.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And their generic version is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class GenericSequence&amp;lt;T&amp;gt;
{
    public abstract GenericIterator&amp;lt;T&amp;gt; GetEnumerator(); // Must be public.
}

internal abstract class GenericIterator&amp;lt;T&amp;gt;
{
    public abstract bool MoveNext(); // Must be public.

    public abstract T Current { get; } // Must be public.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These types and members demonstrate the minimum requirements for iteration pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The sequence is the container of sequential values, it has a GetEnumerator factory method returning an iterator&lt;/li&gt;
&lt;li&gt;Iterator traverses all values in the sequence. Its MoveNext method returns a bool value to indicate whether there is still a next value that can be pulled. If true is returned, its Current property can be called to pull that value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then the values in above non-generic and generic sequences can be access with C# foreach statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class IteratorPattern
{
    internal static void ForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; processNext)
    {
        foreach (T value in sequence)
        {
            processNext(value);
        }
    }

    internal static void ForEach&amp;lt;T&amp;gt;(GenericSequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; processNext)
    {
        foreach (T value in sequence)
        {
            processNext(value);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above foreach loops are compiled to while loops:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; processNext)
{
    Iterator iterator = sequence.GetEnumerator();
    try
    {
        while (iterator.MoveNext())
        {
            T value = (T)iterator.Current;
            processNext(value);
        }
    }
    finally
    {
        (iterator as IDisposable)?.Dispose();
    }
}

internal static void CompiledForEach&amp;lt;T&amp;gt;(GenericSequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; processNext)
{
    GenericIterator&amp;lt;T&amp;gt; iterator = sequence.GetEnumerator();
    try
    {
        while (iterator.MoveNext())
        {
            T value = iterator.Current;
            processNext(value);
        }
    }
    finally
    {
        (iterator as IDisposable)?.Dispose();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the foreach loops is syntactic sugar to make above imperative control flow declarative. The generic version is always preferred, becuase the non-generic Iterator’s Current property returns object, it has to be explicitly casted to the expected type specified in the foreach statement, which could be a chance of failure.&lt;/p&gt;
&lt;p&gt;To demonstrate the iterator pattern implementation, a sequence of values can be stored with a singly linked list, with one value in each node:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class SinglyLinkedListNode&amp;lt;T&amp;gt;
{
    internal SinglyLinkedListNode(T value, SinglyLinkedListNode&amp;lt;T&amp;gt; next = null)
    {
        this.Value = value;
        this.Next = next;
    }

    public T Value { get; }

    public SinglyLinkedListNode&amp;lt;T&amp;gt; Next { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then iterator can be implemented to traverse along the linked list nodes. Iterator pattern is imperative, and iterator can change its state during the iteration. When MoveNext is called and returns true, it have Current to return a different next value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class LinkedListIterator&amp;lt;T&amp;gt; : GenericIterator&amp;lt;T&amp;gt;
{
    private SinglyLinkedListNode&amp;lt;T&amp;gt; node; // State.

    internal LinkedListIterator(SinglyLinkedListNode&amp;lt;T&amp;gt; head) =&amp;gt;
        this.node = new SinglyLinkedListNode&amp;lt;T&amp;gt;(default, head);

    public override bool MoveNext()
    {
        if (this.node.Next != null)
        {
            this.node = this.node.Next; // State change.
            return true;
        }
        return false;
    }

    public override T Current =&amp;gt; this.node.Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the sequence can be simply implemented as a iterator factory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class LinkedListSequence&amp;lt;T&amp;gt; : GenericSequence&amp;lt;T&amp;gt;
{
    private readonly SinglyLinkedListNode&amp;lt;T&amp;gt; head;

    internal LinkedListSequence(SinglyLinkedListNode&amp;lt;T&amp;gt; head) =&amp;gt; this.head = head;

    public override GenericIterator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt; new LinkedListIterator&amp;lt;T&amp;gt;(this.head);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the values in the linked list sequence can be sequentially pulled with the foreach syntactic sugar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach(SinglyLinkedListNode&amp;lt;int&amp;gt; head)
{
    LinkedListSequence&amp;lt;int&amp;gt; sequence = new LinkedListSequence&amp;lt;int&amp;gt;(head);
    foreach (int value in sequence)
    {
        value.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A general implementation of iterator pattern will be discussed later in this chapter.&lt;/p&gt;
&lt;h2&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;Initially, .NET Framework 1.0 provides IEnumerable and IEnumerator interfaces to represent iterator pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections
{
    public interface IEnumerable // Sequence.
    {
        IEnumerator GetEnumerator();
    }

    public interface IEnumerator // Iterator.
    {
        object Current { get; }

        bool MoveNext();

        void Reset(); // For COM interoperability.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Many sequence and collection types implement IEnumerable so that they can be used with foreach, like ArrayList, Queue, Stack, etc. Then .NET Framework 2.0 supports generics, where the generic version, IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;, are provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IEnumerable&amp;lt;T&amp;gt; : IEnumerable // Sequence.
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }

    public interface IEnumerator&amp;lt;T&amp;gt; : IDisposable, IEnumerator // Iterator.
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since then the sequence and collection types are provided with IEnumerable&amp;lt;T&amp;gt; implemented by default, like List&amp;lt;T&amp;gt;, Queue&amp;lt;T&amp;gt;, Stack&amp;lt;T&amp;gt;, etc.&lt;/p&gt;
&lt;p&gt;Later, .NET Framework 4.0 introduces covariance and contravariance for generic interface. As discussed in the Functional Programming chapter, T is covariant for both IEnumerable&amp;lt;T&amp;gt; and IEnumerable&amp;lt;T&amp;gt;. So their definitions are updated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable // Sequence.
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }

    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator // Iterator.
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;EnumerableAssert utility&lt;/h3&gt;
&lt;p&gt;In Microsoft’s unit test framework &lt;a href=&quot;https://en.wikipedia.org/wiki/MSTest&quot;&gt;MSTest&lt;/a&gt;, there are &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms182530.aspx&quot;&gt;built-in assertion utility types&lt;/a&gt; provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assert to check general conditions, providing methods like IsTrue, IsNotNull, AreEqual, etc.&lt;/li&gt;
&lt;li&gt;StringAssert to check conditions for string, providing methods like Contains, StartsWith, EndsWith, etc.&lt;/li&gt;
&lt;li&gt;CollectionAssert to check conditions for ICollection, providing methods like AllItemsAreInstancesOfType, AllItemsAreNotNull, IsSubsetOf, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate how to consume IEnumerator&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; with the iterator pattern, an EnumerableAssert utility type can be defined to check conditions for sequence. For example, the following assertion methods check whether the specified sequence is not null and is empty/is not null and is not empty/is null or is empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableAssert
{
    public static void IsEmpty&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
    {
        Assert.IsNotNull(actual, message, parameters);
        using (IEnumerator&amp;lt;T&amp;gt; iterator = actual.GetEnumerator())
        {
            Assert.IsFalse(iterator.MoveNext(), message, parameters);
        }
    }

    public static void Any&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
    {
        Assert.IsNotNull(actual, message, parameters);
        using (IEnumerator&amp;lt;T&amp;gt; iterator = actual.GetEnumerator())
        {
            Assert.IsTrue(iterator.MoveNext(), message, parameters);
        }
    }
    
    public static void IsNullOrEmpty&amp;lt;T&amp;gt;(
        IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
    {
        using (IEnumerator&amp;lt;T&amp;gt; iterator = actual?.GetEnumerator())
        {
            Assert.IsFalse(iterator?.MoveNext() ?? false, message, parameters);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following methods check whether the specified sequence contains one single value/contains more then one values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void Single&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    using (IEnumerator&amp;lt;T&amp;gt; iterator = actual.GetEnumerator())
    {
        Assert.IsTrue(iterator.MoveNext() &amp;amp;&amp;amp; !iterator.MoveNext(), message, parameters);
    }
}

public static void Multiple&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    using (IEnumerator&amp;lt;T&amp;gt; iterator = actual.GetEnumerator())
    {
        Assert.IsTrue(iterator.MoveNext() &amp;amp;&amp;amp; iterator.MoveNext(), message, parameters);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following methods check whether the specified sequence contains/does not contain the specified value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void Contains&amp;lt;T&amp;gt;(
    T expected,
    IEnumerable&amp;lt;T&amp;gt; actual,
    IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
    string message = null,
    params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    comparer = comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;
    foreach (T value in actual)
    {
        if (comparer.Equals(expected, value))
        {
            return;
        }
    }
    Assert.Fail(message, parameters);
}

public static void DoesNotContain&amp;lt;T&amp;gt;(
    T expected, IEnumerable&amp;lt;T&amp;gt; actual, 
    IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
    string message = null,
    params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    comparer = comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;
    foreach (T value in actual)
    {
        if (comparer.Equals(expected, value))
        {
            Assert.Fail(message, parameters);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following AreSequentialEqual method checks whether 2 sequences’ values are sequentially equal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void AreSequentialEqual&amp;lt;T&amp;gt;(
    IEnumerable&amp;lt;T&amp;gt; expected,
    IEnumerable&amp;lt;T&amp;gt; actual,
    IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
    string message = null,
    params object[] parameters)
{
    Assert.IsNotNull(expected, message ?? $&quot;Expected sequence is null.&quot;, parameters);
    Assert.IsNotNull(actual, message ?? $&quot;Actual sequence is null.&quot;, parameters);

    comparer = comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;
    using (IEnumerator&amp;lt;T&amp;gt; expectedItorator = expected.GetEnumerator())
    using (IEnumerator&amp;lt;T&amp;gt; actualIterator = actual.GetEnumerator())
    {
        int expectedIndex = 0;
        for (; expectedItorator.MoveNext(); expectedIndex++)
        {
            Assert.IsTrue(
                actualIterator.MoveNext(),
                message ?? $&quot;Expected sequence has more than {expectedIndex} value(s), actual sequence has {expectedIndex} value(s).&quot;,
                parameters);
            T expectedValue = expectedItorator.Current;
            T actualValue = actualIterator.Current;
            Assert.IsTrue(
                comparer.Equals(expectedValue, actualValue),
                message ?? $&quot;Expected and actual sequences&apos; values are not equal at index {expectedIndex}. Expected value is {expectedValue}, actual value is {actualValue}.&quot;,
                parameters);
        }
        Assert.IsFalse(
            actualIterator.MoveNext(),
            message ?? $&quot;Expected sequence has {expectedIndex} value(s), actual sequence has more than {expectedIndex} value(s).&quot;,
            parameters);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;foreach loop vs. for loop&lt;/h3&gt;
&lt;p&gt;Array is a special type. A concrete array T[] inherits System.Array type, which does not implement IEnumerable&amp;lt;T&amp;gt; but IEnumerable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public abstract class Array : ICollection, IEnumerable, IList, IStructuralComparable, IStructuralEquatable
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead, T[] directly implements IEnumerable&amp;lt;T&amp;gt;, ICollection&amp;lt;T&amp;gt;, and IList&amp;lt;T&amp;gt;, as long as T[] is single dimensional, and zero–lower bound. So array T[] can be used with foreach loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; action)
{
    foreach (T value in array)
    {
        action(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For better performance, it is compiled into a for loop, accessing each value with index. For array, this is cheaper than calling MoveNext method and Current getter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; action)
{
    for (int index = 0; index &amp;lt; array.Length; index++)
    {
        T value = array[index];
        action(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so is string. Since string is a sequence of characters, it implements IEnumerable&amp;lt;char&amp;gt;. When string is used with foreach loop, it is also compiled to for loop for better performance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach(string @string, Action&amp;lt;char&amp;gt; action)
{
    foreach (char value in @string)
    {
        action(value);
    }
}

internal static void CompiledForEach(string @string, Action&amp;lt;char&amp;gt; action)
{
    for (int index = 0; index &amp;lt; @string.Length; index++)
    {
        char value = @string[index];
        action(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;LINQ to Objects queryable types&lt;/h2&gt;
&lt;p&gt;Most of pull-based .NET sequence and collection types implements IEnumerable&amp;lt;T&amp;gt;, like T[], List&amp;lt;T&amp;gt;, Dictionary&amp;lt;TKey, TValue&amp;gt;, HashSet&amp;lt;T&amp;gt;, Collection&amp;lt;T&amp;gt;, Stack&amp;lt;T&amp;gt;, Queue&amp;lt;T&amp;gt;, etc. Here is a detailed list of .NET types implemented IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft.Collections.Immutable.IImmutableQueue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableQueue&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft.Collections.Immutable.IImmutableStack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableStack&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft.Collections.Immutable.IOrderedCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Concurrent.IProducerConsumerCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Concurrent.ConcurrentBag&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.Concurrent.ConcurrentQueue&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.Concurrent.ConcurrentStack&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Concurrent.BlockingCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.ICollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Generic.IDictionary&amp;lt;TKey, TValue&amp;gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Concurrent.ConcurrentDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Dynamic.ExpandoObject&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.IList&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.ArraySegment&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.List&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.ObjectModel.ObservableCollection&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.KeyedCollection&amp;lt;TKey, TItem&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.ISet&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Generic.HashSet&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.SortedSet&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.IReadOnlyCollection&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Generic.IReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;
&lt;ul&gt;
&lt;li&gt;System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;Microsoft.Collections.Immutable.IImmutableDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableSortedDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.IReadOnlyList&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.IImmutableList&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic.List&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft.Collections.Immutable.IImmutableSet&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.IImmutableHashSet&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableHashSet&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft.Collections.Immutable.IImmutableSortedSet&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.Collections.Immutable.ImmutableSortedSet&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.LinkedList&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.Queue&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.SortedList&amp;lt;TKey, TValue&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Collections.Generic.Stack&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Linq.IGrouping&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Linq.ILookup&amp;lt;TKey, TElement&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.Lookup&amp;lt;TKey, TElement&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Linq.IOrderedEnumerable&amp;lt;TElement&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Linq.ParallelQuery&amp;lt;TSource&amp;gt;*&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.OrderedParallelQuery&amp;lt;TSource&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Linq.IQueryable&amp;lt;T&amp;gt;*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.IOrderedQueryable&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.EnumerableQuery&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Data.Objects.ObjectQuery&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Data.Entity.Core.Objects.ObjectQuery&amp;lt;T&amp;gt;
&lt;ul&gt;
&lt;li&gt;System.Data.Entity.Core.Objects.ObjectSet&amp;lt;TEntity&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Data.Entity.Infrastructure.DbQuery&amp;lt;TResult&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.Data.Entity.DbSet&amp;lt;TEntity&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable&amp;lt;TResult&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Data.Linq.ITable&amp;lt;TEntity&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;System.Data.Linq.Table&amp;lt;TEntity&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.DbSet&amp;lt;TEntity&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;T[] (not System.Array)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the LINQ to Objects query methods and query expression are available for to all the above types. Please notice ParallelQuery&amp;lt;T&amp;gt; represents local sequence where values can be pulled in parallel. It implements IEnumerable&amp;lt;T&amp;gt;, so it also supports pulling values sequentially. IQueryable&amp;lt;T&amp;gt; represents remote sequence of values. It also implements IEnumerable&amp;lt;T&amp;gt;, which its values can be loaded to local memory of current .NET application or service, and be queried locally and sequentially. This chapter covers LINQ to Objects queries for IEnumerable&amp;lt;T&amp;gt;. ParallelQuery&amp;lt;T&amp;gt; is covered in the Parallel LINQ chapter, and IQueryable&amp;lt;T&amp;gt; is covered in the LINQ to Entities chapter.&lt;/p&gt;
&lt;h3&gt;Non-generic sequence&lt;/h3&gt;
&lt;p&gt;For historical reason, there are a number of .NET early built-in types only implement IEnumerable. The following example queries these types from the core library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGenericSequences()
{
    Type nonGenericEnumerable = typeof(IEnumerable);
    Type genericEnumerable = typeof(IEnumerable&amp;lt;&amp;gt;);
    IEnumerable&amp;lt;Type&amp;gt; nonGenericSequences = typeof(object).Assembly // Core library.
        .GetExportedTypes()
        .Where(type =&amp;gt;
        {
            if (type == nonGenericEnumerable || type == genericEnumerable)
            {
                return false;
            }
            Type[] interfaces = type.GetInterfaces();
            return interfaces.Any(@interface =&amp;gt; @interface == nonGenericEnumerable)
                &amp;amp;&amp;amp; !interfaces.Any(@interface =&amp;gt;
                    @interface.IsGenericType
                    &amp;amp;&amp;amp; @interface.GetGenericTypeDefinition() == genericEnumerable);
        })
        .OrderBy(type =&amp;gt; type.FullName); // Define query.
    foreach (Type nonGenericSequence in nonGenericSequences) // Execute query.
    {
        nonGenericSequence.FullName.WriteLine();
    }
#if NETFX
    // System.Array
    // System.Collections.ArrayList
    // System.Collections.BitArray
    // System.Collections.CollectionBase
    // System.Collections.DictionaryBase
    // System.Collections.Hashtable
    // System.Collections.ICollection
    // System.Collections.IDictionary
    // System.Collections.IList
    // System.Collections.Queue
    // System.Collections.ReadOnlyCollectionBase
    // System.Collections.SortedList
    // System.Collections.Stack
    // System.Resources.IResourceReader
    // System.Resources.ResourceReader
    // System.Resources.ResourceSet
    // System.Runtime.Remoting.Channels.BaseChannelObjectWithProperties
    // System.Runtime.Remoting.Channels.BaseChannelSinkWithProperties
    // System.Runtime.Remoting.Channels.BaseChannelWithProperties
    // System.Security.AccessControl.AuthorizationRuleCollection
    // System.Security.AccessControl.CommonAcl
    // System.Security.AccessControl.DiscretionaryAcl
    // System.Security.AccessControl.GenericAcl
    // System.Security.AccessControl.RawAcl
    // System.Security.AccessControl.SystemAcl
    // System.Security.NamedPermissionSet
    // System.Security.Permissions.KeyContainerPermissionAccessEntryCollection
    // System.Security.PermissionSet
    // System.Security.Policy.ApplicationTrustCollection
    // System.Security.Policy.Evidence
    // System.Security.ReadOnlyPermissionSet
#else
    // System.Array
    // System.Collections.BitArray
    // System.Collections.CollectionBase
    // System.Collections.ICollection
    // System.Collections.IDictionary
    // System.Collections.IList
    // System.Resources.IResourceReader
    // System.Resources.ResourceSet
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET Core’s core library has less types, because many types are moved to separate NuGet packages. For example, in .NET Core, ArrayList, DictionaryBase, Hashtable, Queue, ReadOnlyCollectionBase, SortedList, Stack are moved to NuGet package System.Collections.NonGeneric. A Cast query method is provided to cast non-generic sequence can be casted to generic sequence for further LINQ to Objects query, which will be discussed later.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (15) Pattern matching</title><link>https://dixin.github.io/posts/functional-csharp-pattern-matching-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-pattern-matching-7/</guid><description>Pattern matching is a common feature in functional languages. C# 7.0 introduces basic pattern matching, including constant value as pattern and type as pattern, and C# 7.1 supports generics in pattern</description><pubDate>Fri, 15 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-pattern-matching&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-pattern-matching&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pattern matching is a common feature in functional languages. C# 7.0 introduces basic pattern matching, including constant value as pattern and type as pattern, and C# 7.1 supports generics in pattern matching.&lt;/p&gt;
&lt;h2&gt;Pattern matching with is expression&lt;/h2&gt;
&lt;p&gt;Before C# 7.0, is keyword is used in the instance is Type expression to test whether the instance is compatible with the specified type. Since C# 7.0, is can test constant pattern, including null, constant value, enumeration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class PatternMatching
{
    internal static void IsConstantValue(object @object)
    {
        // Type test:
        bool test1 = @object is string;
        // Constant pattern test:
        bool test5 = @object is null; // Compiled to: @object == null
        bool test6 = @object is default; // Compiled to: @object == null
        bool test2 = @object is int.MinValue; // Compiled to: object.Equals(int.MinValue, @object)
        bool test3 = @object is DayOfWeek.Monday; // Compiled to: object.Equals(DayOfWeek.Monday, @object)
        bool test4 = @object is &quot;test&quot;; // Compiled to: object.Equals(&quot;test&quot;, @object)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The is expressions for null test is simply compiled to null check. the other cases are compiled to object.Equal static method calls, where the constant value is the first argument, and the tested instance is the second argument. Internally, object.Equals first does a few checks, then it could call the first argument’s Equals instance method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [Serializable]
    public class Object
    {
        public static bool Equals(object objA, object objB) =&amp;gt;
            objA == objB || (objA != null &amp;amp;&amp;amp; objB != null &amp;amp;&amp;amp; objA.Equals(objB));

        public virtual bool Equals(object obj) =&amp;gt;
            RuntimeHelpers.Equals(this, obj);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The early versions of C# 7.0 compiler takes the tested instance as the first argument of object.Equals call, and the constant value as the second argument. This can have issues. In this way, the generated static object.Equals calls the tested instance’s Equals instance method. Since the tested instance can be any custom type, and its Equals instance method can be overridden with arbitrary custom implementation. In C# 7.0 GA release, this was &lt;a href=&quot;https://github.com/dotnet/roslyn/issues/16710&quot;&gt;fixed&lt;/a&gt; by having the constant value becomes the first argument of object.Equals, so that calling the constant value’s Equals instance method, which has more predictable behavior, could be called.&lt;/p&gt;
&lt;p&gt;The pattern can also be a type, followed by a pattern variable of that type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IsReferenceType(object @object)
{
    if (@object is Uri uri)
    {
        uri.AbsoluteUri.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type in above pattern is a reference type (class), so the is expression is compiled to as type conversion and null check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledIsReferenceType(object @object)
{
    Uri uri = @object as Uri;
    if (uri != null)
    {
        uri.AbsoluteUri.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This syntactic sugar also works for value type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IsValueType(object @object)
{
    if (@object is DateTime dateTime)
    {
        dateTime.ToString(&quot;o&quot;).WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The as operator cannot be used for value type. Type cast (ValueType)instance can work, but when the cast fails it throws exception. So pattern matching for value type is compiled to nullable value type conversion with as operator, and HasValue check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledIsValueType(object @object)
{
    DateTime? nullableDateTime = @object as DateTime?;
    DateTime dateTime = nullableDateTime.GetValueOrDefault();
    if (nullableDateTime.HasValue)
    {
        dateTime.ToString(&quot;o&quot;).WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is also common to use pattern matching with additional conditions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IsWithCondition(object @object)
{
    if (@object is string @string &amp;amp;&amp;amp; TimeSpan.TryParse(@string, out TimeSpan timeSpan))
    {
        timeSpan.TotalMilliseconds.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After compilation, the condition is additional to the null check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledIsWithCondition(object @object)
{
    string @string = @object as string;
    if (@string != null &amp;amp;&amp;amp; TimeSpan.TryParse(@string, out TimeSpan timeSpan))
    {
        timeSpan.TotalMilliseconds.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The previously discussed Data type override the Equals method of object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data : IEquatable&amp;lt;Data&amp;gt;
{
    public override bool Equals(object obj)
    {
        return obj is Data &amp;amp;&amp;amp; this.Equals((Data)obj);
    }

    public bool Equals(Data other) // Member of IEquatable&amp;lt;T&amp;gt;.
    {
        return this.value == other.value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the traditional syntax, the object parameter’s type was detected twice. In .NET Framework, the Code Analysis tool issues warning CA1800 for this: &apos;obj&apos;, a parameter, is cast to type &apos;Data&apos; multiple times in method &apos;Data.Equals(object)&apos;. Cache the result of the &apos;as&apos; operator or direct cast in order to eliminate the redundant castclass instruction. Now with the new syntax, this can be simplified as following without warning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data : IEquatable&amp;lt;Data&amp;gt;
{
    public override bool Equals(object obj) =&amp;gt; 
        obj is Data data &amp;amp;&amp;amp; this.Equals(data);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 7.1 supports generics open type in pattern matching:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OpenType&amp;lt;T1, T2&amp;gt;(object @object, T1 open1)
{
    if (@object is T1 open) { }
    if (open1 is Uri uri) { }
    if (open1 is T2 open2) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The var keyword can be the pattern of any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IsType(object @object)
{
    if (@object is var match)
    {
        object.ReferenceEquals(@object, match).WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the var pattern matching always works, it is compiled to true in debug build:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledIsAnyType(object @object)
{
    object match = @object;
    if (true)
    {
        object.ReferenceEquals(@object, match).WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In release build, the above if (true) test is simply removed.&lt;/p&gt;
&lt;h2&gt;Pattern matching with switch statement&lt;/h2&gt;
&lt;p&gt;Before C# 7.0, the switch statement only supports string, integral types (like bool, byte, char, int, long, etc.), and enumeration; and the case label only supports constant value. Since C# 7.0, switch supports any type and case label supports pattern matching for either constant value or type. The additional condition for the pattern matching can be specified with a when clause. The following example tries to convert object to DateTime:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DateTime ToDateTime(object @object)
{
    switch (@object)
    {
        // Match constant @object.
        case null:
            throw new ArgumentNullException(nameof(@object));
        // Match value type.
        case DateTime dateTIme:
            return dateTIme;
        // Match value type with condition.
        case long ticks when ticks &amp;gt;= 0:
            return new DateTime(ticks);
        // Match reference type with condition.
        case string @string when DateTime.TryParse(@string, out DateTime dateTime):
            return dateTime;
        // Match reference type with condition.
        case int[] date when date.Length == 3 &amp;amp;&amp;amp; date[0] &amp;gt; 0 &amp;amp;&amp;amp; date[1] &amp;gt; 0 &amp;amp;&amp;amp; date[2] &amp;gt; 0:
            return new DateTime(year: date[0], month: date[1], day: date[2]);
        // Match reference type.
        case IConvertible convertible:
            return convertible.ToDateTime(provider: null);
        case var _: // default:
            throw new ArgumentOutOfRangeException(nameof(@object));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last section with with any type pattern is equivalent to the default section, because it always matches. Each pattern matching is compiled in the similar ways as is expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DateTime CompiledToDateTime(object @object)
{
    // case null:
    if (@object == null)
    {
        throw new ArgumentNullException(&quot;@object&quot;);
    }

    // case DateTime dateTIme:
    DateTime? nullableDateTime = @object as DateTime?;
    DateTime dateTime = nullableDateTime.GetValueOrDefault();
    if (nullableDateTime.HasValue)
    {
        return dateTime;
    }

    // case long ticks
    long? nullableInt64 = @object as long?;
    long ticks = nullableInt64.GetValueOrDefault();
    // when ticks &amp;gt;= 0:
    if (nullableInt64.HasValue &amp;amp;&amp;amp; ticks &amp;gt;= 0L)
    {
        return new DateTime(ticks);
    }

    // case string text 
    string @string = @object as string;
    // when DateTime.TryParse(text, out DateTime dateTime):
    if (@string != null &amp;amp;&amp;amp; DateTime.TryParse(@string, out DateTime parsedDateTime))
    {
        return parsedDateTime;
    }

    // case int[] date
    int[] date = @object as int[];
    // when date.Length == 3 &amp;amp;&amp;amp; date[0] &amp;gt;= 0 &amp;amp;&amp;amp; date[1] &amp;gt;= 0 &amp;amp;&amp;amp; date[2] &amp;gt;= 0:
    if (date != null &amp;amp;&amp;amp; date.Length == 3 &amp;amp;&amp;amp; date[0] &amp;gt;= 0 &amp;amp;&amp;amp; date[1] &amp;gt;= 0 &amp;amp;&amp;amp; date[2] &amp;gt;= 0)
    {
        return new DateTime(date[0], date[1], date[2]);
    }

    // case IConvertible convertible:
    IConvertible convertible = @object as IConvertible;
    if (convertible != null)
    {
        return convertible.ToDateTime(null);
    }

    // case var _:
    // or
    // default:
    throw new ArgumentOutOfRangeException(&quot;@object&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (14) Asynchronous Function</title><link>https://dixin.github.io/posts/functional-csharp-asynchronous-function-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-asynchronous-function-7/</guid><description>Asynchronous function can improve the responsiveness and scalability of the application and service. C# 5.0 introduces async and await keywords to greatly simplify the async programming model.</description><pubDate>Thu, 14 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-asynchronous-function&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-asynchronous-function&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Asynchronous function can improve the responsiveness and scalability of the application and service. C# 5.0 introduces async and await keywords to greatly simplify the async programming model.&lt;/p&gt;
&lt;h2&gt;Task, Task&amp;lt;TResult&amp;gt; and asynchrony&lt;/h2&gt;
&lt;p&gt;In C#/.NET async programming model, System.Threading.Tasks.Task is provided to represent async operation returning void, and System.Threading.Tasks.Task&amp;lt;TResult&amp;gt; is provided to represents async operation returning TResult value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public partial class Task : IAsyncResult
    {
        public Task(Action action); // () –&amp;gt; void

        public void Start();

        public void Wait();

        public TaskStatus Status { get; } // Created, WaitingForActivation, WaitingToRun, Running, WaitingForChildrenToComplete, RanToCompletion, Canceled, Faulted.

        public bool IsCanceled { get; }

        public bool IsCompleted { get; }

        public bool IsFaulted { get; }

        public AggregateException Exception { get; }

        Task ContinueWith(Action&amp;lt;Task&amp;gt; continuationAction);

        Task&amp;lt;TResult&amp;gt; ContinueWith&amp;lt;TResult&amp;gt;(Func&amp;lt;Task, TResult&amp;gt; continuationFunction);

        // Other members.
    }

    public partial class Task&amp;lt;TResult&amp;gt; : Task
    {
        public Task(Func&amp;lt;TResult&amp;gt; function); // () –&amp;gt; TResult

        public TResult Result { get; }

        public Task ContinueWith(Action&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; continuationAction);

        public Task&amp;lt;TNewResult&amp;gt; ContinueWith&amp;lt;TNewResult&amp;gt;(Func&amp;lt;Task&amp;lt;TResult&amp;gt;, TNewResult&amp;gt; continuationFunction);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Task and Task&amp;lt;TResult&amp;gt; can be constructed with () –&amp;gt; void function and () –&amp;gt; TResult function, and can be started by calling the Start method. A task runs asynchronously, and does not block the current thread. Its status can be queried by the Status, IsCanceled, IsCompleted, IsFaulted properties. A task can be waited by calling its Wait method, which blocks the current thread until the task is completed successfully, or fails, or is cancelled. For Task&amp;lt;TResult&amp;gt;, when the underlying async operation is completed successfully, the result is available through Result property. For Task or Task&amp;lt;TResult&amp;gt;, the underlying async operation fails with exception, the exception is available through the Exception property. A task can be chained with another async continuation operation by calling the ContinueWith methods. When the task finishes running, the specified continuation starts running asynchronously. If the task already finishes running when its ContinueWith method is called, then the specified continuation immediately starts running. The following example constructs and starts a task to read a file, and chains another continuation task to write the contents to another file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void CreateTask(string readPath, string writePath)
    {
        Thread.CurrentThread.ManagedThreadId.WriteLine(); // 10
        Task&amp;lt;string&amp;gt; task = new Task&amp;lt;string&amp;gt;(() =&amp;gt;
        {
            Thread.CurrentThread.ManagedThreadId.WriteLine(); // 8
            return File.ReadAllText(readPath);
        });
        task.Start();
        Task continuationTask = task.ContinueWith(antecedentTask =&amp;gt;
        {
            Thread.CurrentThread.ManagedThreadId.WriteLine(); // 9
            object.ReferenceEquals(antecedentTask, task).WriteLine(); // True
            if (antecedentTask.IsFaulted)
            {
                antecedentTask.Exception.WriteLine();
            }
            else
            {
                File.WriteAllText(writePath, antecedentTask.Result);
            }
        });
        continuationTask.Wait();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As async operations, when tasks are started, the wrapped functions are by default scheduled to CLR/CoreCLR thread pool to execute, so that their thread ids are different from the caller thread id.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In .NET Framework, Task also implements System.Threading.IThreadPoolWorkItem and IDisposable interfaces. Its usage is the same as in .NET Core. Do not bother disposing tasks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Task also provides Run methods to construct and automatically start tasks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public partial class Task : IAsyncResult
    {
        public static Task Run(Action action);

        public static Task&amp;lt;TResult&amp;gt; Run&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; function);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now compare the following functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Write(string path, string contents) =&amp;gt; File.WriteAllText(path, contents);

internal static string Read(string path) =&amp;gt; File.ReadAllText(path);

internal static Task WriteAsync(string path, string contents) =&amp;gt; 
    Task.Run(() =&amp;gt; File.WriteAllText(path, contents));

internal static Task&amp;lt;string&amp;gt; ReadAsync(string path) =&amp;gt; Task.Run(() =&amp;gt; File.ReadAllText(path));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Write is called, its execution blocks the current thread. When the writing operation is done synchronously, it returns without result, and then the caller thread can continue execution. Similarly, when Read is called, its execution blocks the current thread too. When the reading operation is done synchronously, it returns the result, so that the result is available to the caller and the caller can continue execution. When WriteAsync is called, it calls Task.Run to construct a Task instance with the writing operation, start the task, then immediately returns the task. Then the caller can continue without being blocked by the writing operation execution. By default, the writing operation is scheduled to thread pool, when it is done, the writing operation return no result, and the task’s Status is updated. Similarly, when ReadAsync is called, it also calls Task.Run to construct a Task&amp;lt;string&amp;gt; instance with the reading operation, start the task, then immediately returns the task. Then the caller can continue without being blocked by the reading operation execution. By default, the reading operation is also scheduled to thread pool, when it is done, the reading operation has a result, and the task’s Status is updated, with the result available through the Result property.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallReadWrite(string path, string contents)
{
    Write(path, contents); // Blocking.
    // Sync operation is completed with no result.
    string result = Read(path); // Blocking.
    // Sync operation is completed with result available.

    Task writeTask = WriteAsync(path, contents); // Non blocking.
    // Async operation is scheduled to thread pool, and will be completed in the future with no result.
    Task&amp;lt;string&amp;gt; readTask = ReadAsync(path); // Non blocking.
    // Async operation is scheduled to thread pool, and will be completed in the future, then result will be available.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Write returning void and Read returning a result are sync functions. WriteAsync returning Task and ReadAsync returning Task&amp;lt;TResult&amp;gt; are async function, where Task can be viewed as future void, and Task&amp;lt;TResult&amp;gt; can be viewed as future TResult result. Here WriteAsync and ReadAsync become async by simply offloading the operations to thread pool. This is for demonstration purpose, and does not bring any scalability improvement. A better implementation will be discussed later.&lt;/p&gt;
&lt;h2&gt;Named async function&lt;/h2&gt;
&lt;p&gt;By default, named async function returns Task or Task&amp;lt;TResult&amp;gt;, and has a Async or AsyncTask postfix in the name as the convention. The following example is a file read and write workflow of sync function calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReadWrite(string readPath, string writePath)
{
    string contents = Read(readPath);
    Write(writePath, contents);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same logic can be implemented by calling the async version of functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task ReadWriteAsync(string readPath, string writePath)
{
    string contents = await ReadAsync(readPath);
    await WriteAsync(writePath, contents);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here await is used for each async function call, and the code structure remains the same as the sync workflow. When await keyword is used in function body, the async modifier is required for that function. Regarding the workflow returns no result, the async function returns Task (future void). This ReadWriteAsync function calls async functions, itself is also async function, since it has the async modifier and return Task. When ReadWriteAsync is called, it works the same way as ReadAsync and WriteAsync. it does not block its caller, and immediately returns a task to represent the scheduled read and write workflow.&lt;/p&gt;
&lt;p&gt;So the await keyword can be viewed as virtually waiting for the task’s underlying async operation to finish. If the task fails, exception is thrown. If the task is completed successfully, the continuation right after the await expression is called back. If the task has a result, await can extract the result. Therefore,, the async workflow keeps the same looking of sync workflow. There is no ContinueWith call needed to build the continuation. The following example is a more complex database query workflow of sync function calls, and a int value is returned as the query result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int Query(DbConnection connection, StreamWriter logWriter)
{
    try
    {
        connection.Open(); // Return void.
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = &quot;SELECT 1;&quot;;
            using (DbDataReader reader = command.ExecuteReader()) // Return DbDataReader.
            {
                if (reader.Read()) // Return bool.
                {
                    return (int)reader[0];
                }
                throw new InvalidOperationException(&quot;Failed to call sync functions.&quot;);
            }
        }
    }
    catch (SqlException exception)
    {
        logWriter.WriteLine(exception.ToString()); // Return void.
        throw new InvalidOperationException(&quot;Failed to call sync functions.&quot;, exception);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the DbConnection.Open, DbCommand.ExecuteReader, DbDataReader.Read, StreamWriter.WriteLine methods have async version provided as DbConnection.OpenAsync, DbCommand.ExecuteReaderAsync, DbDataReader.ReadAsync, StreamWriter.WriteLineAsync. They either return Task, or Task&amp;lt;TResult&amp;gt;. With the async and await keywords, it it easy to call these async functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task&amp;lt;int&amp;gt; QueryAsync(DbConnection connection, StreamWriter logWriter)
{
    try
    {
        await connection.OpenAsync(); // Return Task.
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = &quot;SELECT 1;&quot;;
            using (DbDataReader reader = await command.ExecuteReaderAsync()) // Return Task&amp;lt;DbDataReader&amp;gt;.
            {
                if (await reader.ReadAsync()) // Return Task&amp;lt;bool&amp;gt;.
                {
                    return (int)reader[0];
                }
                throw new InvalidOperationException(&quot;Failed to call async functions.&quot;);
            }
        }
    }
    catch (SqlException exception)
    {
        await logWriter.WriteLineAsync(exception.ToString()); // Return Task.
        throw new InvalidOperationException(&quot;Failed to call async functions.&quot;, exception);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the async workflow persists the same code structure as the sync workflow, the try-catch, using, if block look the same. Without this syntax, it is a lot more complex to call ContinueWith and manually build above workflow. Regarding the async function returns a int result, its return type is Task&amp;lt;int&amp;gt; (future int).&lt;/p&gt;
&lt;p&gt;The above Write and Read functions calls File.WriteAllText and File.ReadAllText to execute sync I/O operation, which are internally implemented by calling StreamWriter.Write and StreamReader.ReadToEnd. Now with the async and await keywords, WriteAsync and ReadAsync can be implemented as real async I/O (as long as the underlying operating system supports async I/O) by calling StreamWriter.WriteAsync and StreamReader.ReadToEndAsync:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task WriteAsync(string path, string contents)
{
    // File.WriteAllText:
    // using (StreamWriter writer = new StreamWriter(new FileStream(
    //    path: path, mode: FileMode.Create, access: FileAccess.Write,
    //    share: FileShare.Read, bufferSize: 4096, useAsync: false)))
    // {
    //    writer.Write(contents);
    // }
    using (StreamWriter writer = new StreamWriter(new FileStream(
        path: path, mode: FileMode.Create, access: FileAccess.Write,
        share: FileShare.Read, bufferSize: 4096, useAsync: true)))
    {
        await writer.WriteAsync(contents);
    }
}

internal static async Task&amp;lt;string&amp;gt; ReadAsync(string path)
{
    // File.ReadAllText:
    // using (StreamReader reader = new StreamReader(new FileStream(
    //    path: path, mode: FileMode.Open, access: FileAccess.Read, 
    //    share: FileShare.Read, bufferSize: 4096, useAsync: false)))
    // {
    //    return reader.ReadToEnd();
    // }
    using (StreamReader reader = new StreamReader(new FileStream(
        path: path, mode: FileMode.Open, access: FileAccess.Read, 
        share: FileShare.Read, bufferSize: 4096, useAsync: true)))
    {
        return await reader.ReadToEndAsync();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is one special scenario where async function has to return void instead of Task – async event handler. For example, ObservableCollection&amp;lt;T&amp;gt; has a CollectionChanged event:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.ObjectModel
{
    public class ObservableCollection&amp;lt;T&amp;gt; : Collection&amp;lt;T&amp;gt;, INotifyCollectionChanged, INotifyPropertyChanged
    {
        public event NotifyCollectionChangedEventHandler CollectionChanged;

        // Other members.
    }
}

namespace System.Collections.Specialized
{
    public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This event requires its handler to be a function of type (object, NotifyCollectionChangedEventArgs) –&amp;gt; void. So when defining an async function as the above event’s handler, that async function has to return void instead of Task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    private static StringBuilder logs = new StringBuilder();

    private static StringWriter logWriter = new StringWriter(logs);

    private static async void CollectionChangedAsync(object sender, NotifyCollectionChangedEventArgs e) =&amp;gt;
        await logWriter.WriteLineAsync(e.Action.ToString());

    internal static void EventHandler()
    {
        ObservableCollection&amp;lt;int&amp;gt; collection = new ObservableCollection&amp;lt;int&amp;gt;();
        collection.CollectionChanged += CollectionChangedAsync;
        collection.Add(1); // Fires CollectionChanged event.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides task returned by the async functions, the await keyword works with any Task and Task&amp;lt;TResult&amp;gt; instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task AwaitTasks(string path)
{
    // string contents = await ReadAsync(path);
    Task&amp;lt;string&amp;gt; task1 = ReadAsync(path);
    string contents = await task1;

    // await WriteAsync(path, contents);
    Task task2 = WriteAsync(path, contents);
    await task2;

    // await Task.Run(() =&amp;gt; { });
    Task task3 = Task.Run(() =&amp;gt; { });
    await task3;

    // int result = await Task.Run(() =&amp;gt; 0);
    Task&amp;lt;int&amp;gt; task4 = Task.Run(() =&amp;gt; 0);
    int result = await task4;

    // await Task.Delay(TimeSpan.FromSeconds(10));
    Task task5 = Task.Delay(TimeSpan.FromSeconds(10));
    await task5;

    // result = await Task.FromResult(result);
    Task&amp;lt;int&amp;gt; task6 = Task.FromResult(result);
    result = await task6;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a task is never started, it never finishes running. The code after its await expression is never called back:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task HotColdTasks(string path)
{
    Task hotTask = new Task(() =&amp;gt; { });
    hotTask.Start();
    await hotTask;
    hotTask.Status.WriteLine();

    Task coldTask = new Task(() =&amp;gt; { });
    await coldTask;
    coldTask.Status.WriteLine(); // Never executes.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Task not started yet is called cold task, and task already started is called hot task. As a convention, any function returning task should always return a hot task. All .NET APIs follow this convention.&lt;/p&gt;
&lt;h2&gt;Awaitable-awaiter pattern&lt;/h2&gt;
&lt;p&gt;C# compiles the await expression with the awaitable-awaiter pattern. Besides Task and Task&amp;lt;TResult&amp;gt;, the await keyword can be used with any awaitable type. A awaitable type has a GetAwaiter instance or extension method to return a awaiter. A awaiter type implements System.Runtime.CompilerServices.INotifyCompletion interface, also has a IsCompleted property returning a bool value, and a GetResult instance method returning either void or a result value. The following IAwaitable and IAwaiter interfaces demonstrate the awaitable-awaiter pattern for operations with no result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IAwaitable
{
    IAwaiter GetAwaiter();
}

public interface IAwaiter : INotifyCompletion
{
    bool IsCompleted { get; }

    void GetResult(); // No result.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following IAwaitable&amp;lt;TResult&amp;gt; and IAwaiter&amp;lt;TResult&amp;gt; interfaces demonstrate the awaitable-awaiter pattern for operations with a result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IAwaitable&amp;lt;TResult&amp;gt;
{
    IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();
}

public interface IAwaiter&amp;lt;TResult&amp;gt; : INotifyCompletion
{
    bool IsCompleted { get; }

    TResult GetResult(); // TResult result.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And INotifyCompletion interface has a single OnCompleted method to chain a continuation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Runtime.CompilerServices
{
    public interface INotifyCompletion
    {
        void OnCompleted(Action continuation);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is how Task and Task&amp;lt;TResult&amp;gt; implement the awaitable-awaiter pattern. Task can be virtually viewed as implementation of IAwaitable, it has a GetAwaiter instance method returning System.Runtime.CompilerServices.TaskAwaiter, which can be virtually viewed as implementation of IAwaiter; Similarly, Task&amp;lt;TResult&amp;gt; can be virtually viewed as implementation of IAwaitable&amp;lt;TResult&amp;gt;, it has a GetAwaiter method returning System.Runtime.CompilerServices.TaskAwaiter&amp;lt;TResult&amp;gt;, which can be virtually viewed as implementation of IAwaiter&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public partial class Task : IAsyncResult
    {
        public TaskAwaiter GetAwaiter();
    }

    public partial class Task&amp;lt;TResult&amp;gt; : Task
    {
        public TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();
    }
}

namespace System.Runtime.CompilerServices
{
    public struct TaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
    {
        public bool IsCompleted { get; }

        public void GetResult(); // No result.

        public void OnCompleted(Action continuation);

        // Other members.
    }

    public struct TaskAwaiter&amp;lt;TResult&amp;gt; : ICriticalNotifyCompletion, INotifyCompletion
    {
        public bool IsCompleted { get; }

        public TResult GetResult(); // TResult result.

        public void OnCompleted(Action continuation);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Any other type can be used with the await keyword, as long as the awaitable-awaiter pattern is implemented. Take Action as example, a GetAwaiter method can be easily implemented as an extension method, by reusing above TaskAwaiter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ActionExtensions
{
    public static TaskAwaiter GetAwaiter(this Action action) =&amp;gt; Task.Run(action).GetAwaiter();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, this pattern can be implemented for Func&amp;lt;TResult&amp;gt;, by reusing TaskAwaiter&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function) =&amp;gt;
        Task.Run(function).GetAwaiter();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the await keyword can be used with a function directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task AwaitFunctions(string readPath, string writePath)
{
    Func&amp;lt;string&amp;gt; read = () =&amp;gt; File.ReadAllText(readPath);
    string contents = await read;

    Action write = () =&amp;gt; File.WriteAllText(writePath, contents);
    await write;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Async state machine&lt;/h2&gt;
&lt;p&gt;As fore mentioned, with async and await keywords, an async function is non blocking. At compile time, the workflow of an async function is compiled to an async state machine. At runtime, when this async function is called, it just starts that async state machine generated by compiler, and immediately returns a task representing the workflow in the async state machine. To demonstrate this, define the following async methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task&amp;lt;T&amp;gt; Async&amp;lt;T&amp;gt;(T value)
{
    T value1 = Start(value);
    T result1 = await Async1(value1);
    T value2 = Continuation1(result1);
    T result2 = await Async2(value2);
    T value3 = Continuation2(result2);
    T result3 = await Async3(value3);
    T result = Continuation3(result3);
    return result;
}

internal static T Start&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async1&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.Run(() =&amp;gt; value);

internal static T Continuation1&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async2&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.FromResult(value);

internal static T Continuation2&amp;lt;T&amp;gt;(T value) =&amp;gt; value;

internal static Task&amp;lt;T&amp;gt; Async3&amp;lt;T&amp;gt;(T value) =&amp;gt; Task.Run(() =&amp;gt; value);

internal static T Continuation3&amp;lt;T&amp;gt;(T value) =&amp;gt; value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After compilation, the async modifier is gone. The async function becomes a normal function to start a async state machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[AsyncStateMachine(typeof(AsyncStateMachine&amp;lt;&amp;gt;))]
internal static Task&amp;lt;T&amp;gt; CompiledAsync&amp;lt;T&amp;gt;(T value)
{
    AsyncStateMachine&amp;lt;T&amp;gt; asyncStateMachine = new AsyncStateMachine&amp;lt;T&amp;gt;()
    {
        Value = value,
        Builder = AsyncTaskMethodBuilder&amp;lt;T&amp;gt;.Create(),
        State = -1 // -1 means start.
    };
    asyncStateMachine.Builder.Start(ref asyncStateMachine);
    return asyncStateMachine.Builder.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the generated async state machine is a structure in release build, and a class in debug build:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
private struct AsyncStateMachine&amp;lt;TResult&amp;gt; : IAsyncStateMachine
{
    public int State;

    public AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; Builder;

    public TResult Value;

    private TaskAwaiter&amp;lt;TResult&amp;gt; awaiter;

    void IAsyncStateMachine.MoveNext()
    {
        TResult result;
        try
        {
            switch (this.State)
            {
                case -1: // Start code from the beginning to the 1st await.
                    // Workflow begins.
                    TResult value1 = Start(this.Value);
                    this.awaiter = Async1(value1).GetAwaiter();
                    if (this.awaiter.IsCompleted)
                    {
                        // If the task returned by Async1 is already completed, immediately execute the continuation.
                        goto case 0;
                    }
                    else
                    {
                        this.State = 0;
                        // If the task returned by Async1 is not completed, specify the continuation as its callback.
                        this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
                        // Later when the task returned by Async1 is completed, it calls back MoveNext, where State is 0.
                        return;
                    }
                case 0: // Continuation code from after the 1st await to the 2nd await.
                    // The task returned by Async1 is completed. The result is available immediately through GetResult.
                    TResult result1 = this.awaiter.GetResult();
                    TResult value2 = Continuation1(result1);
                    this.awaiter = Async2(value2).GetAwaiter();
                    if (this.awaiter.IsCompleted)
                    {
                        // If the task returned by Async2 is already completed, immediately execute the continuation.
                        goto case 1;
                    }
                    else
                    {
                        this.State = 1;
                        // If the task returned by Async2 is not completed, specify the continuation as its callback.
                        this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
                        // Later when the task returned by Async2 is completed, it calls back MoveNext, where State is 1.
                        return;
                    }
                case 1: // Continuation code from after the 2nd await to the 3rd await.
                    // The task returned by Async2 is completed. The result is available immediately through GetResult.
                    TResult result2 = this.awaiter.GetResult();
                    TResult value3 = Continuation2(result2);
                    this.awaiter = Async3(value3).GetAwaiter();
                    if (this.awaiter.IsCompleted)
                    {
                        // If the task returned by Async3 is already completed, immediately execute the continuation.
                        goto case 2;
                    }
                    else
                    {
                        this.State = 2;
                        // If the task returned by Async3 is not completed, specify the continuation as its callback.
                        this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
                        // Later when the task returned by Async3 is completed, it calls back MoveNext, where State is 1.
                        return;
                    }
                case 2: // Continuation code from after the 3rd await to the end.
                    // The task returned by Async3 is completed. The result is available immediately through GetResult.
                    TResult result3 = this.awaiter.GetResult();
                    result = Continuation3(result3);
                    this.State = -2; // -2 means end.
                    this.Builder.SetResult(result);
                    // Workflow ends.
                    return;
            }
        }
        catch (Exception exception)
        {
            this.State = -2; // -2 means end.
            this.Builder.SetException(exception);
        }
    }

    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine asyncStateMachine) =&amp;gt;
        this.Builder.SetStateMachine(asyncStateMachine);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated async state machine is a finite state machine:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-14-Asy_86AA/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-14-Asy_86AA/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The workflow is compiled into its MoveNext method, and the workflow is split to 4 blocks by the 3 await keywords. The parameter of the workflow is compiled as a field of the state machine, so that is can be accessed by the workflow inside MoveNext. When the state machine is initialized, its initial state is –1, which means start. Once the state machine is started, MoveNext is called, and the case –1 block is executed, which has the code from the beginning of the workflow to the first await expression, which is compiled to a GetAwaiter call. If the awaiter is already completed, then the continuation should immediate be executed, so the next case 0 block is executed; If the awaiter is not completed, the continuation (MoveNext call with next state 0) is specified as the awaiter’s callback when it is completed in the future. In either case, when code in case 0 block is executed, the previous awaiter is already completed, and its result is immediately available through its GetResult method. The execution goes on in the same pattern, until the last block of case 2 is executed.&lt;/p&gt;
&lt;h2&gt;Runtime context capture&lt;/h2&gt;
&lt;p&gt;For each await expression, if the awaited task is not completed yet, the continuation is scheduled as callback when it is completed. As a result, the continuation can be executed by a thread different from initial caller thread. By default, the initial thread’s runtime context information are captured, and are reused by the to execute the continuation. To demonstrate this, the above awaitable-awaiter pattern for Action can be re-implemented with with custom awaiter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ActionExtensions
{
    public static IAwaiter GetAwaiter(this Action action) =&amp;gt; new ActionAwaiter(Task.Run(action));
}

public class ActionAwaiter : IAwaiter
{
    private readonly (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext =
        RuntimeContext.Capture();

    private readonly Task task;

    public ActionAwaiter(Task task) =&amp;gt; this.task = task;

    public bool IsCompleted =&amp;gt; this.task.IsCompleted;

    public void GetResult() =&amp;gt; this.task.Wait();

    public void OnCompleted(Action continuation) =&amp;gt; this.task.ContinueWith(task =&amp;gt;
        this.runtimeContext.Execute(continuation));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the awaiter is constructed, it captures the runtime context information, including System.Threading.SynchronizationContext, System.Threading.Tasks.TaskScheduler, and System.Threading.ExecutionContext of current thread. Then in OnCompleted, when the continuation is called back, it is executed with the previously captured runtime context information. The custom awaiter can be implemented for Func&amp;lt;TResult&amp;gt; in the same pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function) =&amp;gt;
        new FuncAwaiter&amp;lt;TResult&amp;gt;(Task.Run(function));
}

public class FuncAwaiter&amp;lt;TResult&amp;gt; : IAwaiter&amp;lt;TResult&amp;gt;
{
    private readonly (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext =
        RuntimeContext.Capture();

    private readonly Task&amp;lt;TResult&amp;gt; task;

    public FuncAwaiter(Task&amp;lt;TResult&amp;gt; task) =&amp;gt; this.task = task;

    public bool IsCompleted =&amp;gt; this.task.IsCompleted;

    public TResult GetResult() =&amp;gt; this.task.Result;

    public void OnCompleted(Action continuation) =&amp;gt; this.task.ContinueWith(task =&amp;gt;
        this.runtimeContext.Execute(continuation));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is a basic implementation of runtime context capture and resume:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class RuntimeContext
{
    public static (SynchronizationContext, TaskScheduler, ExecutionContext) Capture() =&amp;gt;
        (SynchronizationContext.Current, TaskScheduler.Current, ExecutionContext.Capture());

    public static void Execute(
        this (SynchronizationContext, TaskScheduler, ExecutionContext) runtimeContext, Action continuation)
    {
        var (synchronizationContext, taskScheduler, executionContext) = runtimeContext;
        if (synchronizationContext != null &amp;amp;&amp;amp; synchronizationContext.GetType() != typeof(SynchronizationContext))
        {
            if (synchronizationContext == SynchronizationContext.Current)
            {
                executionContext.Run(continuation);
            }
            else
            {
                executionContext.Run(() =&amp;gt; synchronizationContext.Post(
                    d: state =&amp;gt; continuation(), state: null));
            }
            return;
        }
        if (taskScheduler != null &amp;amp;&amp;amp; taskScheduler != TaskScheduler.Default)
        {
            Task continuationTask = new Task(continuation);
            continuationTask.Start(taskScheduler);
            return;
        }
        executionContext.Run(continuation);
    }

    public static void Run(this ExecutionContext executionContext, Action continuation)
    {
        if (executionContext != null)
        {
            ExecutionContext.Run(
                executionContext: executionContext, 
                callback: executionContextState =&amp;gt; continuation(), 
                state: null);
        }
        else
        {
            continuation();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the continuation is executed, first the previously captured SynchronizationContext is checked. If a specialized SynchronizationContext is captured and it is different from current SynchronizationContext, then the continuation is executed with the captured SynchronizationContext and ExecutionContext. When there is no specialized SynchronizationContext captured, then the TaskScheduler is checked. If a specialized TaskScheduler is captured, it is used to schedule the continuation as a task. For all the other cases, the continuation is executed with the captured ExecutionContext.&lt;/p&gt;
&lt;p&gt;Task and Task&amp;lt;TResult&amp;gt; provides a ConfigureAwait method to specify whether the continuation is marshaled to the previously captured runtime context:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public partial class Task : IAsyncResult
    {
        public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext);
    }

    public partial class Task&amp;lt;TResult&amp;gt; : Task
    {
        public ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt; ConfigureAwait(bool continueOnCapturedContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To demonstrate the runtime context capture, define a custom task scheduler, which simply start a background thread to execute each task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class BackgroundThreadTaskScheduler : TaskScheduler
{
    protected override IEnumerable&amp;lt;Task&amp;gt; GetScheduledTasks() =&amp;gt; throw new NotImplementedException();

    protected override void QueueTask(Task task) =&amp;gt;
        new Thread(() =&amp;gt; this.TryExecuteTask(task)) { IsBackground = true }.Start();

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) =&amp;gt;
        this.TryExecuteTask(task);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following async function has 2 await expressions, where ConfigureAwait is called with different bool values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task ConfigureRuntimeContextCapture(string readPath, string writePath)
{
    TaskScheduler taskScheduler1 = TaskScheduler.Current;
    string contents = await ReadAsync(readPath).ConfigureAwait(continueOnCapturedContext: true);
    // Equivalent to: await ReadAsync(readPath);

    // Continuation is executed with captured runtime context.
    TaskScheduler taskScheduler2 = TaskScheduler.Current;
    object.ReferenceEquals(taskScheduler1, taskScheduler2).WriteLine(); // True
    await WriteAsync(writePath, contents).ConfigureAwait(continueOnCapturedContext: false);

    // Continuation is executed without captured runtime context.
    TaskScheduler taskScheduler3 = TaskScheduler.Current;
    object.ReferenceEquals(taskScheduler1, taskScheduler3).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To demonstrate the task scheduler capture, call the above async function by specifying the custom task scheduler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task CallConfigureContextCapture(string readPath, string writePath)
{
    Task&amp;lt;Task&amp;gt; task = new Task&amp;lt;Task&amp;gt;(() =&amp;gt; ConfigureRuntimeContextCapture(readPath, writePath));
    task.Start(new BackgroundThreadTaskScheduler());
    await task.Unwrap(); // Equivalent to: await await task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here since async function ConfigureRuntimeContextCapture returns Task, so the task constructed with async function is of type Task&amp;lt;Task&amp;gt;. A Unwrap extension method is provided for Task&amp;lt;Task&amp;gt; to convert it to normal Task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public static class TaskExtensions
    {
        public static Task Unwrap(this Task&amp;lt;Task&amp;gt; task);

        public static Task&amp;lt;TResult&amp;gt; Unwrap&amp;lt;TResult&amp;gt;(this Task&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; task);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When async function ConfigureRuntimeContextCapture is executed, its initial task scheduler is the specified custom task scheduler. In the first await expression, ConfigureAwait is called with true, so that the runtime context information is captured and the continuation is executed with the captured runtime context information. This is the default behavior, so calling ConfigureAwait with true is equal to not calling ConfigureAwait at all. As a result, the first continuation is executed with the same custom task scheduler. In the second await expression, ConfigureAwait is called with false, so the runtime context information is not captured. As a result, the second continuation is executed with the default task scheduler (System.Threading.Tasks.ThreadPoolTaskScheduler).&lt;/p&gt;
&lt;p&gt;The runtime context capture can be also demonstrated by SynchronizationContext. &lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/gg598924.aspx&quot;&gt;SynchronizationContext has different implementations&lt;/a&gt; in different application models, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ASP.NET: System.Web.&lt;a href=&quot;http://referencesource.microsoft.com/#System.Web/AspNetSynchronizationContext.cs&quot;&gt;AspNetSynchronizationContext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WPF: System.Windows.Threading.&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchersynchronizationcontext.aspx&quot;&gt;DispatcherSynchronizationContext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WinForms: System.Windows.Forms.&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.forms.windowsformssynchronizationcontext.aspx&quot;&gt;WindowsFormsSynchronizationContext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WinRT and Windows Universal: System.Threading.WinRTSynchronizationContext&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take Windows Universal application as example. In Visual Studio, create a Windows Universal application, add a button to its UI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Button x:Name=&quot;Button&quot; Content=&quot;Button&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Click=&quot;ButtonClick&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the code behind, implement the Click event handler as a async function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private async void ButtonClick(object sender, RoutedEventArgs e)
{
    SynchronizationContext synchronizationContext1 = SynchronizationContext.Current;
    ExecutionContext executionContext1 = ExecutionContext.Capture();
    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(continueOnCapturedContext: true);
    // Equivalent to: await Task.Delay(TimeSpan.FromSeconds(1));
            
    // Continuation is executed with captured runtime context.
    SynchronizationContext synchronizationContext2 = SynchronizationContext.Current;
    Debug.WriteLine(synchronizationContext1 == synchronizationContext2); // True
    this.Button.Background = new SolidColorBrush(Colors.Blue); // UI update works.
    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(continueOnCapturedContext: false);
            
    // Continuation is executed without captured runtime context.
    SynchronizationContext synchronizationContext3 = SynchronizationContext.Current;
    Debug.WriteLine(synchronizationContext1 == synchronizationContext3); // False
    this.Button.Background = new SolidColorBrush(Colors.Yellow); // UI update fails.
    // Exception: The application called an interface that was marshalled for a different thread.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The WinRTSynchronizationContext is only available for the UI thread. When the button is clicked, the UI thread executes the async function ButtonClick, so the initial SynchronizationContext is WinRTSynchronizationContext. Similar to the previous example, when ConfigureAwait is called with true, the continuation is executed with the previously captured WinRTSynchronizationContext, so the continuation can update the UI successfully. When ConfigureAwait is called with true, the continuation is not executed with the WinRTSynchronizationContext, and it fails to update the UI and throws exception.&lt;/p&gt;
&lt;h2&gt;Generalized async return type and async method builder&lt;/h2&gt;
&lt;p&gt;Since C# 7, async function is supported to return any awaitable type, as long as it has a async method builder specified. For example, the following FuncAwaitable&amp;lt;TResult&amp;gt; is an awaitable type, it reuses above FuncAwater&amp;lt;TResult&amp;gt; as its awaiter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[AsyncMethodBuilder(typeof(AsyncFuncAwaitableMethodBuilder&amp;lt;&amp;gt;))]
public class FuncAwaitable&amp;lt;TResult&amp;gt; : IAwaitable&amp;lt;TResult&amp;gt;
{
    private readonly Func&amp;lt;TResult&amp;gt; function;

    public FuncAwaitable(Func&amp;lt;TResult&amp;gt; function) =&amp;gt; this.function = function;

    public IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter() =&amp;gt; new FuncAwaiter&amp;lt;TResult&amp;gt;(Task.Run(this.function));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Func&amp;lt;TResult&amp;gt; is already awaitable with the above GetAwaiter extension method, but here such a wrapper type is implemented, so that a async method builder can be specified for it, with a [AsyncMethodBuilder] attribute. The async method builder is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;
{
    private AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; taskMethodBuilder;

    private TResult result;

    private bool hasResult;

    private bool useBuilder;

    public static AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt; Create() =&amp;gt;
        new AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;()
        {
            taskMethodBuilder = AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt;.Create()
        };

    public void Start&amp;lt;TStateMachine&amp;gt;(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =&amp;gt;
        this.taskMethodBuilder.Start(ref stateMachine);

    public void SetStateMachine(IAsyncStateMachine stateMachine) =&amp;gt;
        this.taskMethodBuilder.SetStateMachine(stateMachine);

    public void SetResult(TResult result)
    {
        if (this.useBuilder)
        {
            this.taskMethodBuilder.SetResult(result);
        }
        else
        {
            this.result = result;
            this.hasResult = true;
        }
    }

    public void SetException(Exception exception) =&amp;gt; this.taskMethodBuilder.SetException(exception);

    public FuncAwaitable&amp;lt;TResult&amp;gt; Task
    {
        get
        {
            if (this.hasResult)
            {
                TResult result = this.result;
                return new FuncAwaitable&amp;lt;TResult&amp;gt;(() =&amp;gt; result);
            }
            else
            {
                this.useBuilder = true;
                Task&amp;lt;TResult&amp;gt; task = this.taskMethodBuilder.Task;
                return new FuncAwaitable&amp;lt;TResult&amp;gt;(() =&amp;gt; task.Result);
            }
        }
    }

    public void AwaitOnCompleted&amp;lt;TAwaiter, TStateMachine&amp;gt;(ref TAwaiter awaiter, ref TStateMachine stateMachine)
        where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
    {
        this.useBuilder = true;
        this.taskMethodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
    }

    public void AwaitUnsafeOnCompleted&amp;lt;TAwaiter, TStateMachine&amp;gt;(
        ref TAwaiter awaiter, ref TStateMachine stateMachine)
        where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
    {
        this.useBuilder = true;
        this.taskMethodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the FuncAwitable&amp;lt;TResult&amp;gt; type can be returned by async function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async FuncAwaitable&amp;lt;T&amp;gt; ReturnFuncAwaitable&amp;lt;T&amp;gt;(T value)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    return value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its compilation is in the same pattern as async function returning task. The only difference is, in the generated async state machine, the builder field become the specified AsyncFuncAwaitableMethodBuilder&amp;lt;TResult&amp;gt;, instead of the AsyncTaskMethodBuilder&amp;lt;TResult&amp;gt; for task. And apparently, this async function can be called in the await expression since it returns awaitable type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task CallReturnFuncAwaitable&amp;lt;T&amp;gt;(T value)
{
    T result = await ReturnFuncAwaitable(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ValueTask&amp;lt;TResult&amp;gt; and performance&lt;/h3&gt;
&lt;p&gt;With the generalized async return type support, Microsoft also provides a System.Threading.Tasks.ValueTask&amp;lt;TResult&amp;gt; awaitable structure in the System.Threading.Tasks.Extensions NuGet package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    [AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder&amp;lt;&amp;gt;))]
    [StructLayout(LayoutKind.Auto)]
    public struct ValueTask&amp;lt;TResult&amp;gt; : IEquatable&amp;lt;ValueTask&amp;lt;TResult&amp;gt;&amp;gt;
    {
        public ValueTask(TResult result);

        public ValueTask(Task&amp;lt;TResult&amp;gt; task);

        public ValueTaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its awaiter is System.Threading.Tasks.ValueTaskAwaiter&amp;lt;TResult&amp;gt;, and its async method builder is specified as System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder&amp;lt;TResult&amp;gt;, which are provided in the same package. As a value type, ValueTask&amp;lt;TResult&amp;gt; is cheaper to allocate then reference type Task&amp;lt;TResult&amp;gt;. Also, unlike Task&amp;lt;TResult&amp;gt; as a wrapper of Func&amp;lt;TResult&amp;gt; operation, ValueTask&amp;lt;TResult&amp;gt; can be a wrapper of either Func&amp;lt;TResult&amp;gt; operation, or TResult result which is already available. So ValueTask&amp;lt;TResult&amp;gt; can improve the performance for async function that may have result available before awaiting any async operation. The following example downloads data from the specified URI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Dictionary&amp;lt;string, byte[]&amp;gt; cache = 
    new Dictionary&amp;lt;string, byte[]&amp;gt;(StringComparer.OrdinalIgnoreCase);

internal static async Task&amp;lt;byte[]&amp;gt; DownloadAsyncTask(string uri)
{
    if (cache.TryGetValue(uri, out byte[] cachedResult))
    {
        return cachedResult;
    }
    using (HttpClient httpClient = new HttpClient())
    {
        byte[] result = await httpClient.GetByteArrayAsync(uri);
        cache.Add(uri, result);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It first checks the cache, if the data is already cached for the specified URI, then it returns the cached data without executing any async operation. However, at compile time, since the function has the async modifier, the entire workflow becomes a async state machine. At runtime, a task is always allocated in the managed heap and should be garbage collected, and the async state machine is always executed, even when the result is available in the cache and no async operation is needed. With ValueTask&amp;lt;TResult&amp;gt;, this can be easily optimized:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static ValueTask&amp;lt;byte[]&amp;gt; DownloadAsyncValueTask(string uri)
{
    return cache.TryGetValue(uri, out byte[] cachedResult)
        ? new ValueTask&amp;lt;byte[]&amp;gt;(cachedResult)
        : new ValueTask&amp;lt;byte[]&amp;gt;(DownloadAsync());

    async Task&amp;lt;byte[]&amp;gt; DownloadAsync()
    {
        using (HttpClient httpClient = new HttpClient())
        {
            byte[] result = await httpClient.GetByteArrayAsync(uri);
            cache.Add(uri, result);
            return result;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the function becomes a sync function returning ValueTask&amp;lt;TResult&amp;gt;, which is awaitable. When the result is available in the cache, there is no async operation or async state machine involved, and there is no task allocated in managed heap. The async operation is encapsulated in the async local function, which is compiled to async state machine, and is only involved when the result is not available in the cache. As a result, the performance can be improved, especially when the cache is hit frequently. In practice, please benchmark the performance to decide which pattern to use.&lt;/p&gt;
&lt;h2&gt;Anonymous async function&lt;/h2&gt;
&lt;p&gt;The async and await keywords can be used with the lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task AsyncLambda(string readPath, string writePath)
{
    Func&amp;lt;string, Task&amp;lt;string&amp;gt;&amp;gt; readAsync = async (path) =&amp;gt;
    {
        using (StreamReader reader = new StreamReader(new FileStream(
            path: path, mode: FileMode.Open, access: FileAccess.Read,
            share: FileShare.Read, bufferSize: 4096, useAsync: true)))
        {
            return await reader.ReadToEndAsync();
        }
    };
    Func&amp;lt;string, string, Task&amp;gt; writeAsync = async (path, contents) =&amp;gt;
    {
        using (StreamWriter writer = new StreamWriter(new FileStream(
            path: path, mode: FileMode.Create, access: FileAccess.Write,
            share: FileShare.Read, bufferSize: 4096, useAsync: true)))
        {
            await writer.WriteAsync(contents);
        }
    };

    string result = await readAsync(readPath);
    await writeAsync(writePath, result); 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here these 2 async lambda expressions are compiled as display class methods, in the same pattern as normal sync lambda expressions.&lt;/p&gt;
&lt;p&gt;Since task can be constructed with anonymous function returning any type, it can be constructed with async anonymous function returning task too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task AsyncAnonymous(string readPath, string writePath)
{
    Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt; task1 = new Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt;(async () =&amp;gt; await ReadAsync(readPath));
    task1.Start(); // Cold task needs to be started.
    string contents = await task1.Unwrap(); // Equivalent to: string contents = await await task1;

    Task&amp;lt;Task&amp;gt; task2 = new Task&amp;lt;Task&amp;gt;(async () =&amp;gt; await WriteAsync(writePath, null));
    task2.Start(); // Cold task needs to be started.
    await task2.Unwrap(); // Equivalent to: await await task2;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first task is constructed with async anonymous function of type () –&amp;gt; Task&amp;lt;string&amp;gt;, so the constructed task is of type Task&amp;lt;Task&amp;lt;string&amp;gt;&amp;gt;. Similarly, the second task is constructed with async anonymous function of type () –&amp;gt; Task, so the constructed task is of type Task&amp;lt;Task&amp;gt;. As fore mentioned, nested task can be unwrapped and awaited. For this scenario, overloads of Task.Run are provided to accept async functions and automatically unwrap the nested task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading.Tasks
{
    public partial class Task : IAsyncResult
    {
        public static Task Run(Func&amp;lt;Task&amp;gt; function);

        public static Task&amp;lt;TResult&amp;gt; Run&amp;lt;TResult&amp;gt;(Func&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; function);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example now can be simplified as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task RunAsync(string readPath, string writePath)
{
    Task&amp;lt;string&amp;gt; task1 = Task.Run(async () =&amp;gt; await ReadAsync(readPath)); // Automatically unwrapped.
    string contents = await task1; // Task.Run returns hot task..

    Task task2 = Task.Run(async () =&amp;gt; await WriteAsync(writePath, contents)); // Automatically unwrapped.
    await task2; // Task.Run returns hot task.
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (13) Pure Function</title><link>https://dixin.github.io/posts/functional-csharp-pure-function-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-pure-function-7/</guid><description>Functional programming encourages modeling operations with pure functions.</description><pubDate>Wed, 13 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-pure-function&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-pure-function&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Functional programming encourages modeling operations with pure functions.&lt;/p&gt;
&lt;h2&gt;Referential transparency and side effect free&lt;/h2&gt;
&lt;p&gt;A function is &lt;a href=&quot;http://en.wikipedia.org/wiki/Pure_function&quot;&gt;pure&lt;/a&gt; if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It gives the same output when given the same input. In another word, the function is &lt;a href=&quot;https://en.wikipedia.org/wiki/Purely_functional&quot;&gt;referentially transparent&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It does not have obvious interaction with the caller function or the outside world, in another word, the function has no &lt;a href=&quot;http://en.wikipedia.org/wiki/Side_effect_(computer_science)&quot;&gt;side effect&lt;/a&gt;. Here are some examples of side effect:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Changing state, like data mutation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Changing arguments, outer variable, or global variable&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Producing I/O&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So pure function is like mathematics function, which is is a simple relation between a set of input and a set of output, where each certain input is mapped to certain output. For example, the following functions are not referentially transparent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Console.Read, Console.ReadLine, Console.ReadKey: gives unpredictable output when called each time&lt;/li&gt;
&lt;li&gt;Random.Next, Guid.NewGuid: gives random output when called each time&lt;/li&gt;
&lt;li&gt;DateTime.Now, DateTimeOffset.Now: gives different output when called at different time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the following functions have side effects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MutableDevice.Name’s setter, MutableDevice.Price’s setter in previous part: property setter usually changes state and interact with system.&lt;/li&gt;
&lt;li&gt;In System.Threading namespace, Thread.Start, Thread.Abort: changes state&lt;/li&gt;
&lt;li&gt;int.TryParse, Interlocked.Increase, and any method changes the ref/out argument&lt;/li&gt;
&lt;li&gt;In System.Windows namespace, Application.SetExitCode: internally changes global variable Environment.ExitCode&lt;/li&gt;
&lt;li&gt;Console.Read, Console.ReadLine, Console.ReadKey, Console.Write, Console.Write, Console.WriteLine: produces console I/O&lt;/li&gt;
&lt;li&gt;In System.IO namespace, Directory.Create, Directory.Move, Directory.Delete, File.Create, File.Move, File.Delete, File.ReadAllBytes, File.WriteAllBytes: produces file system I/O&lt;/li&gt;
&lt;li&gt;In System.Net namespace, WebRequest.GetRequestStreamAsync, WebRequest.GetResponseAsync, and in System.Net.Http namespace, HttpClient.GetAsync, HttpClient.PostAsync, HttpClinet.PutAsync, HttpClient.DeleteAsync: produces network I/O&lt;/li&gt;
&lt;li&gt;IDisposable.Dispose: changes state to release unmanaged resources&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Strictly speaking, any function can interact with the outside world. Usually, a function call can at least make the hardware work, which consumes electric energy, and heats the world. Here when identifying function’s purity, only explicit interactions are considered.&lt;/p&gt;
&lt;p&gt;In contrast, the following functions are pure because they are both referentially transparent and side effect free:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Most mathematics functions, like decimal’s arithmetic operators, most of System.Math type’s static methods, etc. Take Math.Max and Math.Min as examples, their computed output only depends on the input, and they are residential transparency, they also produce no side effect, like state change, argument change, global variable change, I/O, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public static class Math
    {
        public static int Max(int val1, int val2) =&amp;gt; (val1 &amp;gt;= val2) ? val1 : val2;

        public static int Min(int val1, int val2) =&amp;gt; (val1 &amp;lt;= val2) ? val1 : val2;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;string.Concat, string.Substring, string.Insert, string.Replace, string.Trim, string.ToUpper, string.ToLower: accepts one or more strings as input, and output a new string, since string is immutable type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;string.Length, Nullable&amp;lt;T&amp;gt;.HasValue, Console.Error, or any property getter return a state. MutableDevice.Name’s getter and MutableDevice.Price’s getter are also pure. For a certain MutableDevice object, they return a predictable state, and during the getters’ execution, the getters do not change the state, or produce other side effect.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;object’s methods, like GetHashCode, GetType, Equals, ReferenceEquals, ToString&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System.Convert type’ conversion methods, like ToBoolean, ToInt32, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pure function has many benefits, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it does not involve state change, which is a major source of code issues.&lt;/li&gt;
&lt;li&gt;It is self contained, with greatly improves testability and maintainability.&lt;/li&gt;
&lt;li&gt;If 2 pure function calls have no data dependency, the order the function calls does not matter, which greatly simplifies parallel computing, like Parallel LINQ.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As fore mentioned, there is also a specialized functional programming paradigm, called purely functional programming, where all operations are modeled as pure function calls. As a result, only immutable values and immutable data structures are allowed too. A few languages, like Haskell, are designed for this paradigm. In Haskell manages I/O with Monad, which is covered in the category theory chapter. The other functional languages, like C# and F#, are called impure functional language.&lt;/p&gt;
&lt;h2&gt;PureAttribute and Code Contracts&lt;/h2&gt;
&lt;p&gt;.NET provides &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.pureattribute.aspx&quot;&gt;System.Diagnostics.Contracts.PureAttribute&lt;/a&gt; to specify a named function member is pure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Purity
{
    [Pure]
    internal static bool IsPositive(int int32) =&amp;gt; int32 &amp;gt; 0;

    internal static bool IsNegative(int int32) // Impure.
    {
        Console.WriteLine(int32.WriteLine()); // Side effect: console I/O.
        return int32 &amp;lt; 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can also be used for a type, to specify all its function members are pure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
internal static class Pure
{
    internal static int Increase(int int32) =&amp;gt; int32 + 1;

    internal static int Decrease(int int32) =&amp;gt; int32 - 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, this attribute is not for general purpose and is only used by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd264808.aspx&quot;&gt;.NET Code Contracts&lt;/a&gt;. Code Contracts is a Microsoft tool for .NET Framework. It consist of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code contract APIs under &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.aspx&quot;&gt;System.Diagnostics.Contracts namespace&lt;/a&gt; to specify preconditions, post conditions, invariant, purity, etc., including the above &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.pureattribute.aspx&quot;&gt;PureAttribute&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Contracts assemblies for some .NET Framework assemblies&lt;/li&gt;
&lt;li&gt;Compile time rewriter and analyzer&lt;/li&gt;
&lt;li&gt;Runtime analyzer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate how [Pure] works with Code Contracts, install the tool from &lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970&quot;&gt;Visual Studio Gallery&lt;/a&gt;, then in Visual Studio, go to project properties, add conditional compilation symbol CONTRACTS_FULL:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-13-Pur_865A/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-13-Pur_865A/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice there is a new tab Code Contract. Go to the tab and enable Perform Runtime Contract Checking:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-13-Pur_865A/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-13-Pur_865A/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Code Contracts can be specified with System.Diagnostics.Contracts.Contract type’s static methods. Only pure function calls are allowed to be used with Contract methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int PureContracts(int int32)
{
    Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(IsPositive(int32)); // Function precondition.
    Contract.Ensures(IsPositive(Contract.Result&amp;lt;int&amp;gt;())); // Function post condition.

    return int32 + 0; // Function logic.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the caller of above function, Code Contract tool can check the specified precondition and post condition at compile time and runtime, if the check is enabled. And logically, the precondition and post condition check should be referential transparent and side effect free. In contrast, the following example calls impure function in precondition and post condition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int ImpureContracts(int int32)
{
    Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(IsNegative(int32)); // Function precondition.
    Contract.Ensures(IsNegative(Contract.Result&amp;lt;int&amp;gt;())); // Function post condition.

    return int32 + 0; // Function logic.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At compile time, Code Contract gives a warning: Detected call to method IsNegative(System.Int32)&apos; without [Pure] in contracts of method ‘ImpureContracts(System.Int32)&apos;.&lt;/p&gt;
&lt;p&gt;[Pure] cannot be used for anonymous function. And for any named function member, [Pure] must be used with caution. The following method is declared to be pure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure] // Incorrect.
internal static ProcessStartInfo Initialize(ProcessStartInfo processStart)
{
    processStart.RedirectStandardInput = false;
    processStart.RedirectStandardOutput = false;
    processStart.RedirectStandardError = false;
    return processStart;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But actually it is impure at all, by changing state. There is no tool to check its internal code at compile time or runtime and give any warning or error. The purity can only be ensured artificially at design time.&lt;/p&gt;
&lt;h2&gt;Purity in .NET&lt;/h2&gt;
&lt;p&gt;When code is compiled and built to assembly, its contracts can either be compiled to the same assembly, or to a separate contract assembly. For .NET Framework FCL assemblies already shipped, Microsoft provides separate contracts assembles for some most used assemblies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.VisualBasic.Compatibility.Contracts.dll&lt;/li&gt;
&lt;li&gt;Microsoft.VisualBasic.Contracts.dll&lt;/li&gt;
&lt;li&gt;mscorlib.Contracts.dll&lt;/li&gt;
&lt;li&gt;PresentationCore.Contracts.dll&lt;/li&gt;
&lt;li&gt;PresentationFramework.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.ComponentModel.Composition.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Configuration.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Configuration.Install.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Core.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Data.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Data.Services.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.DirectoryServices.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Drawing.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Numerics.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Runtime.Caching.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Security.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.ServiceModel.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.ServiceProcess.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Web.ApplicationServices.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Web.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Windows.Forms.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Xml.Contracts.dll&lt;/li&gt;
&lt;li&gt;System.Xml.Linq.Contracts.dll&lt;/li&gt;
&lt;li&gt;WindowsBase.Contracts.dll&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A contract assembly contains the contracts (precondition, post condition, invariant, etc.) for APIs in a certain FLC assemblies. For example, mscorlib.Contracts.dll provides the contracts for APIs in mscorlib.dll, System.ComponentModel.Composition.Contracts.dll provides the contracts fro APIs in System.ComponentModel.Composition.dll, etc. Above Math.Abs function is provided in mscorlib.dll, so its parity contract is provided in mscorlib.Contracts.dll, with the same signature but contains only contracts and no logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public static class Math
    {
        [Pure]
        public static int Abs(int value)
        {
            Contract.Requires(value != int.MinValue);
            Contract.Ensures(Contract.Result&amp;lt;int&amp;gt;() &amp;gt;= 0);
            Contract.Ensures((value - Contract.Result&amp;lt;int&amp;gt;()) &amp;lt;= 0);

            return default;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the caller of Math.Abs, Code Contract tool can load the above precondition and post condition from mscorlib.Contracts.dll, and run the check at compile time and runtime, if the check is enabled. C# language is not designed to be purely functional, neither are .NET APIs. So only a small percentage of built in functions are pure. To demonstrate this, reflection can be used to examine these assembly contracts. The .NET built in reflection APIs does not work well with these assembly contrast. For example, mscorlib.Contracts.dll contains type System.Void, which is considered to be a special type by .NET reflection, and causes crashes. The &lt;a href=&quot;https://www.nuget.org/packages/Mono.Cecil/&quot;&gt;Mono.Cecil&lt;/a&gt; NuGet package, a third party reflection library, can work here. The following LINQ to Objects example calls the Mono.Cecil APIs to query the contract assemblies for the public function members with [Pure], then query all .NET Framework FCL assemblies’ public function members:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PureFunction(string contractsAssemblyDirectory, string gacDirectory = @&quot;C:\Windows\Microsoft.NET\assembly&quot;)
{
    string[] contractAssemblyFiles = Directory
        .EnumerateFiles(contractsAssemblyDirectory, &quot;*.dll&quot;)
        .ToArray();
    string pureAttribute = typeof(PureAttribute).FullName;
    // Query the count of all public function members with [Pure] in all public class in all contract assemblies.
    int pureFunctionCount = contractAssemblyFiles
        .Select(assemblyContractFile =&amp;gt; AssemblyDefinition.ReadAssembly(assemblyContractFile))
        .SelectMany(assemblyContract =&amp;gt; assemblyContract.Modules)
        .SelectMany(moduleContract =&amp;gt; moduleContract.GetTypes())
        .Where(typeContract =&amp;gt; typeContract.IsPublic)
        .SelectMany(typeContract =&amp;gt; typeContract.Methods)
        .Count(functionMemberContract =&amp;gt; functionMemberContract.IsPublic
            &amp;amp;&amp;amp; functionMemberContract.CustomAttributes.Any(attribute =&amp;gt;
                attribute.AttributeType.FullName.Equals(pureAttribute, StringComparison.Ordinal)));
    pureFunctionCount.WriteLine(); // 2473

    string[] assemblyFiles = new string[] { &quot;GAC_64&quot;, &quot;GAC_MSIL&quot; }
        .Select(platformDirectory =&amp;gt; Path.Combine(gacDirectory, platformDirectory))
        .SelectMany(assemblyDirectory =&amp;gt; Directory
            .EnumerateFiles(assemblyDirectory, &quot;*.dll&quot;, SearchOption.AllDirectories))
        .ToArray();
    // Query the count of all public function members in all public class in all FCL assemblies.
    int functionCount = contractAssemblyFiles
        .Select(contractAssemblyFile =&amp;gt; assemblyFiles.First(assemblyFile =&amp;gt; Path.GetFileName(contractAssemblyFile)
            .Replace(&quot;.Contracts&quot;, string.Empty)
            .Equals(Path.GetFileName(assemblyFile), StringComparison.OrdinalIgnoreCase)))
        .Select(assemblyFile =&amp;gt; AssemblyDefinition.ReadAssembly(assemblyFile))
        .SelectMany(assembly =&amp;gt; assembly.Modules)
        .SelectMany(module =&amp;gt; module.GetTypes())
        .Where(type =&amp;gt; type.IsPublic)
        .SelectMany(type =&amp;gt; type.Methods)
        .Count(functionMember =&amp;gt; functionMember.IsPublic);
    functionCount.WriteLine(); // 83447
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, in the above mainstream FCL assemblies, there are only 2.96% public function members are pure.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (12) Immutability, Anonymous Type, and Tuple</title><link>https://dixin.github.io/posts/functional-csharp-immutability-anonymous-type-and-tuple-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-immutability-anonymous-type-and-tuple-7/</guid><description>Immutability is an important aspect of functional paradigm. As fore mentioned, imperative/object-oriented programming is usually stateful, and functional programming encourages immutability without st</description><pubDate>Tue, 12 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-immutability-anonymous-type-and-tuple&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-immutability-anonymous-type-and-tuple&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Immutability is an important aspect of functional paradigm. As fore mentioned, imperative/object-oriented programming is usually stateful, and functional programming encourages immutability without state change. In C# programming, there are &lt;a href=&quot;https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/&quot;&gt;many kinds of immutability&lt;/a&gt;, but they can be categorized into 2 levels: immutability of some value, and immutability of some value’s internal state. Take local variable as example, a local variable can be called immutable, if once it is assigned, there is no way to reassign to it; a local variable can also be called immutable, if once its internal state is initialized, there is no way to modify its state to different state.&lt;/p&gt;
&lt;p&gt;Generally, immutability can make programming easier in many cases, since it gets rid of a major source of bugs. Immutable value and immutable state can also largely simplify concurrent/parallel/multithread programming, because they are thread-safe by nature. The disadvantage of immutability is, apparently, to change an immutable value or immutable state, another new instance must to be created with the mutation, which can cause performance overhead.&lt;/p&gt;
&lt;h2&gt;Immutable value&lt;/h2&gt;
&lt;p&gt;Many functional languages support immutable value. In contrast to variable. Once a value is assigned with something, it cannot be reassigned so that it cannot be changed to anything else. For example, in F#, a value is immutable by default, unless the mutable keyword is specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let value = new Uri(&quot;https://weblogs.asp.net/dixin&quot;) // Immutable value.
value &amp;lt;- null // Cannot be compiled. Cannot reassign to value.

let mutable variable = new Uri(&quot;https://weblogs.asp.net/dixin&quot;) // Mutable variable.
variable &amp;lt;- null // Can reassign to variable.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a C-like language, C# variable is mutable by default. C# has a few other language features for immutable value.&lt;/p&gt;
&lt;h3&gt;Constant&lt;/h3&gt;
&lt;p&gt;C# has a const keyword to define compile time constant, which cannot be changed at runtime. However, it only works for primitive types, string, and null reference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Immutability
{
    internal static void Const()
    {
        const int immutable1 = 1;
        const string immutable2 = &quot;https://weblogs.asp.net/dixin&quot;;
        const object immutale3 = null;
        const Uri immutable4 = null;
        const Uri immutable5 = new Uri(immutable2); // Cannot be compiled.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;using statement and foreach statement&lt;/h3&gt;
&lt;p&gt;C# also supports immutable value in a few statements, like the fore mentioned using and foreach statements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForEach(IEnumerable&amp;lt;int&amp;gt; source)
{
    foreach (int immutable in source)
    {
        // Cannot reassign to immutable.
    }
}

internal static void Using(Func&amp;lt;IDisposable&amp;gt; disposableFactory)
{
    using (IDisposable immutable = disposableFactory())
    {
        // Cannot reassign to immutable.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;this reference for class&lt;/h3&gt;
&lt;p&gt;In class definition, this keyword can be used in instance function members. It refers to the current instance of the class, and it is immutable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
{
    internal void InstanceMethod()
    {
        // Cannot reassign to this.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, this reference is mutable for structure definition, which is discussed later.&lt;/p&gt;
&lt;h3&gt;Function’s readonly input and readonly output&lt;/h3&gt;
&lt;p&gt;The fore mentioned function parameter passed by readonly reference (in parameter) is immutable in the function, and function result retuned by readonly reference (ref readonly return) is immutable for the function’s caller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ParameterAndReturn&amp;lt;T&amp;gt;(Span&amp;lt;T&amp;gt; span)
{
    ref readonly T Last(in Span&amp;lt;T&amp;gt; immutableInput)
    {
        // Cannot reassign to immutableInput.
        int length = immutableInput.Length;
        if (length &amp;gt; 0)
        {
            return ref immutableInput[length - 1];
        }
        throw new ArgumentException(&quot;Span is empty.&quot;, nameof(immutableInput));
    }

    ref readonly T immutableOutput = ref Last(in span);
    // Cannot reassign to immutableOutput.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Local variable by readonly reference (ref readonly variable)&lt;/h3&gt;
&lt;p&gt;C# 7.2 introduces readonly reference for local variable. In C#, when defining and initializing a new local variable with some existing local variable, there are 3 cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By copy: directly assign to local variable. If a value type instance is assigned, that value type instance is copied to a new instance; if a reference type instance is assigned, that reference is copied. So when the new local variable is reassigned, the previous local variable is not impacted.&lt;/li&gt;
&lt;li&gt;By reference: assign to local variable with the ref keyword. The new local variable can be virtually viewed as a pointer or alias of the existing local variable. So when the new local variable is reassigned, it is equivalent to reassigning the previous local variable&lt;/li&gt;
&lt;li&gt;By readonly reference: assign to local variable with the ref readonly keywords. The new local variable can be also virtually viewed as a pointer or alias, but in this case the new local variable is immutable, and cannot be reassigned.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReadOnlyReference()
{
    int value = 1;
    int copyOfValue = value; // Assign by copy.
    copyOfValue = 10; // After the assignment, value does not change.
    ref int mutaleRefOfValue = ref value; // Assign by reference.
    mutaleRefOfValue = 10; // After the reassignment, value changes too.
    ref readonly int immutableRefOfValue = ref value; // Assign by readonly reference.
    immutableRefOfValue = 0; // Cannot be compiled. Cannot reassign to immutableRefOfValue.

    Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
    Uri copyOfReference = reference; // Assign by copy.
    copyOfReference = new Uri(&quot;https://flickr.com/dixin&quot;); // After the assignment, reference does not change.
    ref Uri mutableRefOfReference = ref reference; // Assign by reference.
    mutableRefOfReference = new Uri(&quot;https://flickr.com/dixin&quot;); // After the reassignment, reference changes too.
    ref readonly Uri immutableRefOfReference = ref reference; // Assign by readonly reference.
    immutableRefOfReference = null; // Cannot be compiled. Cannot reassign to immutableRefOfReference.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Immutable value in LINQ query expression&lt;/h3&gt;
&lt;p&gt;In LINQ query expression introduced by C# 3.0, the from, join, let clauses can declare values, and the into query keyword can declare value too. These values are all immutable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void QueryExpression(IEnumerable&amp;lt;int&amp;gt; source1, IEnumerable&amp;lt;int&amp;gt; source2)
{
    IEnumerable&amp;lt;IGrouping&amp;lt;int, int&amp;gt;&amp;gt; query =
        from immutable1 in source1
        // Cannot reassign to immutable1.
        join immutable2 in source2 on immutable1 equals immutable2 into immutable3
        // Cannot reassign to immutable2, immutable3.
        let immutable4 = immutable1
        // Cannot reassign to immutable4.
        group immutable4 by immutable4 into immutable5
        // Cannot reassign to immutable5.
        select immutable5 into immutable6
        // Cannot reassign to immutable6.
        select immutable6;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Query expression is a syntactic sugar of query method calls, which will be discussed in detail in LINQ to Objects chapter.&lt;/p&gt;
&lt;h2&gt;Immutable state (immutable type)&lt;/h2&gt;
&lt;p&gt;Once an instance is constructed from an immutable type, the instance’s internal data cannot be changed. In C#, string (System.String) is an immutable type. Once a string is constructed, there is no API to change that string. For example, string.Remove does not change the string but always return a newly constructed string with specified characters removed. In contrast, string builder (System.Text.StringBuilder) is a mutable type. For example, StringBuilder.Remove actually change the string to remove the specified characters. In the core library, most classes are mutable types, and most structures are immutable types.&lt;/p&gt;
&lt;h3&gt;Type’s constant field&lt;/h3&gt;
&lt;p&gt;When defining type (class or structure), a field with the const modifier is immutable. Again, it only works for primitive types, string, and null reference.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public struct DateTime : IComparable, IComparable&amp;lt;DateTime&amp;gt;, IConvertible, IEquatable&amp;lt;DateTime&amp;gt;, IFormattable, ISerializable
    {
        private const int DaysPerYear = 365;
        // Compiled to:
        // .field private static literal int32 DaysPerYear = 365

        private const int DaysPer4Years = DaysPerYear * 4 + 1;
        // Compiled to:
        // .field private static literal int32 DaysPer4Years = 1461

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Immutable class with readonly instance field&lt;/h3&gt;
&lt;p&gt;When the readonly modifier is used for a field, the field can only be initialized by constructor, and cannot be reassigned later. So an immutable class can be immutable by defining all instance fields as readonly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class ImmutableDevice
{
    private readonly string name;

    private readonly decimal price;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the fore mentioned auto property syntactic sugar, the readonly field definition can be automatically generated. The following is an example of mutable data type with read write state, and immutable data type with readonly state stored in readonly instance fields:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class MutableDevice
{
    internal string Name { get; set; }

    internal decimal Price { get; set; }
}

internal partial class ImmutableDevice
{
    internal ImmutableDevice(string name, decimal price)
    {
        this.Name = name;
        this.Price = price;
    }

    internal string Name { get; }

    internal decimal Price { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, constructed MutableDevice instance can change its internal state stored by fields, and ImmutableDevice instance cannot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void State()
{
    MutableDevice mutableDevice = new MutableDevice() { Name = &quot;Microsoft Band 2&quot;, Price = 249.99M };
    // Price drops.
    mutableDevice.Price -= 50M;

    ImmutableDevice immutableDevice = new ImmutableDevice(name: &quot;Surface Book&quot;, price: 1349.00M);
    // Price drops.
    immutableDevice = new ImmutableDevice(name: immutableDevice.Name, price: immutableDevice.Price - 50M);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the instance of immutable type cannot change state, it gets rid of a major source of bugs, and it is always thread safe. But these benefits come with a price. It is common to update some existing data to different value, for example, have a discount based on the current price:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class MutableDevice
{
    internal void Discount() =&amp;gt; this.Price = this.Price * 0.9M;
}

internal partial class ImmutableDevice
{
    internal ImmutableDevice Discount() =&amp;gt; new ImmutableDevice(name: this.Name, price: this.Price * 0.9M);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When discounting the the price, MutableDevice.Discount directly changes the state. ImmutableDevice.Discount cannot do this, so it has to construct a new instance with the new state, then return the new instance, which is also immutable. This is a performance overhead.&lt;/p&gt;
&lt;p&gt;Many .NET built-in types are immutable data structures, including most value types (primitive types, System.Nullable&amp;lt;T&amp;gt;, System.DateTime, System.TimeSpan, etc.), and some reference types (string, System.Lazy&amp;lt;T&amp;gt;, System.Linq.Expressions.Expression and its derived types, etc.). Microsoft also provides a NuGet package of immutable collections &lt;a href=&quot;https://www.nuget.org/packages/System.Collections.Immutable&quot;&gt;System.Collections.Immutable&lt;/a&gt;, with immutable array, list, dictionary, etc.&lt;/p&gt;
&lt;h3&gt;Immutable structure (readonly structure)&lt;/h3&gt;
&lt;p&gt;The following structure is defined with the same pattern as above immutable class. The structure looks immutable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial struct Complex
{
    internal Complex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }

    internal double Real { get; }

    internal double Imaginary { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the auto property syntactic sugar, readonly fields are generated. However, for structure, readonly fields are not enough for immutability. In contrast of class, in structure’s instance function members, this reference is mutable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial struct Complex
{
    internal Complex(Complex value) =&amp;gt; this = value; // Can reassign to this.

    internal Complex Value
    {
        get =&amp;gt; this;
        set =&amp;gt; this = value; // Can reassign to this.
    }

    internal Complex ReplaceBy(Complex value) =&amp;gt; this = value; // Can reassign to this.

    internal Complex Mutate(double real, double imaginary) =&amp;gt; 
        this = new Complex(real, imaginary); // Can reassign to this.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With mutable this, the above structure still can be mutable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Structure()
{
    Complex complex1 = new Complex(1, 1);
    Complex complex2 = new Complex(2, 2);
    complex1.Real.WriteLine(); // 1
    complex1.ReplaceBy(complex2);
    complex1.Real.WriteLine(); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To address this scenario, C# 7.2 enables the readonly modifier for structure definition. To make sure the structure is immutable, It enforces all the instance fields to be readonly, and makes this reference immutable in instance function members except constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal readonly partial struct ImmutableComplex
{
    internal ImmutableComplex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }

    internal ImmutableComplex(in ImmutableComplex value) =&amp;gt; 
        this = value; // Can reassign to this only in constructor.

    internal double Real { get; }

    internal double Imaginary { get; }

    internal void InstanceMethod()
    {
        // Cannot reassign to this.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Immutable anonymous type&lt;/h3&gt;
&lt;p&gt;C# 3.0 introduces anonymous type to represent immutable data, without providing the type definition at design time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnonymousType()
{
    var immutableDevice = new { Name = &quot;Surface Book&quot;, Price = 1349.00M };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the type name is unknown at design time, the above instance is of an anonymous type, and the type name is represented by the var keyword. At compile time, the following immutable data type definition is generated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[DebuggerDisplay(@&quot;\{ Name = {Name}, Price = {Price} }&quot;, Type = &quot;&amp;lt;Anonymous Type&amp;gt;&quot;)]
internal sealed class AnonymousType0&amp;lt;TName, TPrice&amp;gt;
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly TName name;

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly TPrice price;

    [DebuggerHidden]
    public AnonymousType0(TName name, TPrice price)
    {
        this.name = name;
        this.price = price;
    }

    public TName Name =&amp;gt; this.name;

    public TPrice Price =&amp;gt; this.price;

    [DebuggerHidden]
    public override bool Equals(object value) =&amp;gt;
        value is AnonymousType0&amp;lt;TName, TPrice&amp;gt; anonymous
        &amp;amp;&amp;amp; anonymous != null
        &amp;amp;&amp;amp; EqualityComparer&amp;lt;TName&amp;gt;.Default.Equals(this.name, anonymous.name)
        &amp;amp;&amp;amp; EqualityComparer&amp;lt;TPrice&amp;gt;.Default.Equals(this.price, anonymous.price);

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the above setting-property-like syntax is compiled to normal constructor call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledAnonymousType()
{
    AnonymousType0&amp;lt;string, decimal&amp;gt; immutableDevice = new AnonymousType0&amp;lt;string, decimal&amp;gt;(
        name: &quot;Surface Book&quot;, price: 1349.00M);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If there are other different anonymous type used in the code, C# compiler generates more type definitions AnonymousType1, AnonymousType2, etc. Anonymous type are reused by different instantiation if their properties have same number, names, types, and order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReuseAnonymousType()
{
    var device1 = new { Name = &quot;Surface Book&quot;, Price = 1349.00M };
    var device2 = new { Name = &quot;Surface Pro 4&quot;, Price = 899.00M };
    var device3 = new { Name = &quot;Xbox One S&quot;, Price = 399.00 }; // Price is of type double.
    var device4 = new { Price = 174.99M, Name = &quot;Microsoft Band 2&quot; };
    (device1.GetType() == device2.GetType()).WriteLine(); // True
    (device1.GetType() == device3.GetType()).WriteLine(); // False
    (device1.GetType() == device4.GetType()).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anonymous type’s property name can be inferred from the identifier used to initialize the property. The following 2 anonymous type instantiation are equivalent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PropertyInference(Uri uri, int value)
{
    var anonymous1 = new { value, uri.Host };
    var anonymous2 = new { value = value, Host = uri.Host };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anonymous type can also be part of other types, like array, and type parameter for generic type, etc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnonymousTypeParameter()
{
    var source = new[] // AnonymousType0&amp;lt;string, decimal&amp;gt;[].
    {
        new { Name = &quot;Surface Book&quot;, Price = 1349.00M },
        new { Name = &quot;Surface Pro 4&quot;, Price = 899.00M }
    };
    var query = // IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt;.
        source.Where(device =&amp;gt; device.Price &amp;gt; 0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the source array is inferred to be of AnonymousType0&amp;lt;string, decimal&amp;gt;[] type, because each array value is of type AnonymousType0. Array T[] implements IEnumerable&amp;lt;T&amp;gt; interface, so the source array implements IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt; interface. Its Where extension method accepts a AnonymousType0&amp;lt;string, decimal&amp;gt; –&amp;gt; bool predicate function, and returns IEnumerable&amp;lt;AnonymousType0&amp;lt;string, decimal&amp;gt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;C# compiler utilizes anonymous type for let clause in LINQ query expression. The let clause is compiled to Select query method call with a selector function returning anonymous type. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Let(IEnumerable&amp;lt;int&amp;gt; source)
{
    IEnumerable&amp;lt;double&amp;gt; query =
        from immutable1 in source
        let immutable2 = Math.Sqrt(immutable1)
        select immutable1 + immutable2;
}

internal static void CompiledLet(IEnumerable&amp;lt;int&amp;gt; source)
{
    IEnumerable&amp;lt;double&amp;gt; query = source // from clause.
        .Select(immutable1 =&amp;gt; new { immutable1, immutable2 = Math.Sqrt(immutable1) }) // let clause.
        .Select(anonymous =&amp;gt; anonymous.immutable1 + anonymous.immutable2); // select clause.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The full details of query expression compilation is covered in the LINQ to Objects chapter.&lt;/p&gt;
&lt;h3&gt;Local variable type inference&lt;/h3&gt;
&lt;p&gt;Besides local variable of anonymous type, the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb383973.aspx&quot;&gt;var keyword&lt;/a&gt; can be also used to initialize local variable of existing type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalVariable(IEnumerable&amp;lt;int&amp;gt; source, string path)
{
    var a = default(int); // int.
    var b = 1M; // decimal.
    var c = typeof(void); // Type.
    var d = from int32 in source where int32 &amp;gt; 0 select Math.Sqrt(int32); // IEnumerable&amp;lt;double&amp;gt;.
    var e = File.ReadAllLines(path); // string[].
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is just a syntactic sugar. The local variable’s type is inferred from the initial value’s type. The compilation of implicit typed local variable has no difference from explicitly typed local variable. When the initial value’s type is ambiguous, the var keyword cannot be directly used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalVariableWithType()
{
    var f = (Uri)null;
    var g = (Func&amp;lt;int, int&amp;gt;)(int32 =&amp;gt; int32 + 1);
    var h = (Expression&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;)(int32 =&amp;gt; int32 + 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For consistency and readability, this tutorial &lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;uses explicit typing when possible, uses implicit typing (var) when needed&lt;/a&gt; (for anonymous type).&lt;/p&gt;
&lt;h3&gt;Immutable tuple vs. mutable tuple&lt;/h3&gt;
&lt;p&gt;Tuple is another kind of data structure commonly used in functional programming. It is a finite and ordered list of values, usually immutable in most functional languages. To represent tuple, a series of generic tuple classes with 1 ~ 8 type parameters are provided since .NET Framework 3.5. For example, the following is the definition of Tuple&amp;lt;T1, T2&amp;gt;, which represents a 2-tuple (tuple of 2 values):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [Serializable]
    public class Tuple&amp;lt;T1, T2&amp;gt; : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
    {
        public Tuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }

        public T1 Item1 { get; }

        public T2 Item2 { get; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All tuple classes are immutable. The latest C# 7.0 introduces tuple syntax, which work with a series of generic tuple structures with 1 ~ 8 type parameters. For example, 2-tuple is now represented by the following ValueTuple&amp;lt;T1, T2&amp;gt; structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [StructLayout(LayoutKind.Auto)]
    public struct ValueTuple&amp;lt;T1, T2&amp;gt; : IEquatable&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;, IStructuralEquatable, IStructuralComparable, IComparable, IComparable&amp;lt;ValueTuple&amp;lt;T1, T2&amp;gt;&amp;gt;, ITupleInternal
    {
        public T1 Item1;

        public T2 Item2;

        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }

        public override bool Equals(object obj) =&amp;gt; obj is ValueTuple&amp;lt;T1, T2&amp;gt; tuple &amp;amp;&amp;amp; this.Equals(tuple);

        public bool Equals(ValueTuple&amp;lt;T1, T2&amp;gt; other) =&amp;gt;
            EqualityComparer&amp;lt;T1&amp;gt;.Default.Equals(this.Item1, other.Item1)
            &amp;amp;&amp;amp; EqualityComparer&amp;lt;T2&amp;gt;.Default.Equals(this.Item2, other.Item2);

        public int CompareTo(ValueTuple&amp;lt;T1, T2&amp;gt; other)
        {
            int compareItem1 = Comparer&amp;lt;T1&amp;gt;.Default.Compare(this.Item1, other.Item1);
            return compareItem1 != 0 ? compareItem1 : Comparer&amp;lt;T2&amp;gt;.Default.Compare(this.Item2, other.Item2);
        }

        public override string ToString() =&amp;gt; $&quot;({this.Item1}, {this.Item2})&quot;;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The value tuple is provided for better performance, since it does not managed heap allocation and garbage collection. However, all value tuple structures become mutable types, where the values are just public fields. To be functional and consistent, this tutorial only uses value tuples, and only use them as immutable types.&lt;/p&gt;
&lt;p&gt;As above tuple definition shows, in contrast of list, tuple’s values can be of different types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TupleAndList()
{
    ValueTuple&amp;lt;string, decimal&amp;gt; tuple = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Book&quot;, 1349M);
    List&amp;lt;string&amp;gt; list = new List&amp;lt;string&amp;gt;() { &quot;Surface Book&quot;, &quot;1349M&quot; };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tuple type and anonymous type are conceptually similar to each other, they are both a set of properties returning a list of values. The major difference is, at design time, the tuple type is defined, and anonymous type is not defined yet. Therefore, anonymous type (var) can only be used for local variable with initial value to infer the expected type from, and cannot be used as parameter type, return type, type argument, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static ValueTuple&amp;lt;string, decimal&amp;gt; Method(ValueTuple&amp;lt;string, decimal&amp;gt; values)
{
    ValueTuple&amp;lt;string, decimal&amp;gt; variable1;
    ValueTuple&amp;lt;string, decimal&amp;gt; variable2 = default;
    IEnumerable&amp;lt;ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt; variable3;
    return values;
}

internal static var Method(var values) // Cannot be compiled.
{
    var variable1; // Cannot be compiled.
    var variable2 = default; // Cannot be compiled.
    IEnumerable&amp;lt;var&amp;gt; variable3; // Cannot be compiled.
    return values;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Construction, element and element inference&lt;/h3&gt;
&lt;p&gt;C# 7.0 introduces tuple syntactic sugar, which brings great convenience. The tuple type ValuTuple&amp;lt;T1, T2, T3, …&amp;gt; can be simplified to (T1, T2, T3, …), and the tuple construction new ValueTuple&amp;lt;T1, T2, T3, …&amp;gt;(value1, value2, value3, …) can be simplified to (value1, value2, value3, …):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TupleTypeLiteral()
{
    (string, decimal) tuple1 = (&quot;Surface Pro 4&quot;, 899M);
    // Compiled to: 
    // ValueTuple&amp;lt;string, decimal&amp;gt; tuple1 = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Pro 4&quot;, 899M);

    (int, bool, (string, decimal)) tuple2 = (1, true, (&quot;Surface Studio&quot;, 2999M));
    // ValueTuple&amp;lt;int, bool, ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt; tuple2 = 
    //    new ValueTuple&amp;lt;int, bool, new ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt;(1, true, (&quot;Surface Studio&quot;, 2999M))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, tuple can be function’s parameter/return type, just like other types. When using tuple as the function return type, the tuple syntax virtually enables function to return multiple values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static (string, decimal) MethodReturnMultipleValues()
// internal static ValueTuple&amp;lt;string, decimal&amp;gt; MethodReturnMultipleValues()
{
    string returnValue1 = default;
    int returnValue2 = default;

    (string, decimal) Function() =&amp;gt; (returnValue1, returnValue2);
    // ValueTuple&amp;lt;string, decimal&amp;gt; Function() =&amp;gt; new ValueTuple&amp;lt;string, decimal&amp;gt;(returnValue1, returnValue2);

    Func&amp;lt;(string, decimal)&amp;gt; function = () =&amp;gt; (returnValue1, returnValue2);
    // Func&amp;lt;ValueTuple&amp;lt;string, decimal&amp;gt;&amp;gt; function = () =&amp;gt; new ValueTuple&amp;lt;string, decimal&amp;gt;(returnValue1, returnValue2);

    return (returnValue1, returnValue2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 7.0 also introduces element name for tuple, so that each value of the tuple type can be given a property-like name, with the syntax (T1 Name1, T2 Name2, T3 Name3, …), and each value of the tuple instance can be given a name too, with syntax (Name1: value1, Name2, value2, Name3 value3, …). So that the values in the tuple can be accessed with a meaningful name, instead of the actual Item1, Item2, Item3, … field names. This is also a syntactic sugar, at compile time, all element names are all replaced by the underlying fields.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ElementName()
{
    (string Name, decimal Price) tuple1 = (&quot;Surface Pro 4&quot;, 899M);
    tuple1.Name.WriteLine();
    tuple1.Price.WriteLine();
    // Compiled to: 
    // ValueTuple&amp;lt;string, decimal&amp;gt; tuple1 = new ValueTuple&amp;lt;string, decimal&amp;gt;(&quot;Surface Pro 4&quot;, 899M);
    // TraceExtensions.WriteLine(tuple1.Item1);
    // TraceExtensions.WriteLine(tuple1.Item2)

    (string Name, decimal Price) tuple2 = (ProductNanme: &quot;Surface Book&quot;, ProductPrice: 1349M);
    tuple2.Name.WriteLine(); // Element names on the right side are ignore.

    var tuple3 = (Name: &quot;Surface Studio&quot;, Price: 2999M);
    tuple3.Name.WriteLine(); // Element names are available through var.

    ValueTuple&amp;lt;string, decimal&amp;gt; tuple4 = (Name: &quot;Xbox One&quot;, Price: 179M);
    tuple4.Item1.WriteLine(); // Element names are not available on ValueTuple&amp;lt;T1, T2&amp;gt;.
    tuple4.Item2.WriteLine();

    (string Name, decimal Price) Function((string Name, decimal Price) tuple)
    {
        tuple.Name.WriteLine(); // Parameter element names are available in function.
        return (tuple.Name, tuple.Price - 10M);
    };
    var tuple5 = Function((&quot;Xbox One S&quot;, 299M));
    tuple5.Name.WriteLine(); // Return value element names are available through var.
    tuple5.Price.WriteLine();

    Func&amp;lt;(string Name, decimal Price), (string Name, decimal Price)&amp;gt; function = tuple =&amp;gt;
    {
        tuple.Name.WriteLine(); // Parameter element names are available in function.
        return (tuple.Name, tuple.Price - 100M);
    };
    var tuple6 = function((&quot;HoloLens&quot;, 3000M));
    tuple5.Name.WriteLine(); // Return value element names are available through var.
    tuple5.Price.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to anonymous type’s property inference, C# 7.1 can infer tuple’s element name from the identifier used to initialize the element. The following 2 tuple are equivalent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ElementInference(Uri uri, int value)
{
    var tuple1 = (value, uri.Host);
    var tuple2 = (value: value, Host: uri.Host);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Deconstruction&lt;/h3&gt;
&lt;p&gt;Since C# 7.0, the var keyword can also be used to deconstruct tuple to a list of values. This syntax is very useful when used with functions returning multiple values represented by tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeconstructTuple()
{
    (string, decimal) GetProductInfo() =&amp;gt; (&quot;HoLoLens&quot;, 3000M);
    var (name, price) = GetProductInfo();
    name.WriteLine(); // name is string.
    price.WriteLine(); // price is decimal.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This deconstruction syntactic sugar can be used with any type, as long as that type has a Deconstruct instance or extension method defined, where the values as the out parameters. Take the fore mentioned Device type as example, It has 3 properties Name, Description, and Price, so its Deconstruct method can be either one of the following 2 forms:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
{
    internal void Deconstruct(out string name, out string description, out decimal price)
    {
        name = this.Name;
        description = this.Description;
        price = this.Price;
    }
}

internal static class DeviceExtensions
{
    internal static void Deconstruct(this Device device, out string name, out string description, out decimal price)
    {
        name = device.Name;
        description = device.Description;
        price = device.Price;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the var keyword can destruct Device too, which is just compiled to Destruct method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeconstructDevice()
{
    Device GetDevice() =&amp;gt; new Device() { Name = &quot;Surface studio&quot;, Description = &quot;All-in-one PC.&quot;, Price = 2999M };
    var (name, description, price) = GetDevice();
    // Compiled to:
    // string name; string description; decimal price;
    // surfaceStudio.Deconstruct(out name, out description, out price);
    name.WriteLine(); // Surface studio
    description.WriteLine(); // All-in-one PC.
    price.WriteLine(); // 2999
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Discard&lt;/h3&gt;
&lt;p&gt;In tuple destruction, since the elements are compiled to out variables of the Destruct method, any element can be discarded with underscore just like a out variable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Discard()
{
    Device GetDevice() =&amp;gt; new Device() { Name = &quot;Surface studio&quot;, Description = &quot;All-in-one PC.&quot;, Price = 2999M };
    var (_, _, price1) = GetDevice();
    (_, _, decimal price2) = GetDevice();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Tuple assignment&lt;/h3&gt;
&lt;p&gt;With the tuple syntax, now C# can also support fancy tuple assignment, just like Python and other languages. The following example assigns 2 values to 2 variables with a single line of code, then swap the values of 2 variables with a single line of code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TupleAssignment(int value1, int value2)
{
    (value1, value2) = (1, 2);
    // Compiled to:
    // value1 = 1; value2 = 2;

    (value1, value2) = (value2, value1);
    // Compiled to:
    // int temp1 = value1; int temp2 = value2;
    // value1 = temp2; value2 = temp1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is easy to calculate Fibonacci number with loop and tuple assignment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int Fibonacci(int n)
{
    (int a, int b) = (0, 1);
    for (int i = 0; i &amp;lt; n; i++)
    {
        (a, b) = (b, a + b);
    }
    return a;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides variables, tuple assignment works for other scenarios too, like type member. The following example assigns 2 values to 2 properties with a single line of code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class ImmutableDevice
{
    internal ImmutableDevice(string name, decimal price) =&amp;gt;
        (this.Name, this.Price) = (name, price);

    internal string Name { get; }

    internal decimal Price { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Immutability vs. readonly&lt;/h2&gt;
&lt;h3&gt;Immutable collection vs. readonly collection&lt;/h3&gt;
&lt;p&gt;Microsoft provides immutable collections through the System.Collections.Immutable NuGet Package, including ImmutableArray&amp;lt;T&amp;gt;, ImmutableDictionary&amp;lt;TKey, TValue&amp;gt;, ImmutableHashSet&amp;lt;T&amp;gt;, ImmutableList&amp;lt;T&amp;gt;, ImmutableQueue&amp;lt;T&amp;gt;, ImmutableSet&amp;lt;T&amp;gt;, ImmutableStack&amp;lt;T&amp;gt;, etc. As fore mentioned, trying to changing an immutable collection creates a new immutable collection:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ImmutableCollection()
{
    ImmutableList&amp;lt;int&amp;gt; immutableList1 = ImmutableList.Create(1, 2, 3);
    ImmutableList&amp;lt;int&amp;gt; immutableList2 = immutableList1.Add(4); // Create a new collection.
    object.ReferenceEquals(immutableList1, immutableList2).WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET/Core also provides readonly collections, like ReadOnlyCollection&amp;lt;T&amp;gt;, ReadOnlyDictionary&amp;lt;TKey, TValue&amp;gt;, etc., which can be confusing. These readonly collections are actually a simple wrapper of mutable collections. They just do not implement and expose methods like Add, Remove, which are used to change the collection. They are neither immutable, nor thread safe. The following example creates an immutable collection and a readonly collection from a mutable source. When the source is changed, the immutable collection apparently is not changed, but the readonly collection is changed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReadOnlyCollection()
{
    List&amp;lt;int&amp;gt; mutableList = new List&amp;lt;int&amp;gt;() { 1, 2, 3 };
    ImmutableList&amp;lt;int&amp;gt; immutableList = ImmutableList.CreateRange(mutableList);
    ReadOnlyCollection&amp;lt;int&amp;gt; readOnlyCollection = new ReadOnlyCollection&amp;lt;int&amp;gt;(mutableList);
    // ReadOnlyCollection&amp;lt;int&amp;gt; wraps a mutable source, just has no methods like Add, Remove, etc.

    mutableList.Add(4);
    immutableList.Count.WriteLine(); // 3
    readOnlyCollection.Count.WriteLine(); // 4
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (11) Covariance and Contravariance</title><link>https://dixin.github.io/posts/functional-csharp-covariance-and-contravariance-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-covariance-and-contravariance-7/</guid><description>In ), variance means the capability to substitute a type with a more derived type or les</description><pubDate>Mon, 11 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-covariance-and-contravariance&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-covariance-and-contravariance&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&quot;https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)&quot;&gt;covariance and contravariance&lt;/a&gt;, variance means the capability to substitute a type with a more derived type or less derived type in a context. The following is a simple &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/27db6csx.aspx&quot;&gt;inheritance hierarchy&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Base { }

internal class Derived : Base { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Base is a less derived type, and Derived is a more derived type. So a Derived instance “&lt;a href=&quot;https://en.wikipedia.org/wiki/Is-a&quot;&gt;is a&lt;/a&gt;” Base instance, or in another words, a Derived instance can substitute a Base instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Variances
{
    internal static void Substitute()
    {
        Base @base = new Base();
        @base = new Derived();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here covariance and contravariance discusses the “is a” or substitution relationship of functions and generic interfaces. C# 2.0 introduces variances for functions, and C# 4.0 introduces variances for generic delegate types and generic interfaces. C# covariance/contravariance only applies to reference types, not value types. So the above Base and Derived types are defined as classes, and they are used to demonstrate the variances.&lt;/p&gt;
&lt;h2&gt;Variances of non-generic function type&lt;/h2&gt;
&lt;p&gt;By using above Base and Derived as input and output type of function, there are 4 combinations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Derived -&amp;gt; Base
internal static Base DerivedToBase(Derived input) =&amp;gt; new Base();

// Derived -&amp;gt; Derived
internal static Derived DerivedToDerived(Derived input) =&amp;gt; new Derived();

// Base -&amp;gt; Base
internal static Base BaseToBase(Base input) =&amp;gt; new Base();

// Base -&amp;gt; Derived
internal static Derived BaseToDerived(Base input) =&amp;gt; new Derived();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are of 4 different function types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Base DerivedToBase(Derived input); // Derived -&amp;gt; Base

internal delegate Derived DerivedToDerived(Derived input); // Derived -&amp;gt; Derived

internal delegate Base BaseToBase(Base input); // Base -&amp;gt; Base

internal delegate Derived BaseToDerived(Base input); // Base -&amp;gt; Derived
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take the second function DerivedToDerived as example, naturally, it is of the second function type DerivedToDerived:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGeneric()
{
    DerivedToDerived derivedToDerived = DerivedToDerived;
    Derived output = derivedToDerived(input: new Derived());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since C# 2.0, it seems of the first function type DerivedToBase too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGenericCovariance()
{
    DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base

    // Covariance: Derived is Base, so that DerivedToDerived is DerivedToBase.
    derivedToBase = DerivedToDerived; // Derived -&amp;gt; Derived

    // When calling derivedToBase, DerivedToDerived executes.
    // derivedToBase should output Base, while DerivedToDerived outputs Derived.
    // The actual Derived output is the required Base output. This always works.
    Base output = derivedToBase(input: new Derived());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So function instance’s actual output can be more derived than function type’s required output. Therefore, function with more derived output “is a” function with less derived output, or in another word, function with more derived output can substitute function with less derived output. This is called covariance. Similarly, function instance’s input can be less derived than function type input:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGenericContravariance()
{
    DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base

    // Contravariance: Derived is Base, so that BaseToBase is DerivedToBase.
    derivedToBase = BaseToBase; // Base -&amp;gt; Base

    // When calling derivedToBase, BaseToBase executes.
    // derivedToBase should accept Derived input, while BaseToBase accepts Base input.
    // The required Derived input is the accepted Base input. This always works.
    Base output = derivedToBase(input: new Derived());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Therefore, function with less derived input “is a” function with more derived input, or in another word, function with less derived input can substitute function with more derived input. This is called contravariance. Covariance and contravariance can happen at the same time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGenericeCovarianceAndContravariance()
{
    DerivedToBase derivedToBase = DerivedToBase; // Derived -&amp;gt; Base

    // Covariance and contravariance: Derived is Base, so that BaseToDerived is DerivedToBase. 
    derivedToBase = BaseToDerived; // Base -&amp;gt; Derived

    // When calling derivedToBase, BaseToDerived executes.
    // derivedToBase should accept Derived input, while BaseToDerived accepts Base input.
    // The required Derived input is the accepted Base input.
    // derivedToBase should output Base, while BaseToDerived outputs Derived.
    // The actual Derived output is the required Base output. This always works.
    Base output = derivedToBase(input: new Derived());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, function instance output cannot be less derived than function type output, and function input cannot be more derived than function type input. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NonGenericInvalidVariance()
{
    // baseToDerived should output Derived, while BaseToBase outputs Base. 
    // The actual Base output is not the required Derived output. This cannot be compiled.
    BaseToDerived baseToDerived = BaseToBase; // Base -&amp;gt; Derived

    // baseToDerived should accept Base input, while DerivedToDerived accepts Derived input.
    // The required Base input is not the accepted Derived input. This cannot be compiled.
    baseToDerived = DerivedToDerived; // Derived -&amp;gt; Derived

    // baseToDerived should accept Base input, while DerivedToBase accepts Derived input.
    // The required Base input is not the expected Derived input.
    // baseToDerived should output Derived, while DerivedToBase outputs Base.
    // The actual Base output is not the required Derived output. This cannot be compiled.
    baseToDerived = DerivedToBase; // Derived -&amp;gt; Base
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Variances of generic function type&lt;/h2&gt;
&lt;p&gt;With generic delegate type, all the above function types can be represented by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate TOutput GenericFunc&amp;lt;TInput, TOutput&amp;gt;(TInput input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the above variances can be represented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Generic()
{
    GenericFunc&amp;lt;Derived, Base&amp;gt; derivedToBase = DerivedToBase; // GenericFunc&amp;lt;Derived, Base&amp;gt;: no variances.
    derivedToBase = DerivedToDerived; // GenericFunc&amp;lt;Derived, Derived&amp;gt;: covariance.
    derivedToBase = BaseToBase; // GenericFunc&amp;lt;Base, Base&amp;gt;: contravariance.
    derivedToBase = BaseToDerived; // GenericFunc&amp;lt;Base, Derived&amp;gt;: covariance and contravariance.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For functions of GenericFunc&amp;lt;TInput, TOutput&amp;gt; type, covariance can happen when TOutput is substituted by more derived type, and contravariance can happen when TInput is substituted by less derived type. So TOutput is called covariant type parameter for this generic delegate type, and TInput is called contravariant type parameter. C# 4.0 introduces the out/in modifiers for the covariant/contravariant type parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate TOutput GenericFuncWithVariances&amp;lt;in TInput, out TOutput&amp;gt;(TInput input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These modifiers enable the implicit conversion/substitution between functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctionImplicitConversion()
{
    GenericFuncWithVariances&amp;lt;Derived, Base&amp;gt; derivedToBase = DerivedToBase; // Derived -&amp;gt; Base
    GenericFuncWithVariances&amp;lt;Derived, Derived&amp;gt; derivedToDerived = DerivedToDerived; // Derived -&amp;gt; Derived
    GenericFuncWithVariances&amp;lt;Base, Base&amp;gt; baseToBase = BaseToBase; // Base -&amp;gt; Base
    GenericFuncWithVariances&amp;lt;Base, Derived&amp;gt; baseToDerived = BaseToDerived; // Base -&amp;gt; Derived

    // Cannot be compiled without the out/in modifiers.
    derivedToBase = derivedToDerived; // Covariance.
    derivedToBase = baseToBase; // Contravariance.
    derivedToBase = baseToDerived; // Covariance and contravariance.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, unified Func and Action generic delegate types are provided to represent all function types. Since .NET Framework 4.0, all their type parameters have the out/in modifiers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate TResult Func&amp;lt;out TResult&amp;gt;();

    public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);

    public delegate TResult Func&amp;lt;in T1, in T2, out TResult&amp;gt;(T1 arg1, T2 arg2);

    // ...

    public delegate void Action();

    public delegate void Action&amp;lt;in T&amp;gt;(T obj);

    public delegate void Action&amp;lt;in T1, in T2&amp;gt;(T1 arg1, T2 arg2);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Variant type parameter is not syntactic sugar. The out/in modifiers are compiled to CIL +/– flags in CIL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class public auto ansi sealed Func&amp;lt;-T, +TResult&amp;gt; extends System.MulticastDelegate
{
    .method public hidebysig newslot virtual instance !TResult Invoke(!T arg) runtime managed
    {
    }

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Variances of generic interface&lt;/h2&gt;
&lt;p&gt;Besides generic delegate types, C# 4.0 also introduces variances for generic interfaces. An interface can be viewed as a set of function members’ signatures to indicate their function types, without implementations. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IOutput&amp;lt;out TOutput&amp;gt; // TOutput is covariant for all members using TOutput.
{
    TOutput ToOutput(); // () -&amp;gt; TOutput

    TOutput Output { get; } // get_Output: () -&amp;gt; TOutput

    void TypeParameterNotUsed();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above generic interface, there are 2 function members using the type parameter, and the type parameter is covariant for these 2 functions’ function types. Therefore, the type parameter is covariant for the interface, and the out modifier can be used to enable the implicit conversion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GenericInterfaceCovariance(IOutput&amp;lt;Base&amp;gt; outputBase, IOutput&amp;lt;Derived&amp;gt; outputDerived)
{
    // Covariance: Derived is Base, so that IOutput&amp;lt;Derived&amp;gt; is IOutput&amp;lt;Base&amp;gt;.
    outputBase = outputDerived;

    // When calling outputBase.ToOutput, outputDerived.ToOutput executes.
    // outputBase.ToOutput should output Base, outputDerived.ToOutput outputs Derived.
    // The actual Derived output is the required Base output. This always works.
    Base output1 = outputBase.ToOutput();

    Base output2 = outputBase.Output; // outputBase.get_Output().
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IOutput&amp;lt;Derived&amp;gt; interface does not inherit IOutput&amp;lt;Base&amp;gt; interface, but it seems a IOutput&amp;lt;Derived&amp;gt; interface “is an” IOutput&amp;lt;Base&amp;gt; interface, or in another word, IOutput&amp;lt;TOutput&amp;gt; interface with more derived type argument can substitute IOutput&amp;lt;TOutput&amp;gt; with less derived type argument. This is the covariance of generic interface. Similarly, generic interface can also have contravariant type parameter, and the in modifier can enable the implicit conversion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IInput&amp;lt;in TInput&amp;gt; // TInput is contravariant for all members using TInput.
{
    void InputToVoid(TInput input); // TInput -&amp;gt; void

    TInput Input { set; } // set_Input: TInput -&amp;gt; void

    void TypeParameterNotUsed();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IInput&amp;lt;Base&amp;gt; interface does not inherit IInput&amp;lt;Derived&amp;gt; interface, but it seems a IInput&amp;lt;Base&amp;gt; interface “is an” IInput&amp;lt;Derived&amp;gt; interface, or in another word, IInput&amp;lt;TInput&amp;gt; interface with more derived type argument can substitute IInput&amp;lt;TInput&amp;gt; with less derived type argument. This is the contravariance of generic interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GenericInterfaceContravariance(IInput&amp;lt;Derived&amp;gt; inputDerived, IInput&amp;lt;Base&amp;gt; inputBase)
{
    // Contravariance: Derived is Base, so that IInput&amp;lt;Base&amp;gt; is IInput&amp;lt;Derived&amp;gt;.
    inputDerived = inputBase;

    // When calling inputDerived.Input, inputBase.Input executes.
    // inputDerived.Input should accept Derived input, while inputBase.Input accepts Base input.
    // The required Derived output is the accepted Base input. This always works.
    inputDerived.InputToVoid(input: new Derived());

    inputDerived.Input = new Derived();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to generic delegate type, generic interface can have covariant type parameter and contravariant type parameter at the same time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IInputOutput&amp;lt;in TInput, out TOutput&amp;gt; // TInput/TOutput is contravariant/covariant for all members using TInput/TOutput.
{
    void InputToVoid(TInput input); // TInput -&amp;gt; void

    TInput Input { set; } // set_Input: TInput -&amp;gt; void

    TOutput ToOutput(); // () -&amp;gt; TOutput

    TOutput Output { get; } // get_Output: () -&amp;gt; TOutput

    void TypeParameterNotUsed();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates the covariance and contravariance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GenericInterfaceCovarianceAndContravariance(
    IInputOutput&amp;lt;Derived, Base&amp;gt; inputDerivedOutputBase, IInputOutput&amp;lt;Base, Derived&amp;gt; inputBaseOutputDerived)
{
    // Covariance and contravariance: Derived is Base, so that IInputOutput&amp;lt;Base, Derived&amp;gt; is IInputOutput&amp;lt;Derived, Base&amp;gt;.
    inputDerivedOutputBase = inputBaseOutputDerived;

    inputDerivedOutputBase.InputToVoid(new Derived());
    inputDerivedOutputBase.Input = new Derived();
    Base output1 = inputDerivedOutputBase.ToOutput();
    Base output2 = inputDerivedOutputBase.Output;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not all type parameters can be variant for generic interface. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IInvariant&amp;lt;T&amp;gt;
{
    T Output(); // T is covariant for Output: () -&amp;gt; T.

    void Input(T input); // T is contravariant for Input: T -&amp;gt; void.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type parameter T is neither covariant for all function members using T, nor contravariant for all function members using T, so T cannot be covariant or contravariant for the interface.&lt;/p&gt;
&lt;h2&gt;Variances of generic higher-order function&lt;/h2&gt;
&lt;p&gt;So far covariance and the out modifier are all about output, and contravariance and the in modifier are all about input. The variances are interesting for generic higher-order function types. For example, the following function type is higher-order, because it returns a function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate Func&amp;lt;TOutput&amp;gt; ToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant output type.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type parameter is used by output function type, where it is still covariant. The following example demonstrate how this works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OutputVariance()
{
    // First order functions.
    Func&amp;lt;Base&amp;gt; toBase = () =&amp;gt; new Base();
    Func&amp;lt;Derived&amp;gt; toDerived = () =&amp;gt; new Derived();

    // Higher-order functions.
    ToFunc&amp;lt;Base&amp;gt; toToBase = () =&amp;gt; toBase;
    ToFunc&amp;lt;Derived&amp;gt; toToDerived = () =&amp;gt; toDerived;

    // Covariance: Derived is Base, so that ToFunc&amp;lt;Derived&amp;gt; is ToFunc&amp;lt;Base&amp;gt;.
    toToBase = toToDerived;

    // When calling toToBase, toToDerived executes.
    // toToBase should output Func&amp;lt;Base&amp;gt;, while toToDerived outputs Func&amp;lt;Derived&amp;gt;.
    // The actual Func&amp;lt;Derived&amp;gt; output is the required Func&amp;lt;Base&amp;gt; output. This always works.
    Func&amp;lt;Base&amp;gt; output = toToBase();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For higher-order function types, when type parameter is used in output function type, it always covariant:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; T:
internal delegate TOutput Func&amp;lt;out TOutput&amp;gt;(); // Covariant output type.

// () -&amp;gt; () -&amp;gt; T, equivalent to Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;:
internal delegate Func&amp;lt;TOutput&amp;gt; ToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant output type.

// () -&amp;gt; () -&amp;gt; () -&amp;gt; T: Equivalent to Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;:
internal delegate ToFunc&amp;lt;TOutput&amp;gt; ToToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant output type.

// () -&amp;gt; () -&amp;gt; () -&amp;gt; () -&amp;gt; T: Equivalent to Func&amp;lt;Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;:
internal delegate ToToFunc&amp;lt;TOutput&amp;gt; ToToToFunc&amp;lt;out TOutput&amp;gt;(); // Covariant output type.

// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, higher-order function type can be defined by accepting function as input:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void ActionToVoid&amp;lt;in TTInput&amp;gt;(Action&amp;lt;TTInput&amp;gt; action); // Cannot be compiled.

internal static void InputVariance()
{
    ActionToVoid&amp;lt;Derived&amp;gt; derivedToVoidToVoid = (Action&amp;lt;Derived&amp;gt; derivedToVoid) =&amp;gt; { };
    ActionToVoid&amp;lt;Base&amp;gt; baseToVoidToVoid = (Action&amp;lt;Base&amp;gt; baseToVoid) =&amp;gt; { };
    derivedToVoidToVoid = baseToVoidToVoid;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, the above code cannot be compiled. The reason is, when type parameter is used by input function type, it can be covariant or contravariant. In this case, it becomes contravariant:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void ActionToVoid&amp;lt;out TInput&amp;gt;(Action&amp;lt;TInput&amp;gt; action);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how it works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InputVariance()
{
    // Higher-order functions.
    ActionToVoid&amp;lt;Derived&amp;gt; derivedToVoidToVoid = (Action&amp;lt;Derived&amp;gt; derivedToVoid) =&amp;gt; { };
    ActionToVoid&amp;lt;Base&amp;gt; baseToVoidToVoid = (Action&amp;lt;Base&amp;gt; baseToVoid) =&amp;gt; { };

    // Covariance: Derived is Base, so that ActionToVoid&amp;lt;Derived&amp;gt; is ActionToVoid&amp;lt;Base&amp;gt;.
    baseToVoidToVoid = derivedToVoidToVoid;

    // When calling baseToVoidToVoid, derivedToVoidToVoid executes.
    // baseToVoidToVoid should accept Action&amp;lt;Base&amp;gt; input, while derivedToVoidToVoid accepts Action&amp;lt;Derived&amp;gt; input.
    // The required Action&amp;lt;Derived&amp;gt; input is the accepted Action&amp;lt;Base&amp;gt; input. This always works.
    baseToVoidToVoid(default(Action&amp;lt;Base&amp;gt;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For higher-order function types, when type parameter is used in input function type, here are its variances:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; void:
internal delegate void Action&amp;lt;in TInput&amp;gt;(TInput input); // Contravariant input type.

// (() -&amp;gt; void) -&amp;gt; void, equivalent to Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;:
internal delegate void ActionToVoid&amp;lt;out TTInput&amp;gt;(Action&amp;lt;TTInput&amp;gt; action); // Covariant input type.

// ((() -&amp;gt; void) -&amp;gt; void) -&amp;gt; void, equivalent to Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;:
internal delegate void ActionToVoidToVoid&amp;lt;in TTInput&amp;gt;(ActionToVoid&amp;lt;TTInput&amp;gt; actionToVoid); // Contravariant input type.

// (((() -&amp;gt; void) -&amp;gt; void) -&amp;gt; void) -&amp;gt; void, equivalent to Action&amp;lt;Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;:
internal delegate void ActionToVoidToVoidToVoid&amp;lt;out TTInput&amp;gt;(ActionToVoidToVoid&amp;lt;TTInput&amp;gt; actionToVoidToVoid); // Covariant input type.

// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Covariance of array&lt;/h2&gt;
&lt;p&gt;As fore mentioned, an array T[] implements IList&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IList&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        T this[int index] { get; set; }
        // T is covariant for get_Item: int -&amp;gt; T.
        // T is contravariant for set_Item: (int, T) -&amp;gt; void.

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For IList&amp;lt;T&amp;gt;, T is not covariant for its indexer setter, and T is not contravariant for its indexer getter. So T should be invariant for IList&amp;lt;T&amp;gt; and array T[]. However, C# compiler and CLR/CoreCLR unexpectedly supports covariance for array. The following example can be compiled but throws ArrayTypeMismatchException at runtime, which can be a source of bugs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ArrayCovariance()
{
    Base[] baseArray = new Base[3];
    Derived[] derivedArray = new Derived[3];

    baseArray = derivedArray; // Array covariance at compile time, baseArray refers to a Derived array at runtime.
    Base value = baseArray[0];
    baseArray[1] = new Derived();
    baseArray[2] = new Base(); // ArrayTypeMismatchException at runtime, Base cannot be in Derived array.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are some background information for array covariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/news/2008/08/GenericVariance&quot;&gt;Jonathan Allen said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On a historical note, C# and VB both support array covariance (&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/09/01/understanding-csharp-covariance-and-contravariance-6-typing-issues.html&quot;&gt;out/IEnumerable scenario&lt;/a&gt;) even though it can lead to runtime errors in contravariant situations (in/IWriter scenario). This was done in order to make C# more compatible with Java. This is generally considered a poor decision, but it cannot be undone at this time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the book “&lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0321154932&quot;&gt;The Common Language Infrastructure Annotated Standard&lt;/a&gt;”, Jim Miller said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The decision to support covariant arrays was primarily to allow Java to run on the VES. The covariant design is not thought to be the best design in general, but it was chosen in the interest of broad reach.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx&quot;&gt;Rick Byers said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve heard that Bill Joy, one of the original Java designers, has since said that he tried to remove array covariance in 1995 but wasn&apos;t able to do it in time, and has regretted having it in Java ever since.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Anders Hejlsberg (&lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;chief architect&lt;/a&gt; of C#) &lt;a href=&quot;http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/&quot;&gt;said in this video&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This isn&apos;t type safe. A lot of people maybe don&apos;t even realize that there&apos;s a hole there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://ericlippert.com/&quot;&gt;Eric Lippert&lt;/a&gt; (member of C# design team) &lt;a href=&quot;http://www.informit.com/articles/article.aspx?p=2425867&quot;&gt;put array covariance the top 1 of 10 worst C# features&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C# 1.0 has unsafe array covariance not because the designers of C# thought that the scenario was particularly compelling, but rather because the Common Language Runtime (CLR) has the feature in its type system, so C# gets it &quot;for free.&quot; The CLR has it because Java has this feature; the CLR team wanted to design a runtime that could implement Java efficiently, should that become necessary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a C# language feature that should never be used.&lt;/p&gt;
&lt;h2&gt;Variances in .NET and LINQ&lt;/h2&gt;
&lt;p&gt;The following LINQ query finds the generic delegate types and interfaces with variant type parameters in .NET core library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TypesWithVariance()
{
    Assembly coreLibrary = typeof(object).Assembly;
    coreLibrary.GetExportedTypes()
        .Where(type =&amp;gt; type.GetGenericArguments().Any(typeArgument =&amp;gt;
        {
            GenericParameterAttributes attributes = typeArgument.GenericParameterAttributes;
            return attributes.HasFlag(GenericParameterAttributes.Covariant)
                || attributes.HasFlag(GenericParameterAttributes.Contravariant);
        }))
        .OrderBy(type =&amp;gt; type.FullName)
        .WriteLines();
        // System.Action`1[T]
        // System.Action`2[T1,T2]
        // System.Action`3[T1,T2,T3]
        // System.Action`4[T1,T2,T3,T4]
        // System.Action`5[T1,T2,T3,T4,T5]
        // System.Action`6[T1,T2,T3,T4,T5,T6]
        // System.Action`7[T1,T2,T3,T4,T5,T6,T7]
        // System.Action`8[T1,T2,T3,T4,T5,T6,T7,T8]
        // System.Collections.Generic.IComparer`1[T]
        // System.Collections.Generic.IEnumerable`1[T]
        // System.Collections.Generic.IEnumerator`1[T]
        // System.Collections.Generic.IEqualityComparer`1[T]
        // System.Collections.Generic.IReadOnlyCollection`1[T]
        // System.Collections.Generic.IReadOnlyList`1[T]
        // System.Comparison`1[T]
        // System.Converter`2[TInput,TOutput]
        // System.Func`1[TResult]
        // System.Func`2[T,TResult]
        // System.Func`3[T1,T2,TResult]
        // System.Func`4[T1,T2,T3,TResult]
        // System.Func`5[T1,T2,T3,T4,TResult]
        // System.Func`6[T1,T2,T3,T4,T5,TResult]
        // System.Func`7[T1,T2,T3,T4,T5,T6,TResult]
        // System.Func`8[T1,T2,T3,T4,T5,T6,T7,TResult]
        // System.Func`9[T1,T2,T3,T4,T5,T6,T7,T8,TResult]
        // System.IComparable`1[T]
        // System.IObservable`1[T]
        // System.IObserver`1[T]
        // System.IProgress`1[T]
        // System.Predicate`1[T]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Under System.Linq namespace, there are also a number of generic interfaces with variance: IGrouping&amp;lt;out TKey, out TElement&amp;gt;, IQueryable&amp;lt;out T&amp;gt;, IOrderedQueryable&amp;lt;out T&amp;gt;. MSDN has a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd799517#VariantList&quot;&gt;List of Variant Generic Interface and Delegate Types&lt;/a&gt;, but it is inaccurate. For example, it says TElement is covariant for IOrderedEnumerable&amp;lt;TElement&amp;gt;, but actually not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For local sequential LINQ, as fore mentioned, T is covariant for IEnumerable&amp;lt;T&amp;gt;. Here is the full story:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    /// &amp;lt;summary&amp;gt;Exposes the enumerator, which supports a simple iteration over a collection of a specified type.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
    {
        T Current { get; } // T is covariant for get_Current: () –&amp;gt; T.
    }

    /// &amp;lt;summary&amp;gt;Exposes the enumerator, which supports a simple iteration over a collection of a specified type.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); // T is covariant for IEnumerator&amp;lt;T&amp;gt;, so T is covariant for () -&amp;gt; IEnumerator&amp;lt;T&amp;gt;.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, IEnumerator&amp;lt;T&amp;gt;’s type parameter is only used by its Current property’s getter, which can be viewed as a get_Current function of type () –&amp;gt; T, and IEnumerator&amp;lt;T&amp;gt; can be viewed as a wrapper of () –&amp;gt; T function. Since T is covariance for () –&amp;gt; T function, T is also covariant for IEnumerator&amp;lt;T&amp;gt; wrapper. Then, in IEnumerable&amp;lt;T&amp;gt;, T is only used by GetEnumerator method returning IEnumerator&amp;lt;T&amp;gt;. Regarding IEnumerator&amp;lt;T&amp;gt; is a simple wrapper of () –&amp;gt; T function, GetEnumerator can be virtually viewed as a higher-order function returning () –&amp;gt; T function, Therefore, GetEnumerator’s function type () –&amp;gt; IEnumerator&amp;lt;T&amp;gt; can be virtually viewed as higher-order function type () –&amp;gt; () –&amp;gt; T. And similarly, IEnumerable&amp;lt;T&amp;gt; can be viewed as a wrapper of this () –&amp;gt; () –&amp;gt; T function. Since T is still covariant for () –&amp;gt; () –&amp;gt; T, T is also covariance for IEnumerable&amp;lt;T&amp;gt; wrapper. This brings convenience to LINQ queries. For example, the following LINQ query method concatenates 2 IEnumerable&amp;lt;T&amp;gt; instances:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code demonstrates the implicit conversion enabled by the out modifier in the IEnumerable&amp;lt;T&amp;gt; definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToObjects(IEnumerable&amp;lt;Base&amp;gt; enumerableOfBase, IEnumerable&amp;lt;Derived&amp;gt; enumerableOfDerived)
{
    enumerableOfBase = enumerableOfBase.Concat(enumerableOfDerived);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For local Parallel LINQ, ParallelQuery&amp;lt;T&amp;gt; is a class instead of interface, so there T is not variant. Again, variance of type parameter is for function type, including non-generic delegate type, generic delegate type and generic interface. Class can have function implementation so variances do not apply.&lt;/p&gt;
&lt;p&gt;For remote LINQ, here is the definition of IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    /// &amp;lt;summary&amp;gt;Provides functionality to evaluate queries against a specific data source wherein the type of the data is known.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here T is only used for the member inherited from IEnumerable&amp;lt;T&amp;gt;, so apparently, T remains covariant for IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (10) Query Expression</title><link>https://dixin.github.io/posts/functional-csharp-query-expression-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-query-expression-7/</guid><description>C# 3.0 introduces query expression, a SQL-like query syntactic sugar for query methods composition.</description><pubDate>Sun, 10 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-query-expression&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-query-expression&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces query expression, a SQL-like query syntactic sugar for query methods composition.&lt;/p&gt;
&lt;h2&gt;Syntax and compilation&lt;/h2&gt;
&lt;p&gt;The following is the syntax of query expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from [Type] identifier in source
[from [Type] identifier in source]
[join [Type] identifier in source on expression equals expression [into identifier]]
[let identifier = expression]
[where predicate]
[orderby ordering [ascending | descending][, ordering [ascending | descending], …]]
select expression | group expression by key [into identifier]
[continuation]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It introduces new language keywords to C#, which are called query keywords:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;from&lt;/li&gt;
&lt;li&gt;join, on, equals&lt;/li&gt;
&lt;li&gt;let&lt;/li&gt;
&lt;li&gt;where&lt;/li&gt;
&lt;li&gt;orderby, ascending, descending&lt;/li&gt;
&lt;li&gt;select&lt;/li&gt;
&lt;li&gt;group, by&lt;/li&gt;
&lt;li&gt;into&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Query expression is compiled to query method calls at compile time:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;672&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Query expression&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Query method&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;single from clause with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;multiple from clauses with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;SelectMany&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Type in from/join clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Cast&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause without into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause with into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupJoin&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;let clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;where clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Where&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with or without ascending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderBy, ThenBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderByDescending, ThenByDescending&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;group clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;into with continuation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Nested query&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;It is already demonstrated how query expression syntax works for LINQ. Actually, this syntax is not specific for LINQ query or IEnumerable&amp;lt;T&amp;gt;/ParallelQuery&amp;lt;T&amp;gt;/IQueryable&amp;lt;T&amp;gt; types, but a &lt;a href=&quot;https://www.infoq.com/interviews/LINQ-Erik-Meijer&quot;&gt;general C# syntactic sugar&lt;/a&gt;. Take select clause (compiled to Select method call) as example, it can work for any type, as long as the compiler can find a Select instance method or extension method for that type. Take int as example, it does not have a Select instance method, so the following extension method can be defined to accept a selector function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Int32Extensions
{
    internal static TResult Select&amp;lt;TResult&amp;gt;(this int int32, Func&amp;lt;int, TResult&amp;gt; selector) =&amp;gt; 
        selector(int32);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now select clause of query expression syntax can be applied to int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryExpression
{
    internal static void SelectInt32()
    {
        int mapped1 = from zero in default(int) // 0
                      select zero; // 0
        double mapped2 = from three in 1 + 2 // 3
                         select Math.Sqrt(three + 1); // 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And they are compiled to above Select extension method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledSelectInt32()
{
    int mapped1 = Int32Extensions.Select(default, zero =&amp;gt; zero); // 0
    double mapped2 = Int32Extensions.Select(1 + 2, three =&amp;gt; Math.Sqrt(three + 1)); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More generally, Select method can be defined for any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ObjectExtensions
{
    internal static TResult Select&amp;lt;TSource, TResult&amp;gt;(this TSource value, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; 
        selector(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now select clause and Select method can be applied to any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectGuid()
{
    string mapped = from newGuid in Guid.NewGuid()
                    select newGuid.ToString();
}

internal static void CompiledSelectGuid()
{
    string mapped = ObjectExtensions.Select(Guid.NewGuid(), newGuid =&amp;gt; newGuid.ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some tools, like &lt;a href=&quot;https://www.jetbrains.com/resharper&quot;&gt;Resharper&lt;/a&gt;, a powerful &lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/EA4AC039-1B5C-4D11-804E-9BEDE2E63ECF&quot;&gt;extension for Visual Studio&lt;/a&gt;, can help converting query expressions to query methods at design time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-10-Que_851B/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/C-Functional-Programming-In-Depth-10-Que_851B/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Query expression pattern&lt;/h2&gt;
&lt;p&gt;To enable all the query keywords for a certain type, a set of query methods are required to be provided. The following interfaces demonstrate the signatures of the required methods for a locally queryable type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ILocal
{
    ILocal&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
}

public interface ILocal&amp;lt;T&amp;gt; : ILocal
{
    ILocal&amp;lt;T&amp;gt; Where(Func&amp;lt;T, bool&amp;gt; predicate);

    ILocal&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Func&amp;lt;T, TResult&amp;gt; selector);

    ILocal&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        Func&amp;lt;T, ILocal&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;T, TSelector, TResult&amp;gt; resultSelector);

    ILocal&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
        ILocal&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, TInner, TResult&amp;gt; resultSelector);

    ILocal&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
        ILocal&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, ILocal&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector);

    IOrderedLocal&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    IOrderedLocal&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    ILocal&amp;lt;ILocalGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    ILocal&amp;lt;ILocalGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
        Func&amp;lt;T, TKey&amp;gt; keySelector, Func&amp;lt;T, TElement&amp;gt; elementSelector);
}

public interface IOrderedLocal&amp;lt;T&amp;gt; : ILocal&amp;lt;T&amp;gt;
{
    IOrderedLocal&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    IOrderedLocal&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);
}

public interface ILocalGroup&amp;lt;TKey, T&amp;gt; : ILocal&amp;lt;T&amp;gt;
{
    TKey Key { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All above methods return ILocalSource&amp;lt;T&amp;gt;, so these methods or query expression clauses can be easily composed. The above query methods are represented as instance methods. As fore mentioned, extension methods work too. This is called the query expression pattern. Similarly, the following interfaces demonstrate the signatures of the required query methods for a remotely queryable type, which replaces all function parameters with expression tree parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IRemote
{
    IRemote&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
}

public interface IRemote&amp;lt;T&amp;gt; : IRemote
{
    IRemote&amp;lt;T&amp;gt; Where(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; predicate);

    IRemote&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TResult&amp;gt;&amp;gt; selector);

    IRemote&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TSelector&amp;gt;&amp;gt;&amp;gt; selector,
        Expression&amp;lt;Func&amp;lt;T, TSelector, TResult&amp;gt;&amp;gt; resultSelector);

    IRemote&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
        IRemote&amp;lt;TInner&amp;gt; inner,
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
        Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
        Expression&amp;lt;Func&amp;lt;T, TInner, TResult&amp;gt;&amp;gt; resultSelector);

    IRemote&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
        IRemote&amp;lt;TInner&amp;gt; inner,
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; outerKeySelector,
        Expression&amp;lt;Func&amp;lt;TInner, TKey&amp;gt;&amp;gt; innerKeySelector,
        Expression&amp;lt;Func&amp;lt;T, IRemote&amp;lt;TInner&amp;gt;, TResult&amp;gt;&amp;gt; resultSelector);

    IOrderedRemote&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IOrderedRemote&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IRemote&amp;lt;IRemoteGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
        Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector, Expression&amp;lt;Func&amp;lt;T, TElement&amp;gt;&amp;gt; elementSelector);
}

public interface IOrderedRemote&amp;lt;T&amp;gt; : IRemote&amp;lt;T&amp;gt;
{
    IOrderedRemote&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);

    IOrderedRemote&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TKey&amp;gt;&amp;gt; keySelector);
}

public interface IRemoteGroup&amp;lt;TKey, T&amp;gt; : IRemote&amp;lt;T&amp;gt;
{
    TKey Key { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates how the query expression syntax is enabled for ILocal&amp;lt;T&amp;gt; and IRemote&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalQuery(ILocal&amp;lt;Uri&amp;gt; uris)
{
    ILocal&amp;lt;string&amp;gt; query =
        from uri in uris
        where uri.IsAbsoluteUri // ILocal.Where and anonymous method.
        group uri by uri.Host into hostUris // ILocal.GroupBy and anonymous method.
        orderby hostUris.Key // ILocal.OrderBy and anonymous method.
        select hostUris.ToString(); // ILocal.Select and anonymous method.
}

internal static void RemoteQuery(IRemote&amp;lt;Uri&amp;gt; uris)
{
    IRemote&amp;lt;string&amp;gt; query =
        from uri in uris
        where uri.IsAbsoluteUri // IRemote.Where and expression tree.
        group uri by uri.Host into hostUris // IRemote.GroupBy and expression tree.
        orderby hostUris.Key // IRemote.OrderBy and expression tree.
        select hostUris.ToString(); // IRemote.Select and expression tree.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their syntax looks identical but they are compiled to different query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledLocalQuery(ILocal&amp;lt;Uri&amp;gt; uris)
{
    ILocal&amp;lt;string&amp;gt; query = uris
        .Where(uri =&amp;gt; uri.IsAbsoluteUri) // ILocal.Where and anonymous method.
        .GroupBy(uri =&amp;gt; uri.Host) // ILocal.GroupBy and anonymous method.
        .OrderBy(hostUris =&amp;gt; hostUris.Key) // ILocal.OrderBy and anonymous method.
        .Select(hostUris =&amp;gt; hostUris.ToString()); // ILocal.Select and anonymous method.
}

internal static void CompiledRemoteQuery(IRemote&amp;lt;Uri&amp;gt; uris)
{
    IRemote&amp;lt;string&amp;gt; query = uris
        .Where(uri =&amp;gt; uri.IsAbsoluteUri) // IRemote.Where and expression tree.
        .GroupBy(uri =&amp;gt; uri.Host) // IRemote.GroupBy and expression tree.
        .OrderBy(hostUris =&amp;gt; hostUris.Key) // IRemote.OrderBy and expression tree.
        .Select(hostUris =&amp;gt; hostUris.ToString()); // IRemote.Select and expression tree.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides 3 sets of built-in query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt; represents local sequential data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.Enumerable&lt;/li&gt;
&lt;li&gt;ParallelQuery&amp;lt;T&amp;gt; represents local parallel data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.ParallelEnumerable&lt;/li&gt;
&lt;li&gt;IQueryable&amp;lt;T&amp;gt; represents remote data source and query, its query expression pattern is implemented by extension methods provided by System.Linq.Queryable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So query expression works for these 3 kinds of LINQ. The details of query expression usage and compilation is covered by the LINQ to Objects chapter.&lt;/p&gt;
&lt;h2&gt;Query expression vs. query method&lt;/h2&gt;
&lt;p&gt;Query expression is compiled to query method calls, either syntax can be used to build a LINQ query. However, query expression does not cover all query methods and their overloads. For example, Skip and Take query are not supported by query expression syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

        public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, int count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following query implement filtering and mapping queries with query expression, but Skip and Take have to be called as query methods, so it is in a hybrid syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void QueryExpressionAndMethod(IEnumerable&amp;lt;Product&amp;gt; products)
{
    IEnumerable&amp;lt;string&amp;gt; query =
        (from product in products
         where product.ListPrice &amp;gt; 0
         select product.Name)
        .Skip(20)
        .Take(10);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is, Where query method for IEnumerable&amp;lt;T&amp;gt; has 2 overloads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first Where overload is supported by query expression where clause, the second overload is not.&lt;/p&gt;
&lt;p&gt;All query expression syntax and all query methods will be discussed in detail in later chapters. Query expression is also a tool to build general functional workflow, which will also be discussed in the Category Theory chapter.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (9) Function Composition and Chaining</title><link>https://dixin.github.io/posts/functional-csharp-function-composition-and-method-chaining-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-composition-and-method-chaining-7/</guid><description>In object-oriented programming, objects can be composed to build more complex object. Similarly, in functional programming. functions can be composed to build more complex function.</description><pubDate>Sat, 09 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-function-composition-and-method-chaining&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-function-composition-and-method-chaining&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In object-oriented programming, objects can be composed to build more complex object. Similarly, in functional programming. functions can be composed to build more complex function.&lt;/p&gt;
&lt;h2&gt;Forward and backward composition&lt;/h2&gt;
&lt;p&gt;It is very common to pass a function’s output to another function as input:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OutputAsInput()
{
    string input = &quot;-2.0&quot;;
    int output1 = int.Parse(input); // string -&amp;gt; int
    int output2 = Math.Abs(output1); // int -&amp;gt; int
    double output3 = Convert.ToDouble(output2); // int -&amp;gt; double
    double output4 = Math.Sqrt(output3); // double -&amp;gt; double
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So above Abs function and Sqrt function can be combined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// string -&amp;gt; double
internal static double Composition(string input) =&amp;gt; 
    Math.Sqrt(Convert.ToDouble(Math.Abs(int.Parse(input))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above function is the composition of int.Parse, Math.Abs Convert.ToDouble, and Math.Sqrt. Its return value is the last function Math.Sqrt’s return value. Generally, a forward composition operator and a backward composition operator can be defined as extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static Func&amp;lt;T, TResult2&amp;gt; After&amp;lt;T, TResult1, TResult2&amp;gt;(
        this Func&amp;lt;TResult1, TResult2&amp;gt; function2, Func&amp;lt;T, TResult1&amp;gt; function1) =&amp;gt;
            value =&amp;gt; function2(function1(value));

    public static Func&amp;lt;T, TResult2&amp;gt; Then&amp;lt;T, TResult1, TResult2&amp;gt;( // Before.
        this Func&amp;lt;T, TResult1&amp;gt; function1, Func&amp;lt;TResult1, TResult2&amp;gt; function2) =&amp;gt;
            value =&amp;gt; function2(function1(value));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above functions can be composed by calling either After or Then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Compose()
{
    Func&amp;lt;string, int&amp;gt; parse = int.Parse; // string -&amp;gt; int
    Func&amp;lt;int, int&amp;gt; abs = Math.Abs; // int -&amp;gt; int
    Func&amp;lt;int, double&amp;gt; convert = Convert.ToDouble; // int -&amp;gt; double
    Func&amp;lt;double, double&amp;gt; sqrt = Math.Sqrt; // double -&amp;gt; double

    // string -&amp;gt; double
    Func&amp;lt;string, double&amp;gt; composition1 = sqrt.After(convert).After(abs).After(parse);
    composition1(&quot;-2.0&quot;).WriteLine(); // 1.4142135623731

    // string -&amp;gt; double
    Func&amp;lt;string, double&amp;gt; composition2 = parse.Then(abs).Then(convert).Then(sqrt);
    composition2(&quot;-2.0&quot;).WriteLine(); // 1.4142135623731
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The LINQ query methods, like Where, Skip, Take, cannot be directly composed like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        // (IEnumerable&amp;lt;TSource&amp;gt;, TSource -&amp;gt; bool) -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        // (IEnumerable&amp;lt;TSource&amp;gt;, int) -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
        public static IEnumerable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

        // (IEnumerable&amp;lt;TSource&amp;gt;, int) -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
        public static IEnumerable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, int count);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They all return IEnumerable&amp;lt;T&amp;gt;, but they are all 2-arity, so one function cannot be called directly with another function’s output. To compose these functions, they need to be partially applied (called) with the parameter other than IEnumerable&amp;lt;T&amp;gt;, so that they become 1-arity functions, which can be composed. To do this, create the following helper functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Func&amp;lt;TSource, bool&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
internal static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; Where&amp;lt;TSource&amp;gt;(
    Func&amp;lt;TSource, bool&amp;gt; predicate) =&amp;gt; source =&amp;gt; Enumerable.Where(source, predicate);

// int -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
internal static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; Skip&amp;lt;TSource&amp;gt;(
    int count) =&amp;gt; source =&amp;gt; Enumerable.Skip(source, count);

// int -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
internal static Func&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;, IEnumerable&amp;lt;TSource&amp;gt;&amp;gt; Take&amp;lt;TSource&amp;gt;(
    int count) =&amp;gt; source =&amp;gt; Enumerable.Take(source, count);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are curried from the original query methods, with the first parameter and second parameter swapped. After being called with a argument, they return IEnumerable&amp;lt;TSource&amp;gt; –&amp;gt; IEnumerable&amp;lt;TSource&amp;gt; functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqWithPartialApplication()
{
    // IEnumerable&amp;lt;TSource&amp;gt; -&amp;gt; IEnumerable&amp;lt;TSource&amp;gt;
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; where = Where&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0);
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; skip = Skip&amp;lt;int&amp;gt;(1);
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; take = Take&amp;lt;int&amp;gt;(2);

    IEnumerable&amp;lt;int&amp;gt; query = take(skip(where(new int[] { 4, 3, 2, 1, 0, -1 })));
    foreach (int result in query) // Execute query.
    {
        result.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So these LINQ query methods can be composed through the curried helper functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ComposeLinqWithPartialApplication()
{
    Func&amp;lt;IEnumerable&amp;lt;int&amp;gt;, IEnumerable&amp;lt;int&amp;gt;&amp;gt; composition =
        Where&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0)
        .Then(Skip&amp;lt;int&amp;gt;(1))
        .Then(Take&amp;lt;int&amp;gt;(2));

    IEnumerable&amp;lt;int&amp;gt; query = composition(new int[] { 4, 3, 2, 1, 0, -1 });
    foreach (int result in query) // Execute query.
    {
        result.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Forward pipeline&lt;/h2&gt;
&lt;p&gt;The forward pipe operator, which forwards argument to call function, can also help function composition. It can also be defined as extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static TResult Forward&amp;lt;T, TResult&amp;gt;(this T value, Func&amp;lt;T, TResult&amp;gt; function) =&amp;gt;
        function(value);
}

public static partial class ActionExtensions
{
    public static void Forward&amp;lt;T&amp;gt;(this T value, Action&amp;lt;T&amp;gt; function) =&amp;gt;
        function(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates how to use it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Forward()
{
    &quot;-2&quot;
        .Forward(int.Parse) // string -&amp;gt; int
        .Forward(Math.Abs) // int -&amp;gt; int
        .Forward(Convert.ToDouble) // int -&amp;gt; double
        .Forward(Math.Sqrt) // double -&amp;gt; double
        .Forward(Console.WriteLine); // double -&amp;gt; void

    // Equivalent to:
    Console.WriteLine(Math.Sqrt(Convert.ToDouble(Math.Abs(int.Parse(&quot;-2&quot;)))));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Forward extension method can be useful with the null conditional operator to simplify the code, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForwardAndNullConditional(IDictionary&amp;lt;string, object&amp;gt; dictionary, string key)
{
    object value = dictionary[key];
    DateTime? dateTime1;
    if (value != null)
    {
        dateTime1 = Convert.ToDateTime(value);
    }
    else
    {
        dateTime1 = null;
    }

    // Equivalent to:
    DateTime? dateTime2 = dictionary[key]?.Forward(Convert.ToDateTime);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This operator can alkso help composing LINQ query methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ForwardLinqWithPartialApplication()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 };
    IEnumerable&amp;lt;int&amp;gt; query = source
        .Forward(Where&amp;lt;int&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0))
        .Forward(Skip&amp;lt;int&amp;gt;(1))
        .Forward(Take&amp;lt;int&amp;gt;(2));
    foreach (int result in query) // Execute query.
    {
        result.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Fluent method chaining&lt;/h2&gt;
&lt;p&gt;In contrast of static method, instance methods can be easily composed by just chaining the calls, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InstanceMethodChaining(string @string)
{
    string result = @string.TrimStart().Substring(1, 10).Replace(&quot;a&quot;, &quot;b&quot;).ToUpperInvariant();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above functions are fluently composed because each of them returns an instance of that type, so that another instance method can be called fluently. Unfortunately, many APIs are not designed following this pattern. Take List&amp;lt;T&amp;gt; as example, here are some of its methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public class List&amp;lt;T&amp;gt; : IList&amp;lt;T&amp;gt;, IList, IReadOnlyList&amp;lt;T&amp;gt;
    {
        public void Add(T item);

        public void Clear();

        public void ForEach(Action&amp;lt;T&amp;gt; action);

        public void Insert(int index, T item);

        public void RemoveAt(int index);

        public void Reverse();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods return void, so they cannot be composed by chaining. These existing APIs cannot be changed, but the extension method syntactic sugar enables virtually adding new methods to an existing type. So fluent methods can be “added” to List&amp;lt;T&amp;gt; by defining extension methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ListExtensions
{
    public static List&amp;lt;T&amp;gt; FluentAdd&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, T item)
    {
        list.Add(item);
        return list;
    }

    public static List&amp;lt;T&amp;gt; FluentClear&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)
    {
        list.Clear();
        return list;
    }

    public static List&amp;lt;T&amp;gt; FluentForEach&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, Action&amp;lt;T&amp;gt; action)
    {
        list.ForEach(action);
        return list;
    }

    public static List&amp;lt;T&amp;gt; FluentInsert&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, int index, T item)
    {
        list.Insert(index, item);
        return list;
    }

    public static List&amp;lt;T&amp;gt; FluentRemoveAt&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list, int index)
    {
        list.RemoveAt(index);
        return list;
    }

    public static List&amp;lt;T&amp;gt; FluentReverse&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)
    {
        list.Reverse();
        return list;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By always returning the first parameter, these extension methods can be composed by fluent chaining, as if they are instance methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ListFluentExtensions()
{
    List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt;() { 1, 2, 3, 4, 5 }
        .FluentAdd(1)
        .FluentInsert(0, 0)
        .FluentRemoveAt(1)
        .FluentReverse()
        .FluentForEach(value =&amp;gt; value.WriteLine())
        .FluentClear();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, these extension method calls are compiled to normal static method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void CompiledListExtensions()
{
    List&amp;lt;int&amp;gt; list = 
        ListExtensions.FluentClear(
            ListExtensions.FluentForEach(
                ListExtensions.FluentReverse(
                    ListExtensions.FluentRemoveAt(
                        ListExtensions.FluentInsert(
                            ListExtensions.FluentAdd(
                                new List&amp;lt;int&amp;gt;() { 1, 2, 3, 4, 5 }, 1), 
                            0, 0), 
                        1)
                    ), 
                value =&amp;gt; value).WriteLine()
            );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;LINQ query methods composition&lt;/h3&gt;
&lt;p&gt;In C#, LINQ query methods are composed better with this fluent method chaining approach. IEnumerable&amp;lt;T&amp;gt; is provided by .NET Framework 2.0 to represent a sequence of values. It only has a GetEnumerator method, and another version of GetEnumerator method inherited from IEnumerable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections
{
    public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }
}

namespace System.Collections.Generic
{
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When .NET Framework 3.5 introduces LINQ, IEnumerable&amp;lt;T&amp;gt; is used to represent local LINQ data source and query. All the query methods except Empty, Range, Repeat, are defined as extension methods in System.Linq.Enumerable type. Many query methods, like fore mentioned Where, Skip, Take, Select, returns IEnumerable&amp;lt;T&amp;gt;, so that the query methods can be composed by fluent chaining.&lt;/p&gt;
&lt;p&gt;The fore mentioned OrderBy method is slightly different. It accepts IEnumerable&amp;lt;T&amp;gt; but returns IOrderedEnumerable&amp;lt;T&amp;gt;. There are 4 ordering query methods relevant to IOrderedEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(
            Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
    }

    public static class Enumerable
    {
        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IOrderedEnumerable&amp;lt;T&amp;gt;is derived from IEnumerable&amp;lt;T&amp;gt;, so ThenBy and ThenByDescending can only be composed after OrderBy and OrderByDescending, which logically makes sense.&lt;/p&gt;
&lt;p&gt;There are also a few methods returning a single value instead of IEnumerable&amp;lt;T&amp;gt;, like First, Last, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Enumerable
{
    public static TSource First&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);

    public static TSource Last&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usually they terminate the LINQ query, since other query methods cannot be composed after these methods, unless the returned single value is still a IEnumerable&amp;lt;T&amp;gt; instance.&lt;/p&gt;
&lt;p&gt;There are other parities of LINQ to Objects query represented by IEnumerable&amp;lt;T&amp;gt;, like Parallel LINQ to Objects query represented by ParallelQuery&amp;lt;T&amp;gt;, the remote LINQ query represented by IQueryable&amp;lt;T&amp;gt;, their query methods all follow this pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class ParallelEnumerable
    {
        public static ParallelQuery&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static OrderedParallelQuery&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static ParallelQuery&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this ParallelQuery&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        // Other members.
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The details of IEnumerable&amp;lt;T&amp;gt; queries are covered by the LINQ to Objects chapter, ParallelQuery&amp;lt;T&amp;gt; queries are covered by the Parallel LINQ chapter, and IQueryable&amp;lt;T&amp;gt; queries are covered by the LINQ to Entities chapter.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (8) Higher-order Function, Currying and First Class Function</title><link>https://dixin.github.io/posts/functional-csharp-higher-order-function-currying-and-first-class-function-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-higher-order-function-currying-and-first-class-function-7/</guid><description>is a function accepting one or more function parameters as input, or returning a function as output. The other functions are</description><pubDate>Fri, 08 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-higher-order-function-currying-and-first-class-function&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-higher-order-function-currying-and-first-class-function&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;First order and higher-order function&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Higher-order_function&quot;&gt;Higher-order function&lt;/a&gt; is a function accepting one or more function parameters as input, or returning a function as output. The other functions are called first-order functions. C# supports higher-order function from the beginning. Generally, C# function can have almost any data type and function type as its input types and output type, except:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static types, like System.Convert, System.Math, etc., because they cannot be instantiated.&lt;/li&gt;
&lt;li&gt;Special types, like fore mentioned System.Void.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A first-order function can take normal data value as input and output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data { }

internal static partial class Functions
{
    internal static Data FirstOrder(Data value)
    {
        return value;
    }

    internal static void CallFirstOrder()
    {
        Data input = default;
        Data output = FirstOrder(input);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A higher-order function can be defined by replacing above data type with a function type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void Function();

internal static partial class Functions
{
    internal static Function NamedHigherOrder(Function value)
    {
        return value;
    }

    internal static void CallHigherOrder()
    {
        Function input = default;
        Function output = NamedHigherOrder(input);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above HigherOrder is a named higher-order function. Anonymous higher-order functions can also be easily represented with lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LambdaHigherOrder()
{
    Action firstOrder1 = () =&amp;gt; nameof(LambdaHigherOrder).WriteLine();
    firstOrder1(); // LambdaHigherOrder

    // (() -&amp;gt; void) -&amp;gt; void
    // Input: function of type () -&amp;gt; void. Output: void.
    Action&amp;lt;Action&amp;gt; higherOrder1 = action =&amp;gt; action();
    higherOrder1(firstOrder1); // firstOrder1
    higherOrder1(() =&amp;gt; nameof(LambdaHigherOrder).WriteLine()); // LambdaHigherOrder

    Func&amp;lt;int&amp;gt; firstOrder2 = () =&amp;gt; 1;
    firstOrder2().WriteLine(); // 1

    // () -&amp;gt; (() -&amp;gt; int)
    // Input: none. Output: function of type () -&amp;gt; int.
    Func&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; higherOrder2 = () =&amp;gt; firstOrder2;
    Func&amp;lt;int&amp;gt; output2 = higherOrder2();
    output2().WriteLine(); // 1

    // int -&amp;gt; (() -&amp;gt; int)
    // Input: value of type int. Output: function of type () -&amp;gt; int.
    Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt; higherOrder3 = int32 =&amp;gt;
        (() =&amp;gt; int32 + 1);
    Func&amp;lt;int&amp;gt; output3 = higherOrder3(1);
    output3().WriteLine(); // 2

    // (() -&amp;gt; void, () -&amp;gt; int) -&amp;gt; (() -&amp;gt; bool)
    // Input: function of type () -&amp;gt; void, function of type () -&amp;gt; int. Output: function of type () -&amp;gt; bool.
    Func&amp;lt;Action, Func&amp;lt;int&amp;gt;, Func&amp;lt;bool&amp;gt;&amp;gt; higherOrder4 = (action, int32Factory) =&amp;gt;
    {
        action();
        return () =&amp;gt; int32Factory() &amp;gt; 0;
    };
    Func&amp;lt;bool&amp;gt; output4 = higherOrder4(firstOrder1, firstOrder2); // LambdaHigherOrder
    output4().WriteLine(); // True
    output4 = higherOrder4(() =&amp;gt; nameof(LambdaHigherOrder).WriteLine(), () =&amp;gt; 0); // LambdaHigherOrder
    output4().WriteLine(); // False
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These higher-order functions can be defined and called with IIFE syntax, without any function name involved:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnonymousHigherOrder()
{
    // (() -&amp;gt; void) -&amp;gt; void
    new Action&amp;lt;Action&amp;gt;(action =&amp;gt; action())(
        () =&amp;gt; nameof(AnonymousHigherOrder).WriteLine());

    // () -&amp;gt; (() -&amp;gt; int)
    Func&amp;lt;int&amp;gt; output2 = new Func&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;(() =&amp;gt; (() =&amp;gt; 1))();
    output2().WriteLine(); // 1

    // int -&amp;gt; (() -&amp;gt; int)
    Func&amp;lt;int&amp;gt; output3 = new Func&amp;lt;int, Func&amp;lt;int&amp;gt;&amp;gt;(int32 =&amp;gt; (() =&amp;gt; int32 + 1))(1);
    output3().WriteLine(); // 2

    // (() -&amp;gt; int, () -&amp;gt; string) -&amp;gt; (() -&amp;gt; bool)
    Func&amp;lt;bool&amp;gt; output4 = new Func&amp;lt;Action, Func&amp;lt;int&amp;gt;, Func&amp;lt;bool&amp;gt;&amp;gt;((action, int32Factory) =&amp;gt;
    {
        action();
        return () =&amp;gt; int32Factory() &amp;gt; 0;
    })(() =&amp;gt; nameof(LambdaHigherOrder).WriteLine(), () =&amp;gt; 0);
    output4().WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides many built in higher-order functions, like Array.FindAll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public abstract class Array : ICollection, IEnumerable, IList, IStructuralComparable, IStructuralEquatable
    {
        public static T[] FindAll&amp;lt;T&amp;gt;(T[] array, Predicate&amp;lt;T&amp;gt; match);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It iterates all values in the input array, and call the match function for each value. If match function returns true, the value is added to the result array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FilterArray(Uri[] array)
{
    Uri[] notNull = Array.FindAll(array, uri =&amp;gt; uri != null);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Many LINQ query methods are higher-order functions, like fore mentioned Where, OrderBy, Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, LINQ query methods will be discussed in detail in the LINQ to Objects chapter.&lt;/p&gt;
&lt;h2&gt;Curry function&lt;/h2&gt;
&lt;p&gt;In the following example, first order function add2 simply adds 2 int values. Compare this function with the other higher-order function higherOrderAdd2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FirstOrderHigherOrder()
{
    // (int, int) -&amp;gt; int
    Func&amp;lt;int, int, int&amp;gt; add2 = (a, b) =&amp;gt; a + b;
    int add2Result = add2(1, 2);
    // int -&amp;gt; (int -&amp;gt; int)
    Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; higherOrderAdd2 = a =&amp;gt; new Func&amp;lt;int, int&amp;gt;(b =&amp;gt; a + b);
    Func&amp;lt;int, int&amp;gt; add1 = higherOrderAdd2(1); // Equivalent to: b =&amp;gt; 1 + b.
    int curriedAdd2Result = add1(2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first order function of type (int, int) –&amp;gt; int is straightforward. It accepts the first and the second int values, and returns their sum. The higher-order function of type int –&amp;gt; (int –&amp;gt; int) accepts only the first int value, and returns another function of type int –&amp;gt; int, which accepts the second int value and return the sum. Calling these functions are different too. Calling the first order function requires providing the first and second int values, and the result is directly returned. Calling the higher-order function requires only the first int value, it returns function which is a closure of the that int value. Then, calling the returned function requires providing the second int value, and the result is returned.&lt;/p&gt;
&lt;p&gt;Actually, for the higher-order function, its returned function type can be the inferred from the higher-order function type. So it can be simplified as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TypeInference()
{
    // (int, int) -&amp;gt; int
    Func&amp;lt;int, int, int&amp;gt; add2 = (a, b) =&amp;gt; a + b;
    int add2Result = add2(1, 2);
    // int -&amp;gt; (int -&amp;gt; int)
    Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2 = a =&amp;gt; b =&amp;gt; a + b;
    int curriedAdd2Result = curriedAdd2(1)(2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 functions represents the same algorithm but in different form. This kind of transformation from a 2-arity first order function of type (T1, T2) –&amp;gt; TResult) to a 1-arity higher-order function of type T1 –&amp;gt; (T2 –&amp;gt; TResult), is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Currying&quot;&gt;currying&lt;/a&gt;. The term &quot;currying&quot; is introduced by &lt;a href=&quot;http://en.wikipedia.org/wiki/Christopher_Strachey&quot;&gt;Christopher Strachey&lt;/a&gt; in 1967, which is the last name of mathematician and logician &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, the following function with 3 parameters can be curried into a sequence of 3 1-arity functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CurryFunc()
{
    // (int, int, int) -&amp;gt; int
    Func&amp;lt;int, int, int, int&amp;gt; add3 = (a, b, c) =&amp;gt; a + b + c;
    int add3Result = add3(1, 2, 3);
    // int -&amp;gt; int -&amp;gt; int -&amp;gt; int
    Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3 = a =&amp;gt; b =&amp;gt; c =&amp;gt; a + b + c;
    int curriedAdd3Result = curriedAdd3(1)(2)(3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, any N-arity function returning a value can be curried into a sequence of N 1-arity functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CurryFunc&amp;lt;T1, T2, T3, TN, TResult&amp;gt;()
{
    // (T1, T2, T3, ... TN) -&amp;gt; TResult
    Func&amp;lt;T1, T2, T3, /* T4, ... */ TN, TResult&amp;gt; function =
        (value1, value2, value3, /* ... */ valueN) =&amp;gt; default;
    // T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; ... TN -&amp;gt; TResult
    Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, /* Func&amp;lt;T4, ... */ Func&amp;lt;TN, TResult&amp;gt; /* ... */&amp;gt;&amp;gt;&amp;gt; curriedFunction =
        value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; /* value4 =&amp;gt; ... */ valueN =&amp;gt; default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above transformation can be wrapped as the following Curry extension methods for all Func delegate types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    // Transform (T1, T2) -&amp;gt; TResult
    // to T1 -&amp;gt; T2 -&amp;gt; TResult.
    public static Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, TResult&amp;gt; function) =&amp;gt; 
            value1 =&amp;gt; value2 =&amp;gt; function(value1, value2);

    // Transform (T1, T2, T3) -&amp;gt; TResult
    // to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; TResult.
    public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function) =&amp;gt; 
            value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);

    // Transform (T1, T2, T3, T4) =&amp;gt; TResult
    // to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; TResult.
    public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function) =&amp;gt; 
            value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now any function can be curried by just calling the Curry method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallCurry()
{
    // (int, int) -&amp;gt; int
    Func&amp;lt;int, int, int&amp;gt; add2 = (a, b) =&amp;gt; a + b;
    int add2Result = add2(1, 2);
    // int -&amp;gt; (int -&amp;gt; int)
    Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2 = add2.Curry();
    int curriedAdd2Result = curriedAdd2(1)(2);

    // (int, int, int) -&amp;gt; int
    Func&amp;lt;int, int, int, int&amp;gt; add3 = (a, b, c) =&amp;gt; a + b + c;
    int add3Result = add3(1, 2, 3);
    // int -&amp;gt; int -&amp;gt; int -&amp;gt; int
    Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3 = add3.Curry();
    int curriedAdd3Result = curriedAdd3(1)(2)(3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Function returning void can be curried too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CurryAction()
{
    // (int, int) -&amp;gt; void
    Action&amp;lt;int, int&amp;gt; traceAdd2 = (a, b) =&amp;gt; (a + b).WriteLine();
    traceAdd2(1, 2);
    // int -&amp;gt; int -&amp;gt; void
    Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt; curriedTraceAdd2 = a =&amp;gt; b =&amp;gt; (a + b).WriteLine();
    curriedTraceAdd2(1)(2);

    // (int, int, int) -&amp;gt; void
    Action&amp;lt;int, int, int&amp;gt; traceAdd3 = (a, b, c) =&amp;gt; (a + b + c).WriteLine();
    traceAdd3(1, 2, 3);
    // int -&amp;gt; int -&amp;gt; int -&amp;gt; void
    Func&amp;lt;int, Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt;&amp;gt; curriedTraceAdd3 = a =&amp;gt; b =&amp;gt; c =&amp;gt; (a + b + c).WriteLine();
    curriedTraceAdd3(1)(2)(3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, any N-arity function returning void can be curried into a sequence of N 1-arity functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CurryAction&amp;lt;T1, T2, T3, TN&amp;gt;()
{
    // (T1, T2, T3, ... TN) -&amp;gt; void
    Action&amp;lt;T1, T2, T3, /* T4, ... */ TN&amp;gt; function =
        (value1, value2, value3, /* ... */ valueN) =&amp;gt; { };
    // T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; ... TN -&amp;gt; void
    Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, /* Func&amp;lt;T4, ... */ Action&amp;lt;TN&amp;gt; /* ... */&amp;gt;&amp;gt;&amp;gt; curriedFunction =
        value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; /* value4 =&amp;gt; ... */ valueN =&amp;gt; { };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the above transformation can be wrapped as the following Curry extension methods for all Action delegate types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ActionExtensions
{
    // Transform (T1, T2) -&amp;gt; void
    // to T1 =&amp;gt; T2 -&amp;gt; void.
    public static Func&amp;lt;T1, Action&amp;lt;T2&amp;gt;&amp;gt; Curry&amp;lt;T1, T2&amp;gt;(
        this Action&amp;lt;T1, T2&amp;gt; function) =&amp;gt;
            value1 =&amp;gt; value2 =&amp;gt; function(value1, value2);

    // Transform (T1, T2, T3) -&amp;gt; void
    // to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; void.
    public static Func&amp;lt;T1, Func&amp;lt;T2, Action&amp;lt;T3&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3&amp;gt;(
        this Action&amp;lt;T1, T2, T3&amp;gt; function) =&amp;gt; value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);

    // Transform (T1, T2, T3, T4) -&amp;gt; void
    // to T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; void.
    public static Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Action&amp;lt;T4&amp;gt;&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, T4&amp;gt;(
        this Action&amp;lt;T1, T2, T3, T4&amp;gt; function) =&amp;gt;
            value1 =&amp;gt; value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Lambda operator associativity&lt;/h2&gt;
&lt;p&gt;As demonstrated above, in a lambda expression, if on the right side of the =&amp;gt; operator there is another lambda expression, the parenthesis for the right side lambda expression can be omitted. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OperatorAssociativity()
{
    // int -&amp;gt; (int -&amp;gt; int)
    Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2 = a =&amp;gt; (b =&amp;gt; a + b);
    // int -&amp;gt; (int -&amp;gt; (int -&amp;gt; int))
    Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3 = a =&amp;gt; (b =&amp;gt; (c =&amp;gt; a + b + c));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above functions are identical to the following functions without parenthesis:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OperatorAssociativity()
{
    // int -&amp;gt; int -&amp;gt; int
    Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; curriedAdd2 =  a =&amp;gt; b =&amp;gt; a + b;
    // int -&amp;gt; int -&amp;gt; int -&amp;gt; int
    Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3 = a =&amp;gt; b =&amp;gt; c =&amp;gt; a + b + c;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that the =&amp;gt; operator can be viewed as right associative.&lt;/p&gt;
&lt;p&gt;In some other functional languages, functions are curried by default. For example, in F#, it is unnecessary to explicitly define a function as curried:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let curriedAdd2: int -&amp;gt; (int -&amp;gt; int) = fun a -&amp;gt; (fun b -&amp;gt; a + b)
let add1: int -&amp;gt; int = curriedAdd2 1
let curriedAdd2esult: int = add1 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function is curried by default. The above code is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let add2: int -&amp;gt; int -&amp;gt; int = fun a b -&amp;gt; a + b
let add2Result: int = add2 1 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To explicitly define a uncurried function, tuple can be used to pass multiple values at one time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let add2Tuple: int * int -&amp;gt; int = fun (a, b) -&amp;gt; a + b
let add2TupleResult = add2Tuple (1, 2) // add2Tuple(Tuple.Create(1, 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_(programming_language)&quot;&gt;Haskell&lt;/a&gt; (that is the first name of &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;) works similarly as F#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- curriedAdd2 :: Num a =&amp;gt; a –&amp;gt; (a –&amp;gt; a)
curriedAdd2 = \a –&amp;gt; (\b -&amp;gt; a + b)
add1 = curriedAdd2 1
curriedAdd2Result = add1 2

-- add2 :: Num a =&amp;gt; a -&amp;gt; a -&amp;gt; a
add2 a b = a + b
add2Result = add2 1 2

-- add2Tuple :: Num a =&amp;gt; (a, a) -&amp;gt; a
add2Tuple (a, b) = a + b
add2TupleResult = add2Tuple (1, 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Partial apply function&lt;/h2&gt;
&lt;p&gt;Calling (or applying) a curried function with one argument, is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Partial_application&quot;&gt;partial application&lt;/a&gt;. Since any N-arity function can be curried, any N-arity function can also be partial applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    public static Func&amp;lt;T2, TResult&amp;gt; Partial&amp;lt;T1, T2, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, TResult&amp;gt; function, T1 value1) =&amp;gt; 
            value2 =&amp;gt; function(value1, value2);

    public static Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, TResult&amp;gt; function, T1 value1) =&amp;gt; 
            value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);

    public static Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
        this Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; function, T1 value1) =&amp;gt; 
            value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);

    // ...
}

public static partial class ActionExtensions
{
    public static Action&amp;lt;T2&amp;gt; Partial&amp;lt;T1, T2&amp;gt;(
        this Action&amp;lt;T1, T2&amp;gt; function, T1 value1) =&amp;gt;
            value2 =&amp;gt; function(value1, value2);

    public static Func&amp;lt;T2, Action&amp;lt;T3&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3&amp;gt;(
        this Action&amp;lt;T1, T2, T3&amp;gt; function, T1 value1) =&amp;gt;
            value2 =&amp;gt; value3 =&amp;gt; function(value1, value2, value3);

    public static Func&amp;lt;T2, Func&amp;lt;T3, Action&amp;lt;T4&amp;gt;&amp;gt;&amp;gt; Partial&amp;lt;T1, T2, T3, T4&amp;gt;(
        this Action&amp;lt;T1, T2, T3, T4&amp;gt; function, T1 value1) =&amp;gt;
            value2 =&amp;gt; value3 =&amp;gt; value4 =&amp;gt; function(value1, value2, value3, value4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PartialApplication()
{
    Func&amp;lt;int, int, int&amp;gt; add2 = (a, b) =&amp;gt; a + b;
    Func&amp;lt;int, int&amp;gt; add1 = add2.Partial(1);
    int add2Result = add1(2);

    Action&amp;lt;int, int&amp;gt; traceAdd2 = (a, b) =&amp;gt; (a + b).WriteLine();
    Action&amp;lt;int&amp;gt; traceAdd1 = traceAdd2.Partial(1);
    traceAdd1(2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In some other functional languages where functions are curried by default, functions are partially applied by default too.&lt;/p&gt;
&lt;h2&gt;Uncurry function&lt;/h2&gt;
&lt;p&gt;A sequence of N 1-arity functions can also be transformed back to a N-arity function. This is called uncurrying, which can be generally implemented For Func and Action delegate types as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FuncExtensions
{
    // Transform T1 -&amp;gt; T2 -&amp;gt; TResult
    // to (T1, T2) -&amp;gt; TResult.
    public static Func&amp;lt;T1, T2, TResult&amp;gt; Uncurry&amp;lt;T1, T2, TResult&amp;gt;(
        this Func&amp;lt;T1, Func&amp;lt;T2, TResult&amp;gt;&amp;gt; function) =&amp;gt; 
            (value1, value2) =&amp;gt; function(value1)(value2);

    // Transform T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; TResult
    // to (T1, T2, T3) -&amp;gt; TResult.
    public static Func&amp;lt;T1, T2, T3, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, TResult&amp;gt;(
        this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt; 
            (value1, value2, value3) =&amp;gt; function(value1)(value2)(value3);

    // Transform T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; TResult
    // to (T1, T2, T3, T4) -&amp;gt; TResult.
    public static Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; Uncurry&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(
        this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Func&amp;lt;T4, TResult&amp;gt;&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt; 
            (value1, value2, value3, value4) =&amp;gt; function(value1)(value2)(value3)(value4);

    // ...
}

public static partial class ActionExtensions
{
    // Transform T1 -&amp;gt; T2 -&amp;gt; void
    // to (T1, T2) -&amp;gt; void.
    public static Action&amp;lt;T1, T2&amp;gt; Uncurry&amp;lt;T1, T2&amp;gt;(
        this Func&amp;lt;T1, Action&amp;lt;T2&amp;gt;&amp;gt; function) =&amp;gt; (value1, value2) =&amp;gt;
            function(value1)(value2);

    // Transform T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; void
    // to (T1, T2, T3) -&amp;gt; void.
    public static Action&amp;lt;T1, T2, T3&amp;gt; Uncurry&amp;lt;T1, T2, T3&amp;gt;(
        this Func&amp;lt;T1, Func&amp;lt;T2, Action&amp;lt;T3&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
            (value1, value2, value3) =&amp;gt; function(value1)(value2)(value3);

    // Transform T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; void
    // to (T1, T2, T3, T4) -&amp;gt; void.
    public static Action&amp;lt;T1, T2, T3, T4&amp;gt; Uncurry&amp;lt;T1, T2, T3, T4&amp;gt;(
        this Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, Action&amp;lt;T4&amp;gt;&amp;gt;&amp;gt;&amp;gt; function) =&amp;gt;
            (value1, value2, value3, value4) =&amp;gt; function(value1)(value2)(value3)(value4);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallUncurry()
{
    // int -&amp;gt; int -&amp;gt; int -&amp;gt; int
    Func&amp;lt;int, Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; curriedAdd3 = a =&amp;gt; (b =&amp;gt; (c =&amp;gt; a + b + c));
    // (int -&amp;gt; int -&amp;gt; int) -&amp;gt; int
    Func&amp;lt;int, int, int, int&amp;gt; add3 = curriedAdd3.Uncurry();
    int add3Result = add3(1, 2, 3);

    // int -&amp;gt; int -&amp;gt; int -&amp;gt; void
    Func&amp;lt;int, Func&amp;lt;int, Action&amp;lt;int&amp;gt;&amp;gt;&amp;gt; curriedTraceAdd3 = a =&amp;gt; b =&amp;gt; c =&amp;gt; (a + b + c).WriteLine();
    // (int -&amp;gt; int -&amp;gt; int) -&amp;gt; void
    Action&amp;lt;int, int, int&amp;gt; traceAdd3 = curriedTraceAdd3.Uncurry();
    traceAdd3(1, 2, 3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;First-class function&lt;/h2&gt;
&lt;p&gt;As demonstrated, C# treats function as first class citizen. This can be compared with C# object side by side. First of all, object and function both have type and instance, and instance can be assigned/bound to variable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void Object()
    {
        Data value = new Data(0);
    }

    internal static void Function()
    {
        Function value1 = Function; // Named function.
        Function value2 = () =&amp;gt; { }; // Anonymous function.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object and function can both be stored as data field:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    private static Data dataField = new Data(0);

    private static Function namedFunctionField = Function;

    private static Function anonymousFunctionField = () =&amp;gt; { };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object and function can both be input and output of function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static Data Function(Data value) =&amp;gt; value;

    internal static Function Function(Function value) =&amp;gt; value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object and function can both access data out of the scope:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class OuterClass
{
    const int Outer = 1;

    class AccessOuter
    {
        const int Local = 2;
        int sum = Local + Outer;
    }
}

internal static void OuterFunction()
{
    const int Outer = 1;

    void AccessOuter()
    {
        const int Local = 2;
        int sum = Local + Outer;
    }

    Function accessOuter = () =&amp;gt;
    {
        const int Local = 2;
        int sum = Local + Outer;
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object and function can both be nested:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    internal Data Inner { get; set; }
}

internal static partial class Functions
{
    internal static void NestedObject()
    {
        Data outer = new Data(0)
        {
            Inner = new Data(1)
        };
    }

    internal static void NestedFunction()
    {
        void Outer()
        {
            void Inner() { }
        }

        Function outer = () =&amp;gt;
        {
            Function inner = () =&amp;gt; { };
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object and function can both be equality testable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ObjectEquality()
{
    Data value1;
    Data value2;
    value1 = value2 = new Data(0);
    object.ReferenceEquals(value1, value2).WriteLine(); // True
    object.Equals(value1, value2).WriteLine(); // True
    (value1 == value2).WriteLine(); // True

    value1 = new Data(1);
    value2 = new Data(1);
    object.ReferenceEquals(value1, value2).WriteLine(); // False
    object.Equals(value1, value2).WriteLine(); // True
    (value1 == value2).WriteLine(); // True
}

internal static void FunctionEquality()
{
    Function value1;
    Function value2;
    value1 = value2 = () =&amp;gt; { };
    object.ReferenceEquals(value1, value2).WriteLine(); // True
    object.Equals(value1, value2).WriteLine(); // True
    (value1 == value2).WriteLine(); // True

    value1 = new Function(Function);
    value2 = new Function(Function);
    object.ReferenceEquals(value1, value2).WriteLine(); // False
    object.Equals(value1, value2).WriteLine(); // True
    (value1 == value2).WriteLine(); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So C# has &lt;a href=&quot;https://en.wikipedia.org/wiki/First-class_function&quot;&gt;first class functions&lt;/a&gt;. Here is the summary:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;636&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Object&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Function&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Type&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Class&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Delegate type&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Instance&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Class instance&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Delegate instance&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Variable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be assigned to variable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be assigned to variable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Field&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be stored as data field&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be stored as data field&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Input&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be function’s parameter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be higher-order function’s parameter&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Output&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be function’s return value&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be higher-order function’s return value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Outer variable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can access&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can access via closure&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Nesting&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be nested&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be nested&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;Equality&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;210&quot;&amp;gt;Can be testable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;300&quot;&amp;gt;Can be testable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (7) Expression Tree: Function as Data</title><link>https://dixin.github.io/posts/functional-csharp-function-as-data-and-expression-tree-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-as-data-and-expression-tree-7/</guid><description>C# lambda expression is a powerful syntactic sugar. Besides representing anonymous function, the same syntax can also represent expression tree.</description><pubDate>Thu, 07 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-function-as-data-and-expression-tree&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-function-as-data-and-expression-tree&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C# lambda expression is a powerful syntactic sugar. Besides representing anonymous function, the same syntax can also represent expression tree.&lt;/p&gt;
&lt;h2&gt;Lambda expression as expression tree&lt;/h2&gt;
&lt;p&gt;An expression tree can be created with the same lambda expression syntax for anonymous function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void ExpressionLambda()
    {
        // Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
        Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, the expected type for the lambda expression is no longer a Func&amp;lt;int, bool&amp;gt; function type, but Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;. The lambda expression here is no longer compiled to executable anonymous function, but a tree data structure representing that function’s logic, which is called expression tree.&lt;/p&gt;
&lt;h3&gt;Metaprogramming: function as data&lt;/h3&gt;
&lt;p&gt;The above lambda expression is compiled to expression tree building code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledExpressionLambda()
{
    ParameterExpression parameterExpression = Expression.Parameter(typeof(int), &quot;int32&quot;); // int32 parameter.
    ConstantExpression constantExpression = Expression.Constant(0, typeof(int)); // 0
    BinaryExpression greaterThanExpression = Expression.GreaterThan(
        left: parameterExpression, right: constantExpression); // int32 &amp;gt; 0

    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
        body: greaterThanExpression, // ... =&amp;gt; int32 &amp;gt; 0
        parameters: parameterExpression); // int32 =&amp;gt; ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the Expression&amp;lt;Func&amp;lt;int bool&amp;gt;&amp;gt; instance represents the entire tree, the ParameterExpression, ConstantExpression, BinaryExpression instances are nodes in that tree. And they are all derived from System.Linq.Expressions.Expression type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq.Expressions
{
    public abstract partial class Expression
    {
        public virtual ExpressionType NodeType { get; }

        public virtual Type Type { get; }

        // Other members.
    }

    public class ParameterExpression : Expression
    {
        public string Name { get; }

        // Other members.
    }

    public class ConstantExpression : Expression
    {
        public object Value { get; }

        // Other members.
    }

    public class BinaryExpression : Expression
    {
        public Expression Left { get; }

        public Expression Right { get; }

        // Other members.
    }

    public abstract class LambdaExpression : Expression
    {
        public Expression Body { get; }

        public ReadOnlyCollection&amp;lt;ParameterExpression&amp;gt; Parameters { get; }

        // Other members.
    }

    public sealed class Expression&amp;lt;TDelegate&amp;gt; : LambdaExpression
    {
        public TDelegate Compile();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above expression tree data structure can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;int, bool&amp;gt;)
|_Parameters
| |_ParameterExpression (NodeType = Parameter, Type = int)
|   |_Name = &quot;int32&quot;
|_Body
  |_BinaryExpression (NodeType = GreaterThan, Type = bool)
    |_Left
    | |_ParameterExpression (NodeType = Parameter, Type = int)
    |   |_Name = &quot;int32&quot;
    |_Right
      |_ConstantExpression (NodeType = Constant, Type = int)
        |_Value = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So this expression tree is an &lt;a href=&quot;https://en.wikipedia.org/wiki/Abstract_syntax_tree&quot;&gt;abstract syntactic tree&lt;/a&gt;, representing the abstract syntactic structure of C# function source code int32 =&amp;gt; int32 &amp;gt; 0. Notice each node has NodeType property and Type property. NodeType returns the represented construct type in the tree, and Type returns the represented .NET type. For example, above ParameterExpression is parameter node representing an int parameter in the source code, so its NodeType is Parameter and its Type is int.&lt;/p&gt;
&lt;p&gt;To summarize, the differences between&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0; // Code.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0; // Data.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;isPositive variable is a function represented by delegate instance, and can be called. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled to executable code. When isPositive is called, this code is executed.&lt;/li&gt;
&lt;li&gt;isPositiveExpression variable is an abstract syntactic tree data structure. So apparently it cannot be directly called like an executable function. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled to the building of an expression tree, where each node is an Expression instance. This entire tree represents the syntactic structure and logic of function int32 =&amp;gt; int32 &amp;gt; 0. This tree’s top node is a Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; instance, since this is a lambda expression. It has 2 child nodes:
&lt;ul&gt;
&lt;li&gt;A ParameterExpression collection, representing all the parameters of the lambda expression. The lambda expression has 1 parameter, so this collection contains one node:
&lt;ul&gt;
&lt;li&gt;A ParameterExpression instance, representing the int parameter named “int32”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A Body node representing the lambda expression’s body, which is a BinaryExpression instance, representing the body is a “&amp;gt;” (greater than) comparison of 2 operands. So it has 2 child nodes:
&lt;ul&gt;
&lt;li&gt;A reference of above ParameterExpression instance, representing the left operand.&lt;/li&gt;
&lt;li&gt;A ConstantExpression instance, representing the right operand 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because each node in expression tree is strong typed with rich information. The nodes can be traversed to obtain the represented function’s C# source code logic, and convert to the logic of another language. Here isPositiveExpression represents the function logic to predicate whether an int value is greater than a constant 0, and it can be converted to SQL query’s greater-than predicate in a SQL WHERE clause, etc.&lt;/p&gt;
&lt;h3&gt;.NET expressions&lt;/h3&gt;
&lt;p&gt;Besides above ParameterExpression, ConstantExpression, BinaryExpression, LambdaExpression, .NET provides a rich collection of expressions nodes. The following is their inheritance hierarchy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BlockExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ConditionalExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ConstantExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DebugInfoExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DefaultExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DynamicExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GotoExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IndexExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;InvocationExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LabelExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LambdaExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expression&amp;lt;TDelegate&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ListInitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LoopExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MemberExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MemberInitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MethodCallExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NewArrayExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NewExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ParameterExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RuntimeVariablesExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SwitchExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TypeBinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UnaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, as demonstrated above, expression can be instantiated by calling the factory methods of Expression type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract partial class Expression
{
    public static ParameterExpression Parameter(Type type, string name);

    public static ConstantExpression Constant(object value, Type type);

    public static BinaryExpression GreaterThan(Expression left, Expression right);

    public static Expression&amp;lt;TDelegate&amp;gt; Lambda&amp;lt;TDelegate&amp;gt;(Expression body, params ParameterExpression[] parameters);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expression has many other factory methods to cover all the expression instantiation cases:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract partial class Expression
{
    public static BinaryExpression Add(Expression left, Expression right);

    public static BinaryExpression Subtract(Expression left, Expression right);

    public static BinaryExpression Multiply(Expression left, Expression right);

    public static BinaryExpression Divide(Expression left, Expression right);

    public static BinaryExpression Equal(Expression left, Expression right);

    public static UnaryExpression ArrayLength(Expression array);

    public static UnaryExpression Not(Expression expression);

    public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse);

    public static NewExpression New(ConstructorInfo constructor, params Expression[] arguments);

    public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments);

    public static BlockExpression Block(params Expression[] expressions);

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some expression node can have multiple possible NodeType values. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UnaryExpression represents any unary operation with an operator and a operand. Its NodeType can be ArrayLength, Negate, Not, Convert, Decreament, Increment, Throw, UnaryPlus, etc.&lt;/li&gt;
&lt;li&gt;BinaryExpression represents any binary operation with an operator, a left operand, and a right operand, its NodeType can be Add, And, Assign, Divide, Equal, .GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, Modulo, Multiply, NotEqual, Or, Power, Subtract, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So far C# compiler only implements this “function as data” syntactic sugar for expression lambda, and it is not available to statement lambda yet. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StatementLambda()
{
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt;
    {
        Console.WriteLine(int32);
        return int32 &amp;gt; 0;
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It results a compiler error: A lambda expression with a statement body cannot be converted to an expression tree. The above expression tree has to be built manually:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StatementLambda()
{
    ParameterExpression parameterExpression = Expression.Parameter(typeof(int), &quot;int32&quot;); // int32 parameter.
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
        body: Expression.Block( // ... =&amp;gt; {
            // Console.WriteLine(int32);
            Expression.Call(new Action&amp;lt;int&amp;gt;(Console.WriteLine).Method, parameterExpression),
            // return int32 &amp;gt; 0;
            Expression.GreaterThan(parameterExpression, Expression.Constant(0, typeof(int)))), // }
        parameters: parameterExpression); // int32 =&amp;gt; ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Compile expression tree to CIL&lt;/h2&gt;
&lt;p&gt;Expression tree is data - abstract syntactic tree. In C# and LINQ, expression tree is usually used to represent the abstract syntactic structure of function, so that it can be compiled to other &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;domain-specific languages&lt;/a&gt;, like SQL query, URI query, etc. To demonstrate this, take a simple mathematics function as example, which accepts double parameters and execute the 4 basic binary arithmetical calculation: add, subtract, multiply, divide:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ArithmeticalExpression()
{
    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entire tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;double, double, double, double, double, double&amp;gt;)
|_Parameters
| |_ParameterExpression (NodeType = Parameter, Type = double)
| | |_Name = &quot;a&quot;
| |_ParameterExpression (NodeType = Parameter, Type = double)
| | |_Name = &quot;b&quot;
| |_ParameterExpression (NodeType = Parameter, Type = double)
| | |_Name = &quot;c&quot;
| |_ParameterExpression (NodeType = Parameter, Type = double)
| | |_Name = &quot;d&quot;
| |_ParameterExpression (NodeType = Parameter, Type = double)
|   |_Name = &quot;e&quot;
|_Body
  |_BinaryExpression (NodeType = Add, Type = double)
    |_Left
    | |_BinaryExpression (NodeType = Subtract, Type = double)
    |   |_Left
    |   | |_BinaryExpression (NodeType = Add, Type = double)
    |   |   |_Left
    |   |   | |_ParameterExpression (NodeType = Parameter, Type = double)
    |   |   |   |_Name = &quot;a&quot;
    |   |   |_Right
    |   |     |_ParameterExpression (NodeType = Parameter, Type = double)
    |   |       |_Name = &quot;b&quot;
    |   |_Right
    |     |_BinaryExpression (NodeType = Divide, Type = double)
    |       |_Left
    |       | |_BinaryExpression (NodeType = Multiply, Type = double)
    |       |   |_Left
    |       |   | |_ParameterExpression (NodeType = Parameter, Type = double)
    |       |   |   |_Name = &quot;c&quot;
    |       |   |_right
    |       |     |_ParameterExpression (NodeType = Parameter, Type = double)
    |       |       |_Name = &quot;d&quot;
    |       |_Right
    |         |_ConstantExpression (NodeType = Constant, Type = int)
    |           |_Value = 2
    |_Right
      |_BinaryExpression (NodeType = Multiply, Type = double)
        |_Left
        | |_ParameterExpression (NodeType = Parameter, Type = double)
        |   |_Name = &quot;e&quot;
        |_Right
          |_ConstantExpression (NodeType = Constant, Type = int)
            |_Value = 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very simple expression tree, where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;each internal node is a binary node (BinaryExpression instance) representing add, subtract, multiply, or divide binary operations;&lt;/li&gt;
&lt;li&gt;each leaf node is either a parameter (ParameterExpression instance), or a constant (ConstantExpression instance).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In total there are 6 kinds of nodes in this tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add: BinaryExpression { NodeType = ExpressionType.Add }&lt;/li&gt;
&lt;li&gt;subtract: BinaryExpression { NodeType = ExpressionType.Subtract }&lt;/li&gt;
&lt;li&gt;multiply: BinaryExpression { NodeType = ExpressionType.Multiply }&lt;/li&gt;
&lt;li&gt;divide: BinaryExpression { NodeType = ExpressionType.Divide}&lt;/li&gt;
&lt;li&gt;constant: ParameterExpression { NodeType = ExpressionType.Constant }&lt;/li&gt;
&lt;li&gt;parameter: ConstantExpression { NodeType = ExpressionType.Parameter }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Traverse expression tree&lt;/h3&gt;
&lt;p&gt;Recursively traversing this tree is very easy. The following base type implements the basic logic of traversing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class BinaryArithmeticExpressionVisitor&amp;lt;TResult&amp;gt;
{
    internal virtual TResult VisitBody(LambdaExpression expression) =&amp;gt; this.VisitNode(expression.Body, expression);

    protected TResult VisitNode(Expression node, LambdaExpression expression)
    {
        // Processes the 6 types of node.
        switch (node.NodeType)
        {
            case ExpressionType.Add:
                return this.VisitAdd((BinaryExpression)node, expression);

            case ExpressionType.Constant:
                return this.VisitConstant((ConstantExpression)node, expression);

            case ExpressionType.Divide:
                return this.VisitDivide((BinaryExpression)node, expression);

            case ExpressionType.Multiply:
                return this.VisitMultiply((BinaryExpression)node, expression);

            case ExpressionType.Parameter:
                return this.VisitParameter((ParameterExpression)node, expression);

            case ExpressionType.Subtract:
                return this.VisitSubtract((BinaryExpression)node, expression);

            default:
                throw new ArgumentOutOfRangeException(nameof(node));
        }
    }

    protected abstract TResult VisitAdd(BinaryExpression add, LambdaExpression expression);

    protected abstract TResult VisitConstant(ConstantExpression constant, LambdaExpression expression);

    protected abstract TResult VisitDivide(BinaryExpression divide, LambdaExpression expression);

    protected abstract TResult VisitMultiply(BinaryExpression multiply, LambdaExpression expression);

    protected abstract TResult VisitParameter(ParameterExpression parameter, LambdaExpression expression);

    protected abstract TResult VisitSubtract(BinaryExpression subtract, LambdaExpression expression);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The VisitNode method detects the node type, and dispatch to 6 abstract methods for all 6 kinds of nodes. The following type implements those 6 methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class PrefixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;string&amp;gt;
{
    protected override string VisitAdd
        (BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, &quot;add&quot;, expression);

    protected override string VisitConstant
        (ConstantExpression constant, LambdaExpression expression) =&amp;gt; constant.Value.ToString();

    protected override string VisitDivide
        (BinaryExpression divide, LambdaExpression expression) =&amp;gt; this.VisitBinary(divide, &quot;div&quot;, expression);

    protected override string VisitMultiply
        (BinaryExpression multiply, LambdaExpression expression) =&amp;gt;
            this.VisitBinary(multiply, &quot;mul&quot;, expression);

    protected override string VisitParameter
        (ParameterExpression parameter, LambdaExpression expression) =&amp;gt; parameter.Name;

    protected override string VisitSubtract
        (BinaryExpression subtract, LambdaExpression expression) =&amp;gt;
            this.VisitBinary(subtract, &quot;sub&quot;, expression);

    private string VisitBinary( // Recursion: operator(left, right)
        BinaryExpression binary, string @operator, LambdaExpression expression) =&amp;gt;
            $&quot;{@operator}({this.VisitNode(binary.Left, expression)}, {this.VisitNode(binary.Right, expression)})&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When visiting a binary node, it recursively outputs in prefix style operator(left, right). For example, the infix expression a + b is converted to add(a, b), which can be viewed as calling add function with arguments a and b. The following code outputs the function body’s logic in prefixed, function call style:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void Prefix()
    {
        Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
            (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
        PrefixVisitor prefixVisitor = new PrefixVisitor();
        string prefix = prefixVisitor.VisitBody(infix); // add(sub(add(a, b), div(mul(c, d), 2)), mul(e, 3))
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually .NET provides a built-in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor.aspx&quot;&gt;System.Linq.Expressions.ExpressionVisitor&lt;/a&gt; type. Here traversers are implemented from scratch just for demonstration purpose.&lt;/p&gt;
&lt;h3&gt;Expression tree to CIL at runtime&lt;/h3&gt;
&lt;p&gt;If the output is in postfix style (a, b, add), then it can be viewed as: load a to stack, load b to stack, add 2 values on stack. This is how the stack based CIL language works. So a different visitor can be created to output &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_CIL_instructions&quot;&gt;CIL instructions&lt;/a&gt;. CIL instructions can be represented by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcode.aspx&quot;&gt;System.Reflection.Emit.OpCode&lt;/a&gt; structures. So the output can be a sequence of instruction-argument pairs, represented by a tuple of a OpCode value, and a double value (operand) or null (no operand):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class PostfixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;List&amp;lt;(OpCode, double?)&amp;gt;&amp;gt;
{
    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitAdd(
        BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, OpCodes.Add, expression);

    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitConstant(
        ConstantExpression constant, LambdaExpression expression) =&amp;gt;
            new List&amp;lt;(OpCode, double?)&amp;gt;() { (OpCodes.Ldc_R8, (double?)constant.Value) };

    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitDivide(
        BinaryExpression divide, LambdaExpression expression) =&amp;gt;
            this.VisitBinary(divide, OpCodes.Div, expression);

    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitMultiply(
        BinaryExpression multiply, LambdaExpression expression) =&amp;gt;
            this.VisitBinary(multiply, OpCodes.Mul, expression);

    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitParameter(
        ParameterExpression parameter, LambdaExpression expression)
    {
        int index = expression.Parameters.IndexOf(parameter);
        return new List&amp;lt;(OpCode, double?)&amp;gt;() { (OpCodes.Ldarg_S, (double?)index) };
    }

    protected override List&amp;lt;(OpCode, double?)&amp;gt; VisitSubtract(
        BinaryExpression subtract, LambdaExpression expression) =&amp;gt;
            this.VisitBinary(subtract, OpCodes.Sub, expression);

    private List&amp;lt;(OpCode, double?)&amp;gt; VisitBinary( // Recursion: left, right, operator
        BinaryExpression binary, OpCode postfix, LambdaExpression expression)
    {
        List&amp;lt;(OpCode, double?)&amp;gt; cils = this.VisitNode(binary.Left, expression);
        cils.AddRange(this.VisitNode(binary.Right, expression));
        cils.Add((postfix, (double?)null));
        return cils;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code outputs a sequence of CIL code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Cil()
{
    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

    PostfixVisitor postfixVisitor = new PostfixVisitor();
    IEnumerable&amp;lt;(OpCode, double?)&amp;gt; postfix = postfixVisitor.VisitBody(infix);
    foreach ((OpCode Operator, double? Operand) code in postfix)
    {
        $&quot;{code.Operator} {code.Operand}&quot;.WriteLine();
    }
    // ldarg.s 0
    // ldarg.s 1
    // add
    // ldarg.s 2
    // ldarg.s 3 
    // mul 
    // ldc.r8 2 
    // div 
    // sub 
    // ldarg.s 4 
    // ldc.r8 3 
    // mul 
    // add
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the C# logic represented in this expression tree is successfully compiled to CIL language.&lt;/p&gt;
&lt;h3&gt;Expression tree to function at runtime&lt;/h3&gt;
&lt;p&gt;The above compiled CIL code is executable, so a function can be created at runtime, then the CIL code can be emitted into that function. This kind of function is call dynamic function, because it is not in a static assembly generated at compile time, but generated at runtime.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class BinaryArithmeticCompiler
{
    internal static TDelegate Compile&amp;lt;TDelegate&amp;gt;(Expression&amp;lt;TDelegate&amp;gt; expression)
    {
        DynamicMethod dynamicFunction = new DynamicMethod(
            name: string.Empty,
            returnType: expression.ReturnType,
            parameterTypes: expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
            m: typeof(BinaryArithmeticCompiler).Module);
        EmitIL(dynamicFunction.GetILGenerator(), new PostfixVisitor().VisitBody(expression));
        return (TDelegate)(object)dynamicFunction.CreateDelegate(typeof(TDelegate));
    }

    private static void EmitIL(ILGenerator ilGenerator, IEnumerable&amp;lt;(OpCode, double?)&amp;gt; il)
    {
        foreach ((OpCode Operation, double? Operand) code in il)
        {
            if (code.Operand == null)
            {
                ilGenerator.Emit(code.Operation); // add, sub, mul, div
            }
            else if (code.Operation == OpCodes.Ldarg_S)
            {
                ilGenerator.Emit(code.Operation, (int)code.Operand); // ldarg.s (int)index
            }
            else
            {
                ilGenerator.Emit(code.Operation, code.Operand.Value); // ldc.r8 (double)constant
            }
        }
        ilGenerator.Emit(OpCodes.Ret); // Returns the result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code demonstrate how to use it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Compile()
{
    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
    Func&amp;lt;double, double, double, double, double, double&amp;gt; function = 
        BinaryArithmeticCompiler.Compile(expression);
    double result = function(1, 2, 3, 4, 5); // 12
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET provides a built-in API, System.Linq.Expressions.Expression&amp;lt;TDelegate&amp;gt;’s Compile method, for this purpose - compile expression tree to executable function at runtime:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void BuiltInCompile()
{
    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
    Func&amp;lt;double, double, double, double, double, double&amp;gt; function = infix.Compile();
    double result = function(1, 2, 3, 4, 5); // 12
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Internally, Expression&amp;lt;TDelegate&amp;gt;.Compile calls APIs of System.Linq.Expressions.Compiler.LambdaCompile, which is a complete expression tree to CIL compiler implementation.&lt;/p&gt;
&lt;h2&gt;Expression tree and LINQ remote query&lt;/h2&gt;
&lt;p&gt;Expression tree is very important in LINQ remote query, because it is easy to build expression tree, especially with the lambda expression, and it is also easy to compile/convert/translate a C# expression tree’s logic to a different domain or different language. In above examples, expression tree is converted to executable CIL. As fore mentioned, there are local and remote LINQ queries, like relational database. The following examples are a local LINQ to Objects query for local in memory objects, and a remote LINQ to Entities query for relational database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void LinqToObjects(IEnumerable&amp;lt;Product&amp;gt; source)
    {
        IEnumerable&amp;lt;Product&amp;gt; query = source.Where(product =&amp;gt; product.ListPrice &amp;gt; 0M); // Define query.
        foreach (Product result in query) // Execute query.
        {
            result.Name.WriteLine();
        }
    }

    internal static void LinqToEntities(IQueryable&amp;lt;Product&amp;gt; source)
    {
        IQueryable&amp;lt;Product&amp;gt; query = source.Where(product =&amp;gt; product.ListPrice &amp;gt; 0M); // Define query.
        foreach (Product result in query) // Execute query.
        {
            result.Name.WriteLine();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above LINQ to Objects query’s data source is a sequence of Product objects in current .NET application’s local memory. The LINQ to Entities query’s data source is Product table in remote relational database, which is not available in current local memory. In LINQ, local data source and query are represented by IEnumerable&amp;lt;T&amp;gt;, and remote data source and query are represented by IQueryable&amp;lt;T&amp;gt;. They have different LINQ query extension methods, table above Where as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, the Where query and predicate lambda expression share identical syntax for local and remote LINQ queries, but their compilation is totally different. The local query’s predicate is compiled to function, and the remote query’s predicate is compiled to expression tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class CompiledExpressionTree
{
    [CompilerGenerated]
    private static Func&amp;lt;Product, bool&amp;gt; cachedPredicate;

    [CompilerGenerated]
    private static bool Predicate(Product product) =&amp;gt; product.ListPrice &amp;gt; 0M;

    public static void LinqToObjects(IEnumerable&amp;lt;Product&amp;gt; source)
    {
        Func&amp;lt;Product, bool&amp;gt; predicate = cachedPredicate ?? (cachedPredicate = Predicate);
        IEnumerable&amp;lt;Product&amp;gt; query = Enumerable.Where(source, predicate);
        foreach (Product result in query) // Execute query.
        {
            TraceExtensions.WriteLine(result.Name);
        }
    }
}

internal static partial class CompiledExpressionTree
{
    internal static void LinqToEntities(IQueryable&amp;lt;Product&amp;gt; source)
    {
        ParameterExpression productParameter = Expression.Parameter(typeof(Product), &quot;product&quot;);
        Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
            Expression.GreaterThan(
                Expression.Property(productParameter, nameof(Product.ListPrice)),
                Expression.Constant(0M, typeof(decimal))),
            productParameter);

        IQueryable&amp;lt;Product&amp;gt; query = Queryable.Where(source, predicateExpression); // Define query.
        foreach (Product result in query) // Execute query.
        {
            TraceExtensions.WriteLine(result.Name);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At runtime, when the local query executes, the anonymous function is called for each local value in the source sequence, and the remote query is usually translated to a domain specific language, then submit to the remote data source and execute. Here in LINQ to Entities query, the predicate expression tree is translated to predicate in SQL query, and submitted to the database to execute. The translation from expression tree to SQL will be covered in LINQ to Entities chapter.&lt;/p&gt;
</content:encoded></item><item><title>C# Functional Programming In-Depth (6) Anonymous Function and Lambda Expression</title><link>https://dixin.github.io/posts/functional-csharp-anonymous-function-and-lambda-expression-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-anonymous-function-and-lambda-expression-7/</guid><description>Besides named function represented by method members, C# also supports anonymous functions, represented by anonymous method or lambda expression with no name at design time. This part discussed lambda</description><pubDate>Wed, 06 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-anonymous-function-and-lambda-expression&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-anonymous-function-and-lambda-expression&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Besides named function represented by method members, C# also supports anonymous functions, represented by anonymous method or lambda expression with no name at design time. This part discussed lambda expression as a functional feature of C# language. In the meanwhile, the general concept of lambda expression is the core of lambda calculus, where functional programming originates. General lambda expression and lambda calculus will be discussed in the Lambda Calculus chapter.&lt;/p&gt;
&lt;h2&gt;Anonymous method&lt;/h2&gt;
&lt;p&gt;As fore mentioned, a function can be initialized from a named method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static bool IsPositive(int int32)
    {
        return int32 &amp;gt; 0;
    }

    internal static void NamedFunction()
    {
        Func&amp;lt;int, bool&amp;gt; isPositive = IsPositive;
        bool result = isPositive(0);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 2.0 introduces a syntactic sugar called anonymous method, enabling methods to be defined inline with the delegate keyword. The above named method can be inline as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnonymousFunction()
{
    Func&amp;lt;int, bool&amp;gt; isPositive = delegate (int int32)
    {
        return int32 &amp;gt; 0;
    };
    bool result = isPositive(0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no named method defined at design time. At compile time, compiler generates a normal named method. So the compilation is equivalent to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class CompiledFunctions
{
    [CompilerGenerated]
    private static Func&amp;lt;int, bool&amp;gt; cachedIsPositive;

    [CompilerGenerated]
    private static bool IsPositive(int int32)
    {
        return int32 &amp;gt; 0;
    }

    internal static void AnonymousFunction()
    {
        Func&amp;lt;int, bool&amp;gt; isPositive;
        if (cachedIsPositive == null)
        {
            cachedIsPositive = new Func&amp;lt;int, bool&amp;gt;(IsPositive);
        }
        isPositive = cachedIsPositive;
        bool result = isPositive.Invoke(0);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides named methods, C# compiler also generates a cache field for performance. When AnonymousMethod is called for the first time, the delegate instance is constructed, and stored in the cache filed. when AnonymousMethod is called again, the cache field is used and delegate instantiation does not execute again.&lt;/p&gt;
&lt;h2&gt;Lambda expression&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces lambda expression syntactic sugar, so above anonymous method can be simplified as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Lambda()
{
    Func&amp;lt;int, bool&amp;gt; isPositive = (int int32) =&amp;gt;
    {
        return int32 &amp;gt; 0;
    };
    bool result = isPositive(0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its compilation is identical to above anonymous method with delegate keyword. The =&amp;gt; operator is called lambda operator and reads “go to”. Lambda expression can be further shortened:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if the type of parameter can be inferred (for example, from the function type), the type declaration of parameter can be omitted. In above example, the lambda expression’s parameter type can be inferred to be int from function type int –&amp;gt; bool (Func&amp;lt;int, bool&amp;gt; delegate type).&lt;/li&gt;
&lt;li&gt;if lambda expression has one parameter, the parentheses for the parameter can be omitted.&lt;/li&gt;
&lt;li&gt;if the body of the lambda expression has only one statement, the expression body syntactic sugar applies, the curly brackets for the body and return keyword can be omitted,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lambda expression with expression body are called expression lambda, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExpressionLambda()
{
    Func&amp;lt;int, int, int&amp;gt; add = (int32A, int32B) =&amp;gt; int32A + int32B;
    Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
    Action&amp;lt;int&amp;gt; traceLine = int32 =&amp;gt; int32.WriteLine();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a lambda expression having more than one statements in the body, its body has to be a block with curly brackets. It is called statement lambda:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StatementLambda()
{
    Func&amp;lt;int, int, int&amp;gt; add = (int32A, int32B) =&amp;gt;
    {
        int sum = int32A + int32B;
        return sum;
    };
    Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt;
    {
        int32.WriteLine();
        return int32 &amp;gt; 0;
    };
    Action&amp;lt;int&amp;gt; traceLine = int32 =&amp;gt;
    {
        int32.WriteLine();
        Trace.Flush();
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lambda expression (both expression lambda and statement lambda) can also be used with the constructor call syntax of delegate, or type conversion syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConstructorCall()
{
    Func&amp;lt;int, int, int&amp;gt; add = new Func&amp;lt;int, int, int&amp;gt;((int32A, int32B) =&amp;gt; int32A + int32B);
    Func&amp;lt;int, bool&amp;gt; isPositive = new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt;
    {
        int32.WriteLine();
        return int32 &amp;gt; 0;
    });
}

internal static void TypeConversion()
{
    Func&amp;lt;int, int, int&amp;gt; add = (Func&amp;lt;int, int, int&amp;gt;)((int32A, int32B) =&amp;gt; int32A + int32B));
    Func&amp;lt;int, bool&amp;gt; isPositive = (Func&amp;lt;int, bool&amp;gt;)(int32 =&amp;gt;
    {
        int32.WriteLine();
        return int32 &amp;gt; 0;
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Call anonymous function&lt;/h2&gt;
&lt;p&gt;An anonymous function is not required to be assigned to a function variable. It can be used (called) directly. Unfortunately, the following syntax does not work in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallLambdaExpression()
{
    (int32 =&amp;gt; int32 &amp;gt; 0)(1); // Define an expression lambda and call.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code cannot be compiled because C# compiler cannot infer any type for the lambda expression. For this kind of IIFE (&lt;a href=&quot;https://en.wikipedia.org/wiki/Immediately-invoked_function_expression&quot;&gt;immediately-invoked function expression&lt;/a&gt;), the above constructor call syntax, or type conversion syntax can be used to provide type information to compiler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallLambdaExpressionWithConstructor()
{
    bool result = new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0)(1);
}

internal static void CallLambdaExpressionWithTypeConversion()
{
    bool result = ((Func&amp;lt;int, bool&amp;gt;)(int32 =&amp;gt; int32 &amp;gt; 0))(1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here no function name or named function is involved at design time. At compile time, C# compiler generates identical code for the above 2 syntaxes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class CompiledFunctions
{
    [CompilerGenerated]
    [Serializable]
    private sealed class Container
    {
        public static readonly Container Singleton = new Container();

        public static Func&amp;lt;int, bool&amp;gt; cachedIsPositive;

        internal bool IsPositive(int int32)
        {
            return int32 &amp;gt; 0;
        }
    }

    internal static void CallLambdaExpressionWithConstructor()
    {
        Func&amp;lt;int, bool&amp;gt; isPositive;
        if (Container.cachedIsPositive == null)
        {
            Container.cachedIsPositive = new Func&amp;lt;int, bool&amp;gt;(Container.Singleton.IsPositive);
        }
        isPositive = Container.cachedIsPositive;
        bool result = isPositive.Invoke(1);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are more examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallAnonymousFunction()
{
    new Func&amp;lt;int, int, int&amp;gt;((int32A, int32B) =&amp;gt; int32A + int32B)(1, 2);
    new Action&amp;lt;int&amp;gt;(int32 =&amp;gt; int32.WriteLine())(1);

    new Func&amp;lt;int, int, int&amp;gt;((int32A, int32B) =&amp;gt;
    {
        int sum = int32A + int32B;
        return sum;
    })(1, 2);
    new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt;
    {
        int32.WriteLine();
        return int32 &amp;gt; 0;
    })(1);
    new Action&amp;lt;int&amp;gt;(int32 =&amp;gt;
    {
        int32.WriteLine();
        Trace.Flush();
    })(1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some other functional languages support the IIFE syntax without type information. For example, F# compiler can infer the types in the following lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(fun value -&amp;gt; value &amp;gt; 0) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regarding value is compared with int value 1 with the &amp;gt; operator, F# infers parameter value is of type int, and also infers return type is bool from the result type of the &amp;gt; operator for int. Similarly, the following lambda expression works in Haskell (named after &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;, mathematician and logician):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(\value -&amp;gt; value &amp;gt; 0) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can also work In some loosely typed languages, like JavaScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(value =&amp;gt; value &amp;gt; 0)(1);

(function(value) {
     return value &amp;gt; 0;
})(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Closure&lt;/h2&gt;
&lt;p&gt;Anonymous function has the same closure capability as local function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void Closure()
    {
        int outer = 1; // Outside the scope of anonymous function.
        new Action(() =&amp;gt;
        {
            int local = 2; // Inside the scope of anonymous function.
            (local + outer).WriteLine();
        })();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its compilation is also similar to local function. The difference is, C# compiler generates display structure for local function, and generates display class for anonymous function. The above code is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
private sealed class DisplayClass0
{
    public int Outer;

    internal void Add()
    {
        int local = 2;
        (local + this.Outer).WriteLine();
    }
}

internal static void CompiledClosure()
{
    int outer = 1;
    DisplayClass0 display = new DisplayClass0(){ Outer = outer };
    display.Add(); // 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like local function, the closure and display class of anonymous function can introduce the same implicit references. Closure must be used with caution for anonymous function too, to avoid the performance pitfall.&lt;/p&gt;
&lt;h2&gt;Expression bodied function member&lt;/h2&gt;
&lt;p&gt;C# 6.0 and 7.0 introduce expression body syntax, which applies the above lambda syntax to simplify function member’s body to an expression. This syntax works for all named functions, including instance method, static method, extension method, as well as static constructor, constructor, conversion operator, operator overload, property, property getter, property setter, indexer, indexer getter, indexer setter. It also works for local function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    private int value;

    static Data() =&amp;gt; MethodBase.GetCurrentMethod().Name.WriteLine(); // Static constructor.

    internal Data(int value) =&amp;gt; this.value = value; // Constructor.

    ~Data() =&amp;gt; Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // Finalizer.

    internal bool Equals(Data other) =&amp;gt; this.value == other.value; // Instance method.

    internal static bool Equals(Data @this, Data other) =&amp;gt; @this.value == other.value; // Static method.

    public static Data operator +(Data data1, Data Data) =&amp;gt; new Data(data1.value + Data.value); // Operator overload.

    public static explicit operator int(Data value) =&amp;gt; value.value; // Conversion operator.

    public static implicit operator Data(int value) =&amp;gt; new Data(value); // Conversion operator.

    internal int ReadOnlyValue =&amp;gt; this.value; // Property.

    internal int ReadWriteValue
    {
        get =&amp;gt; this.value; // Property getter.
        set =&amp;gt; this.value = value; // Property setter.
    }

    internal int this[long index] =&amp;gt; throw new NotImplementedException(); // Indexer.

    internal int this[int index]
    {
        get =&amp;gt; throw new NotImplementedException(); // Indexer getter.
        set =&amp;gt; throw new NotImplementedException(); // Indexer setter.
    }

    internal event EventHandler Created
    {
        add =&amp;gt; Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // Event accessor.
        remove =&amp;gt; Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // Event accessor.
    }

    internal int GetValue()
    {
        int LocalFunction() =&amp;gt; this.value; // Local function.
        return LocalFunction();
    }
}

internal static partial class DataExtensions
{
    internal static bool Equals(Data @this, Data other) =&amp;gt; @this.ReadOnlyValue == other.Value; // Extension method.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This syntax works for interface explicit implementation too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data : IComparable&amp;lt;Data&amp;gt;
{
    int IComparable&amp;lt;Data&amp;gt;.CompareTo(Data other) =&amp;gt; this.value.CompareTo(other.value); // Explicit interface implementation.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The expression body is purely a syntactic sugar, it is compiled the same way as normal block body with curly bracket.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (5) Delegate: Function type, instance and group</title><link>https://dixin.github.io/posts/functional-csharp-function-type-and-delegate-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-type-and-delegate-7/</guid><description>In C#, functions are represented by methods of types, and other function members of types. In C#, just like just objects have types, methods/functions have types too, which are represented by delegate</description><pubDate>Tue, 05 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-function-type-and-delegate&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-function-type-and-delegate&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;Delegate type as function type&lt;/h2&gt;
&lt;p&gt;In C#, functions are represented by methods of types, and other function members of types. In C#, just like just objects have types, methods/functions have types too, which are represented by delegate type.&lt;/p&gt;
&lt;h3&gt;Function type&lt;/h3&gt;
&lt;p&gt;This tutorial uses notation input parameter types –&amp;gt; output return type for function type. For example, the simplest function type is parameterless, and returning void. Such function type is denoted () –&amp;gt; void. In C#, a delegate type can defined like a method signature with the delegate keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; void
internal delegate void FuncToVoid();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;FuncToVoid can be viewed as an alias of function type () –&amp;gt; void. The following functions are all parameterless, and returning void:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Diagnostics
{
    public sealed class Trace
    {
        public static void Close();

        public static void Flush();

        public static void Indent();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So these functions are all of function type () –&amp;gt; void; in another word, of FuncToVoid type.&lt;/p&gt;
&lt;p&gt;The following delegate type represents the string –&amp;gt; void function type, which accepts a string parameter, and returns void:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// string -&amp;gt; void
internal delegate void FuncStringToVoid(string @string);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following functions are all of FuncStringToVoid type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Diagnostics
{
    public sealed class Trace
    {
        public static void TraceInformation(string message);

        public static void Write(string message);

        public static void WriteLine(string message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These functions’ parameter names are different from the delegate type definition. In C#/.NET, parameter names are ignored when the compiler identifies function types, only parameter types, their order, and return type matter.&lt;/p&gt;
&lt;p&gt;The following delegate type represents the () –&amp;gt; int function type that is parameterless, and returns int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; int
internal delegate int FuncToInt32();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following functions are all of FuncToInt32 type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Runtime.InteropServices
{
    public static class Marshal
    {
        public static int GetExceptionCode();

        public static int GetHRForLastWin32Error();

        public static int GetLastWin32Error();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following delegate type represents the (string, int) –&amp;gt; int function type that accepts a string parameter, then a int parameter, and returns int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// (string, int) -&amp;gt; int
internal delegate int FuncStringInt32ToInt32(string @string, int int32);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is the type of the following functions (Again, the parameter names are ignored.):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Globalization
{
    public static class CharUnicodeInfo
    {
        public static int GetDecimalDigitValue(string s, int index);

        public static int GetDigitValue(string s, int index);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following delegate type represents the string –&amp;gt; bool function type that accepts a string parameter, and returns bool:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// string –&amp;gt; bool
internal delegate bool FuncStringToBoolean(string @string);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following functions are all of FuncStringToBoolean type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [DefaultMember(&quot;Chars&quot;)]
    public sealed class String : IEnumerable&amp;lt;char&amp;gt;, IEnumerable, IComparable, IComparable&amp;lt;String&amp;gt;, IConvertible, IEquatable&amp;lt;String&amp;gt;
    {
        public static bool IsNullOrEmpty(String value);

        public static bool IsNullOrWhiteSpace(String value);

        public bool Contains(String value);

        public bool Equals(String value);

        public bool StartsWith(String value);

        public bool EndsWith(String value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Generic delegate type&lt;/h3&gt;
&lt;p&gt;Above FuncToInt32 represents the () –&amp;gt; int function type that is parameterless and return int. Similarly, for parameterless functions returning bool, string, or object, the following delegate types can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; bool
internal delegate bool FuncToBoolean();

// () -&amp;gt; string
internal delegate string FuncToString();

// () -&amp;gt; object
internal delegate object FuncToObject();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More similar definitions can go forever for different return types. Since C# 2.0. they can be replaced with one single generic delegate type. In the above series of delegate type defections, the return type varies, so the return type can be represented with a type parameter of any name, like TResult:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// () -&amp;gt; TResult
internal delegate TResult Func&amp;lt;TResult&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to generic interface/class/structure, here type parameter TResult is also defined in angle brackets following type name, and it is used as the return type. It is just a placeholder to be specified with concrete type later. When TResult is int, Func&amp;lt;int&amp;gt; represents the () –&amp;gt; int function type, which is equivalent to FuncToInt32, and Func&amp;lt;bool&amp;gt; is equivalent to FuncToBoolean, and Func&amp;lt;string&amp;gt; is equivalent to FuncToString, Func&amp;lt;object&amp;gt; is equivalent to FuncToObject, etc. All the delegate types in this () –&amp;gt; TResult pattern can be represented by Func&amp;lt;TResult&amp;gt;.&lt;/p&gt;
&lt;p&gt;Since Func&amp;lt;int&amp;gt; and FuncToInt32 are equivalent, The above Marshal.GetExceptionCode, Marshal.HRForLastWin32Error, Marsha.GetLastWin32Error functions are of Func&amp;lt;int&amp;gt; type too.&lt;/p&gt;
&lt;p&gt;Here is another example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// (T1, T2) -&amp;gt; TResult
internal delegate TResult Func&amp;lt;T1, T2, TResult&amp;gt;(T1 value1, T2 value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above generic delegate type can represent any function type that accepts 2 parameters and return a result. For example, Func&amp;lt;string, int, int&amp;gt; is equivalent to above FuncStringInt32ToInt32, so the above CharUnicodeInfo.GetDecimalDigitValue and CharUnicodeInfo.GetDigitalValue functions are of Func&amp;lt;string, int, int&amp;gt; type too. The following are more examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public static class Math
    {
        // (double, double) -&amp;gt; double
        public static double Log(double a, double newBase);

        // (int, int) -&amp;gt; int
        public static int Max(int val1, int val2);

        // (double, int) -&amp;gt; double
        public static double Round(double value, int digits);

        // (decimal, MidpointRounding) -&amp;gt; decimal
        public static decimal Round(decimal d, MidpointRounding mode);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These functions’ types: can be represented with Func&amp;lt;double, double, double&amp;gt;, Func&amp;lt;int, int, int&amp;gt;, Func&amp;lt;double, int, double&amp;gt; and Func&amp;lt;decimal, MidpointRounding, decimal&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Unified built-in delegate types&lt;/h3&gt;
&lt;p&gt;As fore mentioned, delegate types can be defined with duplicate, like Func&amp;lt;int&amp;gt; and FuncToInt32 are equivalent, Func&amp;lt;string, int, int&amp;gt; and FuncStringInt32ToInt32are equivalent, etc. Since .NET Framework 2.0, the following delegate type is provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    // (T, T) -&amp;gt; int
    public delegate int Comparison&amp;lt;in T&amp;gt;(T x, T y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following custom delegate types can be defined too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// (T, T) -&amp;gt; int
internal delegate int NewComparison&amp;lt;in T&amp;gt;(T x, T y);

// (string, string) -&amp;gt; TResult
internal delegate TResult FuncStringString&amp;lt;TResult&amp;gt;(string value1, string value2);

// (T1, T2) -&amp;gt; int
internal delegate int FuncToInt32&amp;lt;T1, T2&amp;gt;(T1 value1, T2 value2);

// (string, string) -&amp;gt; int
internal delegate int FuncStringStringToInt32(string value1, string value2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, Func&amp;lt;string, string, int&amp;gt;, Comparison&amp;lt;string&amp;gt;, NewComparison&amp;lt;int&amp;gt;, FuncStringString&amp;lt;int&amp;gt;, FuncToInt32&amp;lt;string, string&amp;gt;, FuncStringStringToInt32 all represent (string, string) –&amp;gt; int function type. They are all equivalent.&lt;/p&gt;
&lt;p&gt;Even built-in delegate types can duplicate. For example, .NET Framework 2.0 also provides the following delegate types, which all represent object –&amp;gt; void function type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Threading
{
    // object -&amp;gt; void
    public delegate void SendOrPostCallback(object state);

    // object -&amp;gt; void
    public delegate void ContextCallback(object state);

    // object -&amp;gt; void
    public delegate void ParameterizedThreadStart(object obj);

    // object -&amp;gt; void
    public delegate void WaitCallback(object state);

    // object -&amp;gt; void
    public delegate void TimerCallback(object state);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To avoid this kind of duplication, since .NET Framework 3.5, 2 series of built-in delegate types are provided to unify all the function types. The following generic Func delegate types can represent any function type that accepts 0 ~ 16 parameters, and returns a result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    // () -&amp;gt; TResult
    public delegate TResult Func&amp;lt;out TResult&amp;gt;();

    // T -&amp;gt; TResult
    public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);

    // (T1, T2) -&amp;gt; TResult
    public delegate TResult Func&amp;lt;in T1, in T2, out TResult&amp;gt;(T1 arg1, T2 arg2);

    // (T1, T2, T3) -&amp;gt; TResult
    public delegate TResult Func&amp;lt;in T1, in T2, in T3, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3);

    // (T1, T2, T3, T4) -&amp;gt; TResult
    public delegate TResult Func&amp;lt;in T1, in T2, in T3, in T4, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

    // ...

    // (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -&amp;gt; TResult
    public delegate TResult Func&amp;lt;in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The in/out modifiers for the type parameter specifies that type parameter is contravariant/covariant, which will be discussed in detail later. However, above Func types cannot represent any function types returning void. Function type Func&amp;lt;void&amp;gt; or Func&amp;lt;System.Void&amp;gt; cannot be compiled, because C# complier does not allow generic’s type argument to be the void keyword or the System.Void type. So following generic Action delegate types are provided to represent all function types that accept 0 ~ 16 parameters, and return void:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    // () -&amp;gt; void
    public delegate void Action();

    // T -&amp;gt; void
    public delegate void Action&amp;lt;in T&amp;gt;(T obj);

    // (T1, T2) -&amp;gt; void
    public delegate void Action&amp;lt;in T1, in T2&amp;gt;(T1 arg1, T2 arg2);

    // (T1, T2, T3) -&amp;gt; void
    public delegate void Action&amp;lt;in T1, in T2, in T3&amp;gt;(T1 arg1, T2 arg2, T3 arg3);

    // (T1, T2, T3, T4) -&amp;gt; void
    public delegate void Action&amp;lt;in T1, in T2, in T3, in T4&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

    // ...

    // (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -&amp;gt; void
    public delegate void Action&amp;lt;in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For consistency, this tutorial always uses the above Func and Action delegate types to represent function types.&lt;/p&gt;
&lt;h2&gt;Delegate instance as function instance&lt;/h2&gt;
&lt;p&gt;Just like object can be instantiated from class, delegate instance can be instantiated from delegate type too. A delegate instance can represent a function, or a group of functions of the same function type.&lt;/p&gt;
&lt;p&gt;When delegate instance is used to represent a specified function, the instantiation syntax is similar to the constructor call when instantiating an object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void Constructor()
    {
        Func&amp;lt;int, int, int&amp;gt; func = new Func&amp;lt;int, int, int&amp;gt;(Math.Max);
        int result = func(1, 2);
        Trace.WriteLine(result); // 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The constructor call syntax can be omitted:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Instantiate()
{
    Func&amp;lt;int, int, int&amp;gt; func = Math.Max;
    int result = func(1, 2);
    Trace.WriteLine(result); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this syntax, above paradigm looks functional. Func&amp;lt;int, int, int&amp;gt; is the function type, func variable is the function (instance), and func variable’s value is initialized with the Math.Max function. And naturally, function func can be called. When it is called, Math.Max executes and return the result.&lt;/p&gt;
&lt;h3&gt;Delegate class and delegate instance&lt;/h3&gt;
&lt;p&gt;The above functional paradigm is actually implemented by wrapping imperative object-oriented programming. For each delegate type definition, C# compiler generates a class definition. For example, System.Func&amp;lt;T1, T2, TResult&amp;gt; delegate type is compiled to the following class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public sealed class CompiledFunc&amp;lt;in T1, in T2, out TResult&amp;gt; : MulticastDelegate
{
    public CompiledFunc(object @object, IntPtr method);

    public virtual TResult Invoke(T1 arg1, T2 arg2);

    public virtual IAsyncResult BeginInvoke(T1 arg1, T2 arg2, AsyncCallback callback, object @object);

    public virtual void EndInvoke(IAsyncResult result);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated class has a Invoke method, with the same signature as the delegate type itself. So above delegate instantiation code is a syntactic sugar compiled to normal object instantiation, and the function call is also a syntactic sugar compiled to above Invoke method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledInstantiate()
{
    CompiledFunc&amp;lt;int, int, int&amp;gt; func = new CompiledFunc&amp;lt;int, int, int&amp;gt;(null, Math.Max);
    int result = func.Invoke(1, 2);
    Trace.WriteLine(result); // 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated Invoke method can be useful along with null conditional operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Invoke(Action&amp;lt;int&amp;gt; action)
{
    action?.Invoke(0); // if (action != null) { action(0); }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The BeginInvoke and EndInvoke methods are for asynchronous programming:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceAllTextAsync(string path)
{
    Func&amp;lt;string, string&amp;gt; func = File.ReadAllText;
    func.BeginInvoke(path, TraceAllTextCallback, func);
}

internal static void TraceAllTextCallback(IAsyncResult asyncResult)
{
    Func&amp;lt;string, string&amp;gt; func = (Func&amp;lt;string, string&amp;gt;)asyncResult.AsyncState;
    string text = func.EndInvoke(asyncResult);
    Trace.WriteLine(text);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 5.0 introduces the async and await keywords. Since then, C# asynchronous programming should follow the async/await pattern instead of using above BeginInvoke/EndInvoke pattern. The async/await asynchronous programming is discussed later in this chapter.&lt;/p&gt;
&lt;p&gt;All delegate types are automatically derived from System.MulticastDelegate, and MulticastDelegate is derived from System.Delegate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public abstract class Delegate
    {
        public object Target { get; }

        public MethodInfo Method { get; }

        public static bool operator ==(Delegate d1, Delegate d2);

        public static bool operator !=(Delegate d1, Delegate d2);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So each delegate instance has Target/Method properties, and ==/!= operators. The following example demonstrates these members of delegate instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Static()
{
    Func&amp;lt;int, int, int&amp;gt; func1 = Math.Max; // new Func&amp;lt;int, int, int&amp;gt;(Math.Max);
    int result1 = func1(1, 2); // func1.Invoke(1, 2);;
    Trace.WriteLine(func1.Target == null); // True
    MethodInfo method1 = func1.Method();
    Trace.WriteLine($&quot;{method1.DeclaringType}: {method1}&quot;); // System.Math: Int32 Max(Int32, Int32)

    Func&amp;lt;int, int, int&amp;gt; func2 = Math.Max; // new Func&amp;lt;int, int, int&amp;gt;(Math.Max);
    Trace.WriteLine(object.ReferenceEquals(func1, func2)); // False
    Trace.WriteLine(func1 == func2); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, func1 looks like a function and works like a function, but it is essentially an instance of the generated class. It has an Invoke method accepting 2 int parameters and return int. Its Target property inherited from Delegate returns the underlying object which has this method. Since the underlying method is a static method, Target returns null. Its Method property returns the underlying method, Math.Max. Then delegate instance func2 is instantiated with the same static method, and apparently it is another different instance from func1. However, func1 and func2 have the same underlying static method, so the == operator returns true.&lt;/p&gt;
&lt;p&gt;In contrast, take instance method object.Equals as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Instance()
{
    object object1 = new object();
    Func&amp;lt;object, bool&amp;gt; func1 = object1.Equals; // new Func&amp;lt;object, bool&amp;gt;(object1.Equals);
    Trace.WriteLine(ReferenceEquals(func1.Target, object1)); // True
    MethodInfo method2 = func1.Method();
    Trace.WriteLine($&quot;{method2.DeclaringType}: {method2}&quot;); // System.Object: Boolean Equals(System.Object)

    object object2 = new object();
    Func&amp;lt;object, bool&amp;gt; func2 = object2.Equals; // new Func&amp;lt;object, bool&amp;gt;(object2.Equals);
    Trace.WriteLine(ReferenceEquals(func2.Target, object2)); // True
    Trace.WriteLine(object.ReferenceEquals(func1, func2)); // False
    Trace.WriteLine(func1 == func2); // False

    Func&amp;lt;object, bool&amp;gt; func3 = object1.Equals; // new Func&amp;lt;object, bool&amp;gt;(object1.Equals);
    Trace.WriteLine(object.ReferenceEquals(func1, func3)); // False
    Trace.WriteLine(func1 == func3); // True
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, func1’s Target property returns object1, which has the underlying instance method. Only when 2 delegate instance have the same underlying instance method from the same target, the == operator returns true.&lt;/p&gt;
&lt;h2&gt;Delegate instance as function group&lt;/h2&gt;
&lt;p&gt;Besides function, delegate instance can also represent function groups. The following methods are all of () –&amp;gt; string type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static string A()
{
    Trace.WriteLine(nameof(A));
    return nameof(A);
}

internal static string B()
{
    Trace.WriteLine(nameof(B));
    return nameof(B);
}

internal static string C()
{
    Trace.WriteLine(nameof(C));
    return nameof(C);
}

internal static string D()
{
    Trace.WriteLine(nameof(D));
    return nameof(D);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can be combined/uncombined with the +/- operators:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctionGroup()
{
    Func&amp;lt;string&amp;gt; a = A;
    Func&amp;lt;string&amp;gt; b = B;
    Func&amp;lt;string&amp;gt; functionGroup1 = a + b;
    functionGroup1 += C;
    functionGroup1 += D;
    string lastResult1 = functionGroup1(); // A(); B(); C(); D();
    Trace.WriteLine(lastResult1); // D

    Func&amp;lt;string&amp;gt; functionGroup2 = functionGroup1 - a;
    functionGroup2 -= D;
    string lastResult2 = functionGroup2(); // B(); C();
    Trace.WriteLine(lastResult2); // C

    Func&amp;lt;string&amp;gt; functionGroup3 = functionGroup1 - functionGroup2 + a;
    string lastResult3 = functionGroup3(); // A(); D(); A();
    Trace.WriteLine(lastResult3); // 8
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here functionGroup1 is combination of A + B + C + D. When functionGroup1 is called, the 4 internal functions are called one by one, so functionGroup1’s return value is the last function D’s return value “D”. functionGroup2 is functionGroup1 – A – D, which is B + C, so functionGroup2’s return value is “C”. functionGroup3 is functionGroup1 – functionGroup2 + A, which is A + B + A, so its return value is “A”. Actually, + is compiled to Delegate.Combine call and – is compiled to Delegate.Remove call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledFunctionGroup()
{
    Func&amp;lt;string&amp;gt; a = A;
    Func&amp;lt;string&amp;gt; b = B;
    Func&amp;lt;string&amp;gt; functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(a, b); // = A + B;
    functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(functionGroup1, new Func&amp;lt;string&amp;gt;(C)); // += C;
    functionGroup1 = (Func&amp;lt;string&amp;gt;)Delegate.Combine(functionGroup1, new Func&amp;lt;string&amp;gt;(D)); // += D;
    string lastResult1 = functionGroup1.Invoke(); // A(); B(); C(); D();
    Trace.WriteLine(lastResult1); // D

    Func&amp;lt;string&amp;gt; functionGroup2 = (Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup1, a); // = functionGroup1 - A;
    functionGroup2 = (Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup2, new Func&amp;lt;string&amp;gt;(D)); //  -= D;
    string lastResult2 = functionGroup2.Invoke(); // B(); C();
    Trace.WriteLine(lastResult2); // C

    Func&amp;lt;string&amp;gt; functionGroup3 = (Func&amp;lt;string&amp;gt;)Delegate.Combine( // = functionGroup1 - functionGroup2 + A;
        (Func&amp;lt;string&amp;gt;)Delegate.Remove(functionGroup1, functionGroup2), a);
    string lastResult3 = functionGroup3(); // A(); D(); A();
    Trace.WriteLine(lastResult3); // A
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# language utilizes delegate instance as function group to implement event. To keep it simple and consistent, this tutorial always use delegate instance to represent single function in all non-event scenarios,.&lt;/p&gt;
&lt;h3&gt;Event and event handler&lt;/h3&gt;
&lt;p&gt;C# event follows the observer pattern of object-oriented programming. After learning how delegate instance as group works, it is very easy to understand event from a functional programming perspective – a event is virtually a delegate instance as function group. The following Downloader type can download string from the specified URI, with a Completed event defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class DownloadEventArgs : EventArgs
{
    internal DownloadEventArgs(string content)
    {
        this.Content = content;
    }

    internal string Content { get; }
}

internal class Downloader
{
    internal event EventHandler&amp;lt;DownloadEventArgs&amp;gt; Completed;

    private void OnCompleted(DownloadEventArgs args)
    {
        EventHandler&amp;lt;DownloadEventArgs&amp;gt; functionGroup = this.Completed;
        functionGroup?.Invoke(this, args);
    }

    internal void Start(string uri)
    {
        using (WebClient webClient = new WebClient())
        {
            string content = webClient.DownloadString(uri);
            this.OnCompleted(new DownloadEventArgs(content));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has a Start method to start downloading. When the downloading is done, Start calls OnCompleted, and OnCompleted raises the Completed event by calling the Completed event as if it is a delegate instance. The type of event is EventHandler&amp;lt;TEventArgs&amp;gt; generic delegate type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    // (object, TEventArgs) -&amp;gt; void
    public delegate void EventHandler&amp;lt;TEventArgs&amp;gt;(object sender, TEventArgs e);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So EventHandler&amp;lt;DownloadEventArgs&amp;gt; represents (object, DownloadEventArgs) –&amp;gt; void function type, where the object argument is the Downloader instance which raises the event, and the DownloadEventArgs argument is the event info, the downloaded string. The Completed event’s handler must be function of the same (object, DownloadEventArgs) –&amp;gt; void type. The following are 2 examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// EventHandler&amp;lt;DownloadEventArgs&amp;gt;: (object, DownloadEventArgs) -&amp;gt; void
internal static void TraceContent(object sender, DownloadEventArgs args)
{
    Trace.WriteLine(args.Content);
}

// EventHandler&amp;lt;DownloadEventArgs&amp;gt;: (object, DownloadEventArgs) -&amp;gt; void
internal static void SaveContent(object sender, DownloadEventArgs args)
{
    File.WriteAllText(Path.GetTempFileName(), args.Content);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the += operator can be used to add a event handler function to the event function group, and –= operator can be used to remove the event handler function from the event function group:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void HandleEvent()
{
    Downloader downloader = new Downloader();
    downloader.Completed += TraceContent;
    downloader.Completed += SaveContent;
    downloader.Start(&quot;https://weblogs.asp.net/dixin&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;when the Start method is called, it downloads the string. When done, it raises the Completed event, which is virtually calling a function group. So that the 2 event handler functions in the group are called. To be accurately understand this mechanism, the Completed event member of type (object, EventArgs) –&amp;gt; void is compiled into 3 members: a delegate instance field of the same type, a add_Completed method, and a remove_Completed method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class CompiledDownloader
{
    private EventHandler&amp;lt;DownloadEventArgs&amp;gt; completedGroup;

    internal void add_Completed(EventHandler&amp;lt;DownloadEventArgs&amp;gt; function)
    {
        EventHandler&amp;lt;DownloadEventArgs&amp;gt; oldGroup;
        EventHandler&amp;lt;DownloadEventArgs&amp;gt; group = this.completedGroup;
        do
        {
            oldGroup = group;
            EventHandler&amp;lt;DownloadEventArgs&amp;gt; newGroup = (EventHandler&amp;lt;DownloadEventArgs&amp;gt;)Delegate.Combine(oldGroup, function);
            group = Interlocked.CompareExchange(ref this.completedGroup, newGroup, oldGroup);
        } while (group != oldGroup);
    }

    internal void remove_Completed(EventHandler&amp;lt;DownloadEventArgs&amp;gt; function)
    {
        EventHandler&amp;lt;DownloadEventArgs&amp;gt; oldGroup;
        EventHandler&amp;lt;DownloadEventArgs&amp;gt; group = this.completedGroup;
        do
        {
            oldGroup = group;
            EventHandler&amp;lt;DownloadEventArgs&amp;gt; newGroup = (EventHandler&amp;lt;DownloadEventArgs&amp;gt;)Delegate.Remove(oldGroup, function);
            group = Interlocked.CompareExchange(ref this.completedGroup, newGroup, oldGroup);
        } while (group != oldGroup);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated delegate instance field is the function group to store the event handler functions. The add_Completed and remove_Completed methods adds and removes event handler functions by calling Delegate.Combine and Delegate.Remove, in a in a thread safe approach. It can be simplified by deleting the Interlocked method calls for thread safety, and representing the (object, DownloadEventArgs) –&amp;gt; void delegate type with the normal unified Action&amp;lt;object, DownloadEventArgs&amp;gt;. The following code shows the the essentials after compilation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class SimplifiedDownloader
{
    private Action&amp;lt;object, DownloadEventArgs&amp;gt; completedGroup;

    internal void add_Completed(Action&amp;lt;object, DownloadEventArgs&amp;gt; function)
    {
        this.completedGroup += function;
    }

    internal void remove_Completed(Action&amp;lt;object, DownloadEventArgs&amp;gt; function)
    {
        this.completedGroup -= function;
    }

    private void OnCompleted(DownloadEventArgs args)
    {
        Action&amp;lt;object, DownloadEventArgs&amp;gt; functionGroup = this.completedGroup;
        functionGroup?.Invoke(this, args);
    }

    internal void Start(string uri)
    {
        using (WebClient webClient = new WebClient())
        {
            string content = webClient.DownloadString(uri);
            this.OnCompleted(new DownloadEventArgs(content));
        }
    }
}

internal static void CompiledHandleEvent()
{
    SimplifiedDownloader downloader = new SimplifiedDownloader();
    downloader.add_Completed(TraceContent);
    downloader.add_Completed(SaveContent);
    downloader.Start(&quot;https://weblogs.asp.net/dixin&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the C# event/event handler model is quite straight forward from functional programming perspective. It is all about function type, function group, and function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A event is a member of class or structure, as a C#/.NET programming convention, it should be of function type (object, TEventArgs) –&amp;gt; void. If the event is a instance member of a class or structure, the object parameter is the instance of that class or structure which raises the event; if the event is static member, the object parameter should be null. The other TEventArgs parameter should derive from System.EventArgs class, and wraps the information of the event, like the downloaded content of a download complete event, the cursor’s position for a mouse click event, etc..&lt;/li&gt;
&lt;li&gt;As a convention, event member’s type is usually represented by EventHandler&amp;lt;TEventArgs&amp;gt; delegate type, which is equivalent to Action&amp;lt;object, TEventArgs&amp;gt;.&lt;/li&gt;
&lt;li&gt;Compiler generates 3 members for a event member: a field member, which is a delegate instance as function group to store event handler function, along with 2 helper method members to add/remove event handler function.&lt;/li&gt;
&lt;li&gt;A event’s event handler is a function of the same (object, TEventArgs) –&amp;gt; void type.&lt;/li&gt;
&lt;li&gt;To handle a event, use the += operator to add the event handler function to the event function group.&lt;/li&gt;
&lt;li&gt;To raise a event, just call the function group, as a result, all the event handler functions stored in the group are called to handle the event.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This compilation of event member is similar to a auto property member, which can be compiled to a backing field, a getter and a setter. Actually C# has a event add/remove accessor syntax similar to property getter/setter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class DownloaderWithEventAccessor
{
    internal event EventHandler&amp;lt;DownloadEventArgs&amp;gt; Completed
    {
        add { this.Completed += value; }
        remove { this.Completed -= value; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The add/remove accessors are compiled to above add/remove helper methods.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (4) Function input and output</title><link>https://dixin.github.io/posts/functional-csharp-function-parameter-and-return-value-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-function-parameter-and-return-value-7/</guid><description>In C#, by default, arguments are passed to parameters by value. In the following example, the PassByValue function has a Uri parameter and a int type parameter. Uri is class so it is reference type, a</description><pubDate>Mon, 04 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-function-parameter-and-return-value&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-function-parameter-and-return-value&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;Pass by value vs. pass by reference (ref parameter)&lt;/h2&gt;
&lt;p&gt;In C#, by default, arguments are passed to parameters by value. In the following example, the PassByValue function has a Uri parameter and a int type parameter. Uri is class so it is reference type, and int is structure so it is value type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void PassByValue(Uri reference, int value)
    {
        reference = new Uri(&quot;https://flickr.com/dixin&quot;);
        value = 10;
    }

    internal static void CallPassByValue()
    {
        Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
        int value = 1;
        PassByValue(reference, value); // Copied.
        reference.WriteLine(); // https://weblogs.asp.net/dixin
        value.WriteLine(); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PassByValue is called with a reference type variable and a value type variable. With the default passing by value behavior, the reference and the value are both copied, then the copied reference and the copied value are passed to PassByValue. Inside PassByValue, it changes the reference and the value, but indeed it changes the copy of the outer variables. So after the execution of PassByValue, the outer variables passed to PassByValue remain unchanged.&lt;/p&gt;
&lt;p&gt;Parameter with a ref modifier is passed by reference, which means passed directly without being copied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PassByReference(ref Uri reference, ref int value)
{
    reference = new Uri(&quot;https://flickr.com/dixin&quot;);
    value = 10;
}

internal static void CallPassByReference()
{
    Uri reference = new Uri(&quot;https://weblogs.asp.net/dixin&quot;);
    int value = 1;
    PassByReference(ref reference, ref value); // Not copied.
    reference.WriteLine(); // https://flickr.com/dixin
    value.WriteLine(); // 10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, when PassByReference is called, the reference type variable and value type variable are both directly passed without being copied. After calling PassByReference, the outer variables are also changed.&lt;/p&gt;
&lt;h3&gt;Pass by read only reference (in parameter)&lt;/h3&gt;
&lt;p&gt;To prevent called function from modifying the argument passed by reference, in modifier can be used for the parameter since C# 7.2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PassByReadOnlyReference(in Uri reference, in int value)
{
    reference = new Uri(&quot;https://flickr.com/dixin&quot;); // Cannot be compiled.
    value = 10; // Cannot be compiled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Trying to modify the parameter passed by read only reference causes error at compile time.&lt;/p&gt;
&lt;h2&gt;Output parameter (out parameter) and out variable&lt;/h2&gt;
&lt;p&gt;C# also supports output parameter, which has a out modifier. The output parameter is also passed by reference, just like ref parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static bool Output(out Uri reference, out int value)
{
    reference = new Uri(&quot;https://flickr.com/dixin&quot;);
    value = 10;
    return false;
}

internal static void CallOutput()
{
    Uri reference;
    int value;
    Output(out reference, out value); // Not copied.
    reference.WriteLine(); // https://flickr.com/dixin
    value.WriteLine(); // 10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, the ref parameter can be viewed as input of the function, so a variable must be initialized before passed to the ref parameter. The output parameter can be viewed as output of the function, so a variable is not required to be initialized before it is passed to the output parameter. Instead, output parameter must be initialized inside the function before returning.&lt;/p&gt;
&lt;p&gt;C# 7.0 introduces a convenient syntactic sugar called out variable, so that a variable can be declared inline when it is passed to an output parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OutVariable()
{
    Output(out Uri reference, out int value);
    reference.WriteLine(); // https://flickr.com/dixin
    value.WriteLine(); // 10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compilation of OutVariable is exactly the same as above CallOutput.&lt;/p&gt;
&lt;h3&gt;Discard out variable&lt;/h3&gt;
&lt;p&gt;Since C# 7.0, if a out argument is not needed, it can be simply discarded with special character _. This syntax works with local variable too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Discard()
{
    bool result = Output(out _, out _);
    _ = Output(out _, out _);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Parameter array&lt;/h2&gt;
&lt;p&gt;Array parameter with params modifier is called parameter array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int Sum(params int[] values)
{
    int sum = 0;
    foreach (int value in values)
    {
        sum += value;
    }
    return sum;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling above function, any number of arguments can be passed to its parameter array, and, of course, array can be passed to parameter array too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallSum(int[] array)
{
    int sum1 = Sum();
    int sum2 = Sum(1);
    int sum3 = Sum(1, 2, 3, 4, 5);
    int sum4 = Sum(array);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The params modifier is compiled to System.ParamArrayAttribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int CompiledSum([ParamArray] int[] values)
{
    int sum = 0;
    foreach (int value in values)
    {
        sum += value;
    }
    return sum;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When passing argument list to parameter array, the argument list is compiled to array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCallSum(int[] array)
{
    int sum1 = Sum(Array.Empty&amp;lt;int&amp;gt;());
    int sum2 = Sum(new int[] { 1 });
    int sum3 = Sum(new int[] { 1, 2, 3, 4, 5 });
    int sum4 = Sum(array);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When function has multiple parameters, the parameter array must be the last:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ParameterArray(bool required1, int required2, params string[] optional) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Positional argument vs. named argument&lt;/h2&gt;
&lt;p&gt;By default, when calling a function, each argument must align with the parameter’s position. C# 4.0 introduces named argument, which enables specifying parameter name when passing an argument. Both positional argument and named argument can be used to call function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PositionalAndNamed()
{
    PassByValue(null, 0); // Positional arguments.
    PassByValue(reference: null, value: 0); // Named arguments.
    PassByValue(value: 0, reference: null); // Named arguments.
    PassByValue(null, value: 0); // Positional argument followed by named argument.
    PassByValue(reference: null, 0); // Named argument followed by positional argument.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a function is called with positional arguments, the arguments must align with the parameters. When a function is called with named arguments, the named arguments can be in arbitrary order. And when using positional and named arguments together, before C# 7.2, positional arguments must be followed by named arguments. Since C# 7.2, when all arguments are in correct position, then named argument can precede positional argument. At compile time, all named arguments are compiled to positional arguments. The above PassByValue calls are compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledPositionalAndNamed()
{
    PassByValue(null, 1);
    PassByValue(null, 1);
    PassByValue(null, 1);
    PassByValue(null, 1);
    PassByValue(null, 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the named arguments are evaluated inline with the function call, the order of evaluation is the same as their appearance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NamedEvaluation()
{
    PassByValue(reference: GetUri(), value: GetInt32()); // Call GetUri then GetInt32.
    PassByValue(value: GetInt32(), reference: GetUri()); // Call GetInt32 then GetUri.
}

internal static Uri GetUri() { return default; }

internal static int GetInt32() { return default; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the above PassByValue calls are compiled, local variable is generated to ensure the arguments are evaluated in the specified order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledNamedArgument()
{
    PassByValue(GetUri(), GetInt32()); // Call GetUri then GetInt32.
    int value = GetInt32(); // Call GetInt32 then GetUri.
    PassByValue(GetUri(), value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In practice, this syntax should be used with cautious because it can generate local variable, which can be slight performance hit. This tutorial uses named argument syntax frequently for readability:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Named()
{
    UnicodeEncoding unicodeEncoding1 = new UnicodeEncoding(true, true, true);
    UnicodeEncoding unicodeEncoding2 = new UnicodeEncoding(
        bigEndian: true, byteOrderMark: true, throwOnInvalidBytes: true);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Required parameter vs. optional parameter&lt;/h2&gt;
&lt;p&gt;By default, function parameters requires arguments. C# 4.0 also introduces optional parameter, with a default value specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Optional(
    bool required1, char required2,
    int optional1 = int.MaxValue, string optional2 = &quot;Default value.&quot;,
    Uri optional3 = null, Guid optional4 = new Guid(),
    Uri optional5 = default, Guid optional6 = default) { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The default value for optional parameter must be compile time constant, or default value of the type (null for reference type, or default constructor call for value type, or default expression). If a function has both required parameters and optional parameters, the required parameters must be followed by optional parameters. Optional parameter is not a syntactic sugar. The above function is compiled as the following CIL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.method assembly hidebysig static 
    void Optional (
        bool required1,
        char required2,
        [opt] int32 optional1,
        [opt] string optional2,
        [opt] class [System]System.Uri optional3,
        [opt] valuetype [mscorlib]System.Guid optional4,
        [opt] class [System]System.Uri optional5,
        [opt] valuetype [mscorlib]System.Guid optional6
    ) cil managed 
{
    .param [3] = int32(2147483647) // optional1 = int.MaxValue
    .param [4] = &quot;Default value.&quot; // optional2 = &quot;Default value.&quot;
    .param [5] = nullref // optional3 = null
    .param [6] = nullref // optional4 = new Guid()
    .param [7] = nullref // optional5 = default
    .param [8] = nullref // optional6 = default

    .maxstack 8

    IL_0000: nop
    IL_0001: ret
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And function with optional parameters can be called with the named argument syntax too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallOptional()
{
    Optional(true, &apos;@&apos;);
    Optional(true, &apos;@&apos;, 1);
    Optional(true, &apos;@&apos;, 1, string.Empty);
    Optional(true, &apos;@&apos;, optional2: string.Empty);
    Optional(
        optional6: Guid.NewGuid(), optional3: GetUri(), required1: false, optional1: GetInt32(), 
        required2: Convert.ToChar(64)); // Call Guid.NewGuid, then GetUri, then GetInt32, then Convert.ToChar.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling function with optional parameter, if the argument is not provided, the specified default value is used. Also, local variables can be generated to ensure the argument evaluation order. The above Optional calls are compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCallOptional()
{
    Optional(true, &apos;@&apos;, 1, &quot;Default value.&quot;, null, new Guid(), null, new Guid());
    Optional(true, &apos;@&apos;, 1, &quot;Default value.&quot;, null, new Guid(), null, new Guid());
    Optional(true, &apos;@&apos;, 1, string.Empty, null, new Guid(), null, new Guid());
    Optional(true, &apos;@&apos;, 1, string.Empty, null, new Guid(), null, new Guid());
    Guid optional6 = Guid.NewGuid(); // Call Guid.NewGuid, then GetUri, then GetInt32, then Convert.ToChar.
    Uri optional3 = GetUri();
    int optional1 = GetInt32();
    Optional(false, Convert.ToChar(64), optional1, &quot;Default value.&quot;, optional3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Caller information parameter&lt;/h2&gt;
&lt;p&gt;C# 5.0 introduces caller information parameters. System.Runtime.CompilerServices.CallerMemberNameAttribute, System.Runtime.CompilerServices.CallerFilePathAttribute, System.Runtime.CompilerServices.CallerLineNumberAttribute can be used for optional parameters to obtain the caller function name, caller function file name, and line number:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceWithCaller(
    string message,
    [CallerMemberName] string callerMemberName = null,
    [CallerFilePath] string callerFilePath = null,
    [CallerLineNumber] int callerLineNumber = 0)
{
    Trace.WriteLine($&quot;[{callerMemberName}, {callerFilePath}, {callerLineNumber}]: {message}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling function with caller information parameters, just omit those arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallTraceWithCaller()
{
    TraceWithCaller(&quot;Message.&quot;);
    // [CallTraceWithCaller, /home/dixin/CodeSnippets/Tutorial.Shared/Functional/Parameters.cs, 242]: Message.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At compile time, the caller information arguments are generated. The above TraceWithCaller call is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCallTraceWithCaller()
{
    TraceWithCaller(&quot;Message.&quot;, &quot;CompiledCallTraceWithCaller&quot;, @&quot;/home/dixin/CodeSnippets/Tutorial.Shared/Functional/Parameters.cs&quot;, 242);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Return by value vs. return by reference&lt;/h2&gt;
&lt;p&gt;By default, function return result by value. Similar to passing argument by value, returning by value means the returned reference or value is copied. The following functions retrieve the last item from the specified array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int LastValue(int[] values)
{
    int length = values.Length;
    if (length &amp;gt; 0)
    {
        return values[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(values));
}

internal static Uri LastReference(Uri[] references)
{
    int length = references.Length;
    if (length &amp;gt; 0)
    {
        return references[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(references));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When they returns the last item to the caller, they return a copied of the reference or value. When the returned item is changed, the item in the array remain unchanged:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReturnByValue()
{
    int[] values = new int[] { 0, 1, 2, 3, 4 };
    int lastValue = LastValue(values); // Copied.
    lastValue = 10;
    Trace.WriteLine(values[values.Length - 1]); // 4

    Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
    Uri lastReference = LastReference(references); // Copied.
    lastReference = new Uri(&quot;https://flickr.com/dixin&quot;);
    Trace.WriteLine(references[references.Length - 1]); // https://weblogs.asp.net/dixin
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 7.0 introduces returning by reference. Return result with a ref modifier is not copied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static ref int RefLastValue(int[] values)
{
    int length = values.Length;
    if (length &amp;gt; 0)
    {
        return ref values[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(values));
}

internal static ref Uri RefLastReference(Uri[] references)
{
    int length = references.Length;
    if (length &amp;gt; 0)
    {
        return ref references[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(references));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Function returning ref result can be called with the ref modifier. This time, when the returned item is changed, the item in the array is changed too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReturnByReference()
{
    int[] values = new int[] { 0, 1, 2, 3, 4 };
    ref int lastValue = ref RefLastValue(values); // Not copied.
    lastValue = 10;
    Trace.WriteLine(values[values.Length - 1]); // 10

    Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
    ref Uri lastReference = ref RefLastReference(references); // Not copied.
    lastReference = new Uri(&quot;https://flickr.com/dixin&quot;);
    Trace.WriteLine(references[references.Length - 1]); // https://flickr.com/dixin
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Return by read only reference&lt;/h3&gt;
&lt;p&gt;To prevent caller from modifying the returned result by reference, ref can be used with the readonly modifier since C# 7.2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static ref readonly int RefReadOnlyLastValue(int[] values)
{
    int length = values.Length;
    if (length &amp;gt; 0)
    {
        return ref values[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(values));
}

internal static ref readonly Uri RefReadOnlyLastReference(Uri[] references)
{
    int length = references.Length;
    if (length &amp;gt; 0)
    {
        return ref references[length - 1];
    }
    throw new ArgumentException(&quot;Array is empty.&quot;, nameof(references));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the returned result by reference becomes read only. Trying to modify it causes error at compile time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReturnByRedOnlyReference()
{
    int[] values = new int[] { 0, 1, 2, 3, 4 };
    ref readonly int lastValue = ref RefReadOnlyLastValue(values); // Not copied.
    lastValue = 10; // Cannot be compiled.
    Trace.WriteLine(values[values.Length - 1]); // 10

    Uri[] references = new Uri[] { new Uri(&quot;https://weblogs.asp.net/dixin&quot;) };
    ref readonly Uri lastReference = ref RefReadOnlyLastReference(references); // Not copied.
    lastReference = new Uri(&quot;https://flickr.com/dixin&quot;); // Cannot be compiled.
    Trace.WriteLine(references[references.Length - 1]); // https://flickr.com/dixin
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# functional programming in-depth (3) Local Function and Closure</title><link>https://dixin.github.io/posts/functional-csharp-local-function-and-closure-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-local-function-and-closure-7/</guid><description>C# 7.0 introduces local function, which allows defining and calling a named, inline function inside a function member’s body. Unlike a local variable, which has to be used after being defined, a local</description><pubDate>Sun, 03 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-local-function-and-closure&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-local-function-and-closure&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2&gt;Local function&lt;/h2&gt;
&lt;p&gt;C# 7.0 introduces local function, which allows defining and calling a named, inline function inside a function member’s body. Unlike a local variable, which has to be used after being defined, a local function can be called before or after it is defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void MethodWithLocalFunction()
    {
        void LocalFunction() // Define local function.
        {
            nameof(LocalFunction).WriteLine();
        }
        LocalFunction(); // Call local function.
    }

    internal static int PropertyWithLocalFunction
    {
        get
        {
            LocalFunction(); // Call local function.
            void LocalFunction() // Define local function.
            {
                nameof(LocalFunction).WriteLine();
            }
            LocalFunction(); // Call local function.
            return 0;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides function members, local function can also have local function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FunctionMember()
{
    void LocalFunction()
    {
        void LocalFunctionInLocalFunction() { }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unlike other named methods, local function does not support ad hoc polymorphism (overload). The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Cannot be compiled.
internal static void LocalFunctionOverload()
{
    void LocalFunction() { }
    void LocalFunction(int int32) { } // Cannot be compiled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This syntax is useful when a function is only used by another specific function. For example, the following binary search function wraps the algorithm in a helper function to for recursion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int BinarySearch&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)
{
    return BinarySearch(source, value, comparer ?? Comparer&amp;lt;T&amp;gt;.Default, 0, source.Count - 1);
}

private static int BinarySearch&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer, int startIndex, int endIndex)
{
    if (startIndex &amp;gt; endIndex) { return -1; }
    int middleIndex = startIndex + (endIndex - startIndex) / 2;
    int compare = comparer.Compare(source[middleIndex], value);
    if (compare == 0) { return middleIndex; }
    return compare &amp;gt; 0
        ? BinarySearch(source, value, comparer, startIndex, middleIndex - 1)
        : BinarySearch(source, value, comparer, middleIndex + 1, endIndex);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The helper function is only used by this binary search function, so it can be defined locally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int BinarySearchWithLocalFunction&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)
{
    int BinarySearch(
        IList&amp;lt;T&amp;gt; localSource, T localValue, IComparer&amp;lt;T&amp;gt; localComparer, int startIndex, int endIndex)
    {
        if (startIndex &amp;gt; endIndex) { return -1; }
        int middleIndex = startIndex + (endIndex - startIndex) / 2;
        int compare = localComparer.Compare(localSource[middleIndex], localValue);
        if (compare == 0) { return middleIndex; }
        return compare &amp;gt; 0
            ? BinarySearch(localSource, localValue, localComparer, startIndex, middleIndex - 1)
            : BinarySearch(localSource, localValue, localComparer, middleIndex + 1, endIndex);
    }
    return BinarySearch(source, value, comparer ?? Comparer&amp;lt;T&amp;gt;.Default, 0, source.Count - 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Local function is just a syntactic sugar. The above code is compiled to the previous implementation, where the local function is compiled to a normal method. C# local function supports closure, so above local function can be further simplified.&lt;/p&gt;
&lt;h2&gt;Closure&lt;/h2&gt;
&lt;p&gt;In object-oriented programming, it is &lt;a href=&quot;http://www.bbc.co.uk/films/2003/08/08/american_pie_the_wedding_2003_review.shtml&quot;&gt;perfectly nature normal thing&lt;/a&gt; for a method to access data inside or outside its body:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Display
{
    int outer = 1; // Outside the scope of method Add.

    internal void Add()
    {
        int local = 2; // Inside the scope of method Add.
        (local + outer).WriteLine(); // this.outer field.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here in Display type, a field is defined outside the scope of the method, so that it can be viewed as an outer variable accessed by the method, in contrast of the local variable defined inside method scope. Outer variable is also called &lt;a href=&quot;https://en.wikipedia.org/wiki/Non-local_variable&quot;&gt;non-local variable&lt;/a&gt; or &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx&quot;&gt;captured variable&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Local function supports accessing outer variable too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalFunctionClosure()
{
    int outer = 1; // Outside the scope of function Add.
    void Add()
    {
        int local = 2; // Inside the scope of function Add.
        (local + outer).WriteLine();
    }
    Add(); // 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This capability for a function or method to access an outer value, is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Closure_(computer_programming)&quot;&gt;closure&lt;/a&gt;. C# closure is a syntactic sugar. Above local function example is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
private struct Display0
{
    public int Outer;
}

private static void Add(ref Display0 display)
{
    int local = 2;
    (local + display.Outer).WriteLine();
}

internal static void CompiledLocalFunctionClosure()
{
    int outer = 1; // Outside the scope of function Add.
    Display0 display = new Display0() { Outer = outer };
    Add(ref display); // 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# compiler generates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Display0 structure as a container. It has filed to store the outer variables; if there are more local functions accessing outer variables, more display structures Display1, Display2, … are generated for each of those local functions.&lt;/li&gt;
&lt;li&gt;A normal named method to represent the local function&lt;/li&gt;
&lt;li&gt;A display structure parameter to the generated method, so that the accessed outer variables are stored in the display structure and passed to the method. In the method body, the reference to outer variable is compiled to reference to the display structure parameter’s field.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So C# compiler implements closure, a functional feature, by generating object-oriented code.&lt;/p&gt;
&lt;p&gt;With closure, the above binary search’s local function can be simplified as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static int BinarySearchWithClosure&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)
{
    int BinarySearch(int startIndex, int endIndex)
    {
        if (startIndex &amp;gt; endIndex) { return -1; }
        int middleIndex = startIndex + (endIndex - startIndex) / 2;
        int compare = comparer.Compare(source[middleIndex], value);
        if (compare == 0) { return middleIndex; }
        return compare &amp;gt; 0
            ? BinarySearch(startIndex, middleIndex - 1)
            : BinarySearch(middleIndex + 1, endIndex);
    }
    comparer = comparer ?? Comparer&amp;lt;T&amp;gt;.Default;
    return BinarySearch(0, source.Count - 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is compiled to the same display structure and named method pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
private struct Display1&amp;lt;T&amp;gt;
{
    public IComparer&amp;lt;T&amp;gt; Comparer;

    public IList&amp;lt;T&amp;gt; Source;

    public T Value;
}

[CompilerGenerated]
private static int CompiledLocalBinarySearch&amp;lt;T&amp;gt;(int startIndex, int endIndex, ref Display1&amp;lt;T&amp;gt; display)
{
    if (startIndex &amp;gt; endIndex) { return -1; }
    int middleIndex = startIndex + (endIndex - startIndex) / 2;
    int compare = display.Comparer.Compare(display.Source[middleIndex], display.Value);
    if (compare == 0) { return middleIndex; }
    return compare &amp;lt;= 0
        ? CompiledLocalBinarySearch(middleIndex + 1, endIndex, ref display)
        : CompiledLocalBinarySearch(startIndex, middleIndex - 1, ref display);
}

internal static int CompiledBinarySearchWithClosure&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; source, T value, IComparer&amp;lt;T&amp;gt; comparer = null)
{
    Display1&amp;lt;T&amp;gt; display = new Display1&amp;lt;T&amp;gt;()
    {
        Source = source,
        Value = value,
        Comparer = comparer
    };
    return CompiledLocalBinarySearch(0, source.Count - 1, ref display);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Outer variable&lt;/h3&gt;
&lt;p&gt;Apparently, outer variable can change, when this happens, the accessing local functions can be impacted. In the previous example, if the outer variable changes, the sum of outer variable and local variable is apparently different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Outer()
{
    int outer = 1; // Outside the scope of function Add.
    void Add()
    {
        int local = 2; // Inside the scope of function Add.
        (local + outer).WriteLine();
    }
    Add(); // 3
    outer = 3; // Outer variable can change.
    Add(); // 5
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes, this can be source of problems:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OuterReference()
{
    List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
    for (int outer = 0; outer &amp;lt; 3; outer++)
    {
        void LocalFunction()
        {
            (outer).WriteLine(); // outer is 0, 1, 2.
        }
        localFunctions.Add(LocalFunction);
    } // outer is 3.
    foreach (Action localFunction in localFunctions)
    {
        localFunction(); // 3 3 3 (instead of 0 1 2)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the for loop has 3 iterations. In the first iteration, outer is 0, a local function is defined to write this value, and stored in a function list. In the second iteration, outer is 1, a local function is repeatedly defined to write that value and stored, and so on. Later, when calling these 3 functions, they do not output 0, 1, 2, but 3, 3, 3, because the 3 iterations of for loop share the same outer variable, when the for loop is done, the value of outer becomes 3. Calling these 3 functions outputs the latest value of outer for 3 times, so it is 3, 3, 3.&lt;/p&gt;
&lt;p&gt;This can be resolved by taking a snapshot of shared outer variable’s current value, and store it in another variable that does not change:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CopyOuterReference()
{
    List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
    for (int outer = 0; outer &amp;lt; 3; outer++)
    {
        int copyOfOuter = outer; // outer is 0, 1, 2.
        // When outer changes, copyOfOuter does not change.
        void LocalFunction()
        {
            copyOfOuter.WriteLine();
        }
        localFunctions.Add(LocalFunction);
    } // copyOfOuter is 0, 1, 2.
    foreach (Action localFunction in localFunctions)
    {
        localFunction(); // 0 1 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In each iteration of for loop, outer variable changes, but each iteration copies its current value to a variable that is not shared cross local functions, and does not change value. When the for loop is done, 3 local function calls write the values of 3 independent variables, so it is 0, 1, 2 this time. Above code is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
private sealed class Display2
{
    public int CopyOfOuter;

    internal void LocalFunction()
    {
        this.CopyOfOuter..WriteLine();
    }
}

internal static void CompiledCopyOuterReference()
{
    List&amp;lt;Action&amp;gt; localFunctions = new List&amp;lt;Action&amp;gt;();
    for (int outer = 0; outer &amp;lt; 3; outer++)
    {
        Display2 display = new Display2() { CopyOfOuter = outer }; // outer is 0, 1, 2.
        // When outer changes, display.CopyOfOuter does not change.
        localFunctions.Add(display.LocalFunction);
    } // display.CcopyOfOuter is 0, 1, 2.
    foreach (Action localFunction in localFunctions)
    {
        localFunction(); // 0 1 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As expected, copyOfOuter variable becomes the field of display structure. And this time the local function is compiled to be a instance method of the display structure to access that field. In 3 iterations of the for loop, 3 independent instances of the display structure are constructed. When the for loop is done, each structure’s instance methods is called to write its own field value.&lt;/p&gt;
&lt;h3&gt;Implicit reference&lt;/h3&gt;
&lt;p&gt;C# closure is a powerful syntactic sugar to enable local function to directly access outer variable. However, it comes with a price. Closure can also be performance pitfall, because a hidden reference is persisted by the generated display structure’s field. As a result, closure extends the outer variable’s lifetime to the display structure’ lifetime, but the display structure is invisible at design time, so its life time is not intuitive. In the last example, copyOfOuter is a temporary variable inside the for loop block, but its value is persisted after for loop finishes executing all iterations. After 3 iterations, in total there are 3 copyOfOuter values still persisted as field by 3 structure instances. The following is another example of implicit reference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{

    internal static void Reference()
    {
        byte[] shortLife = new byte[0X7FFFFFC7]; // Local variable of large array (Array.MaxByteArrayLength).
        // ...
        void LocalFunction()
        {
            // ...
            byte @byte = shortLife[0]; // Closure.
            // ...
        }
        // ...
        LocalFunction();
        // ...
        longLife = LocalFunction; // Reference from longLife to shortLife.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The large byte array is a temp variable supposed to have a short life, but it is accessed by local function as an outer variable, and the local function is stored with a static field with a long life. The compiler generates a display structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    [CompilerGenerated]
    private sealed class Display3
    {
        public byte[] ShortLife;

        internal void LocalFunction()
        {
            // ...
            byte @byte = this.ShortLife[0];
            // ...
        }
    }

    internal static void CompiledReference()
    {
        byte[] shortLife = new byte[0X7FFFFFC7]; // Local variable of large array (Array.MaxByteArrayLength).
        // ...
        Display3 display = new Display3();
        display.ShortLife = shortLife;
        display.LocalFunction();
        // ...
        longLife = display.LocalFunction;
        // Now longLife.ShortLife holds the reference to the huge large array.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The large temp array, accessed as a outer variable, becomes a filed of the display structure, and the local function becomes a method of the display structure. When the local function is stored, actually it is a member of the display structure instance stored. So the display structure or its field cannot be garbage collected by runtime. As a result, this extended the shortLife variable’s life to the longLife static field’s life. Implicit reference problem exists in C#. Other languages supporting closure, like VB, F#, JavaScript, etc., have the same pitfall too. Closure must be used with caution.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (2) Named function and function polymorphism</title><link>https://dixin.github.io/posts/functional-csharp-named-function-and-static-instance-extension-method-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-named-function-and-static-instance-extension-method-7/</guid><description>In C#, the most intuitive functions are method members of class and structure, including static method, instance method, and extension method, etc. These methods have names at design and are called by</description><pubDate>Sat, 02 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version: &lt;a href=&quot;/posts/functional-csharp-named-function-and-static-instance-extension-method&quot;&gt;https://weblogs.asp.net/dixin/functional-csharp-named-function-and-static-instance-extension-method&lt;/a&gt;&lt;/strong&gt;&lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In C#, the most intuitive functions are method members of class and structure, including static method, instance method, and extension method, etc. These methods have names at design and are called by name, so they are named functions. Some other method-like members, including static constructor, constructor, finalizer, conversion operator, operator overload, property, indexer, event accessor, are also named functions, with specific name generated by at compiled time. This chapter discusses named functions in C#, how these named functions are defined, and looks into how they work. Method member’s name is available at design time, which some other function members’ name are generated at compile time.&lt;/p&gt;
&lt;h2&gt;Constructor, static constructor and finalizer&lt;/h2&gt;
&lt;p&gt;Class and structure can have constructor, static constructor, and finalizer. Constructor can access static and instance members, and is usually used to initialize instance members. Static constructor can only access static members, and is called only once automatically at runtime before the first instance is constructed, or before any static member is accessed. Class can also have finalizer, which usually cleanup unmanaged resources, which is called automatically before the instance is garbage collected at runtime. The following simple type Data is a simple wrapper of a int value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    private readonly int value;

    static Data() // Static constructor.
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // .cctor
    }

    internal Data(int value) // Constructor.
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // .ctor
        this.value = value;
    }

    internal int Value
    {
        get { return this.value; }
    }

    ~Data() // Finalizer.
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // Finalize
    }
    // Compiled to:
    // protected override void Finalize()
    // {
    //    try
    //    {
    //        Trace.WriteLine(MethodBase.GetCurrentMethod().Name);
    //    }
    //    finally
    //    {
    //        base.Finalize();
    //    }
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here System.Reflection.MethodBase’s static GetCurrentMethod method returns a System.Reflection.MethodInfo instance to represent the current executing function member. MethodInfo’s Name property returns the actual function name at runtime. The static constructor is compiled to a static method like member, which is parameterless and returns void, and has a special name .cctor (class constructor). The constructor is compiled to an instance method like member, with special name .ctor (constructor). And finalizer is compiled to a protected instance method Finalize, which also calls base type’s Finalize method.&lt;/p&gt;
&lt;h2&gt;Static method and instance method&lt;/h2&gt;
&lt;p&gt;Still take above Data type as example. instance method and static method and be defined in the type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    internal int InstanceAdd(int value1, int value2)
    {
        return this.value + value1 + value2;
    }

    internal static int StaticAdd(Data @this, int value1, int value2)
    {
        return @this.value + value1 + value2;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 method both add a Data instance’s value field with other integers. The difference is, the static method cannot use this keyword to access the Data instance, so a Data instance is passed to the static method as the first parameter. These 2 methods are compiled to different signature, but identical CIL in their bodies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.method assembly hidebysig instance int32 InstanceAdd (
    int32 value1,
    int32 value2) cil managed 
{
    .maxstack  2
    .locals init ([0] int32 V_0) // Local int variable V_0.
    IL_0000:  nop // Do nothing.
    IL_0001:  ldarg.0 // Load first argument this.
    IL_0002:  ldfld int32 Data::&apos;value&apos; // Load field this.value.
    IL_0007:  ldarg.1 // Load second argument value1.
    IL_0008:  add // Add this.value and value1.
    IL_0009:  ldarg.2 // Load third argument value2.
    IL_000a:  add // Add value2.
    IL_000b:  stloc.0 // Set result to first local variable V_0.
    IL_000c:  br.s IL_000e // Transfer control to IL_000e.
    IL_000e:  ldloc.0 // Load first local variable V_0.
    IL_000f:  ret // Return V_0.
}

.method assembly hidebysig static int32 StaticAdd (
    class Data this,
    int32 value1,
    int32 value2) cil managed 
{
    .maxstack  2
    .locals init ([0] int32 V_0) // Local int variable V_0.
    IL_0000:  nop // Do nothing.
    IL_0001:  ldarg.0 // Load first argument this.
    IL_0002:  ldfld int32 Data::&apos;value&apos; // Load field this.value.
    IL_0007:  ldarg.1 // Load second argument value1.
    IL_0008:  add // Add this.value and value1.
    IL_0009:  ldarg.2 // Load third argument value2.
    IL_000a:  add // Add value2.
    IL_000b:  stloc.0 // Set result to first local variable V_0.
    IL_000c:  br.s IL_000e // Transfer control to IL_000e.
    IL_000e:  ldloc.0 // Load first local variable V_0.
    IL_000f:  ret // Return V_0.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So internally, instance method works similarly to static method. The different is, in an instance method, the current instance, which can be referred by this keyword, becomes the first actual argument, the first declared argument from the method signature becomes the second actual argument, the second declared argument becomes the third actual argument, and so on. The similarity of above instance and static methods can be viewed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal int CompiledInstanceAdd(int value1, int value2)
{
    Data arg0 = this;
    int arg1 = value1;
    int arg2 = value2;
    return arg0.value + arg1 + arg2;
}

internal static int CompiledStaticAdd(Data @this, int value1, int value2)
{
    Data arg0 = @this;
    int arg1 = value1;
    int arg2 = value2;
    return arg0.value + arg1 + arg2;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Extension method&lt;/h2&gt;
&lt;p&gt;C# 3.0 introduces extension method syntactic sugar. An extension method is a static method defined in a static non-generic class, with this keyword proceeding the first parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DataExtensions
{
    internal static int ExtensionAdd(this Data @this, int value1, int value2)
    {
        return @this.Value + value1 + value2;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above method is called an extension method for Data type. It can be called like an instance method of Data type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallExtensionMethod(Data data)
{
    int result = data.ExtensionAdd(1, 2L);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So extension method’s first declared argument becomes the current instance, the second declared argument becomes the first calling argument, the third declared argument becomes the second calling argument, and so on. This syntax design is easy to understand based on the nature of instance and static methods. Actually, the extension method definition is compiled to a normal static method with System.Runtime.CompilerServices.ExtensionAttribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class DataExtensions
{
    [Extension]
    internal static int CompiledExtensionAdd(Data @this, int value1, int value2)
    {
        return @this.Value + value1 + value2;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the extension method call is compiled to normal static method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCallExtensionMethod(Data data)
{
    int result = DataExtensions.ExtensionAdd(data, 1, 2L);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a real instance method and an extension name are both defined for the same type with equivalent signature:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data : IEquatable&amp;lt;Data&amp;gt;
{
    public override bool Equals(object obj)
    {
        return obj is Data &amp;amp;&amp;amp; this.Equals((Data)obj);
    }

    public bool Equals(Data other) // Member of IEquatable&amp;lt;T&amp;gt;.
    {
        return this.value == other.value;
    }
}

internal static partial class DataExtensions
{
    internal static bool Equals(Data @this, Data other)
    {
        return @this.Value == other.Value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The instance style method call is compiled to instance method call; In order to call the extension method, use the static method call syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functions
{
    internal static void CallMethods(Data data1, Data data2)
    {
        bool result1 = data1.Equals(string.Empty); // object.Equals.
        bool result2 = data1.Equals(data2); // Data.Equals.
        bool result3 = DataExtensions.Equals(data1, data2); // DataExtensions.Equals.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When compiling instance style method call, C# compiler looks up methods in the following order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;instance method defined in the type&lt;/li&gt;
&lt;li&gt;extension method defined in the current namespace&lt;/li&gt;
&lt;li&gt;extension method defined in the current namespace’s parent namespaces&lt;/li&gt;
&lt;li&gt;extension method defined in the other namespaces imported by using directives&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Extension method can be viewed as if instance method “added” to the specified type. For example, as fore mentioned, enumeration types cannot have methods. However, extension method can be defined for enumeration type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class DayOfWeekExtensions
{
    internal static bool IsWeekend(this DayOfWeek dayOfWeek)
    {
        return dayOfWeek == DayOfWeek.Sunday || dayOfWeek == DayOfWeek.Saturday;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the above extension method can be called as if it is the enumeration type’s instance method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CallEnumerationExtensionMethod(DayOfWeek dayOfWeek)
{
    bool result = dayOfWeek.IsWeekend();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of the LINQ query methods are extension methods, like the Where, OrderBy, Select methods demonstrated previously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods’ usage and implementation will be discussed in detail in the LINQ to Objects chapter.&lt;/p&gt;
&lt;p&gt;This tutorial uses the following extension methods to simplify the tracing of single value and values in sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class TraceExtensions
{
    public static T WriteLine&amp;lt;T&amp;gt;(this T value)
    {
        Trace.WriteLine(value);
        return value;
    }

    public static T Write&amp;lt;T&amp;gt;(this T value)
    {
        Trace.Write(value);
        return value;
    }

    public static IEnumerable&amp;lt;T&amp;gt; WriteLines&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; values, Func&amp;lt;T, string&amp;gt; messageFactory = null)
    {
        if (messageFactory!=null)
        {
            foreach (T value in values)
            {
                string message = messageFactory(value);
                Trace.WriteLine(message);
            }
        }
        else
        {
            foreach (T value in values)
            {
                Trace.WriteLine(value);
            }
        }
        return values;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The WriteLine and Write extension methods are available for any value, and WriteLines is available for any IEnumerable&amp;lt;T&amp;gt; sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceValueAndSequence(Uri value, IEnumerable&amp;lt;Uri&amp;gt; values)
{
    value.WriteLine();
    // Equivalent to: Trace.WriteLine(value);

    values.WriteLines();
    // Equivalent to: 
    // foreach (Uri value in values)
    // {
    //    Trace.WriteLine(value);
    // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More named functions&lt;/h2&gt;
&lt;p&gt;C# supports operator overload and type conversion operator are defined, they are compiled to static methods. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    public static Data operator +(Data data1, Data data2)
    // Compiled to: public static Data op_Addition(Data data1, Data data2)
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Addition
        return new Data(data1.value + data2.value);
    }

    public static explicit operator int(Data value)
    // Compiled to: public static int op_Explicit(Data data)
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Explicit
        return value.value;
    }

    public static explicit operator string(Data value)
    // Compiled to: public static string op_Explicit(Data data)
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Explicit
        return value.value.ToString();
    }

    public static implicit operator Data(int value)
    // Compiled to: public static Data op_Implicit(int data)
    {
        Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // op_Implicit
        return new Data(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The + operator overload is compiled to static method with name op_Addition, the explicit/implicit type conversions are compiled to static methods op_Explicit/op_Implicit method. These operators’ usage are compiled to static method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Operators(Data data1, Data data2)
{
    Data result = data1 + data2; // Compiled to: Data.op_Addition(data1, data2)
    int int32 = (int)data1; // Compiled to: Data.op_Explicit(data1)
    string @string = (string)data1; // Compiled to: Data.op_Explicit(data1)
    Data data = 1; // Compiled to: Data.op_Implicit(1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the above 2 op_Explicit methods are the special case of ad hoc polymorphism (method overload) in C#.&lt;/p&gt;
&lt;p&gt;Property member’s getter and setter are also compiled to named methods. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
{
    private string description;

    internal string Description
    {
        get // Compiled to: internal string get_Description()
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // get_Description
            return this.description;
        }
        set // Compiled to: internal void set_Description(string value)
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // set_Description
            this.description = value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The property getter and setter calls are compiled to method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Property(Device device)
{
    string description = device.Description; // Compiled to: device.get_Description()
    device.Description = string.Empty; // Compiled to: device.set_Description(string.Empty)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Indexer member can be viewed as parameterized property. The indexer getter/setter are always compiled to get_Item/set_Item methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Category
{
    private readonly Subcategory[] subcategories;

    internal Category(Subcategory[] subcategories)
    {
        this.subcategories = subcategories;
    }

    internal Subcategory this[int index]
    {
        get // Compiled to: internal Uri get_Item(int index)
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // get_Item
            return this.subcategories[index];
        }
        set // Compiled to: internal Uri set_Item(int index, Subcategory subcategory)
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // set_Item
            this.subcategories[index] = value;
        }
    }
}

internal static void Indexer(Category category)
{
    Subcategory subcategory = category[0]; // Compiled to: category.get_Item(0)
    category[0] = subcategory; // Compiled to: category.set_Item(0, subcategory)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, a event has an add accessor and a remove accessor, which are either custom defined, or generated by compiler. They are compiled to named methods as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Data
{
    internal event EventHandler Saved
    {
        add // Compiled to: internal void add_Saved(EventHandler value)
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // add_Saved
        }
        remove // Compiled to: internal void remove_Saved(EventHandler value)
        {
            Trace.WriteLine(MethodBase.GetCurrentMethod().Name); // remove_Saved
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Event is a function group. The +=/-= operators adds remove event handler function to the event, and –= operator removes event handler function from the event. They are compiled to the calls to above named methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DataSaved(object sender, EventArgs args) { }

internal static void EventAccessor(Data data)
{
    data.Saved += DataSaved; // Compiled to: data.add_Saved(DataSaved)
    data.Saved -= DataSaved; // Compiled to: data.remove_Saved(DataSaved)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#’s event is discussed in detail in the delegate chapter.&lt;/p&gt;
&lt;h2&gt;Function polymorphisms&lt;/h2&gt;
&lt;p&gt;The word “Polymorphism” comes from Greek, means “many shapes”. In programming, there are several kinds of polymorphisms. In object-oriented programming, a derived type can override base type’s methods to provide. For example, System.IO.FileStream type and System.IO.Memory type derives from System.IO.Stream type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.IO
{
    public abstract class Stream : MarshalByRefObject, IDisposable
    {
        public virtual void WriteByte(byte value);
    }

    public class FileStream : Stream
    {
        public override void WriteByte(byte value);
    }

    public class MemoryStream : Stream
    {
        public override void WriteByte(byte value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;FileStream.WriteByte overrides Stream.WriteByte to implement writing to file system, and MemoryStream.WriteByte overrides Stream.WriteByte to implement writing to memory. This is called subtype polymorphism or inclusion polymorphism. In object-oriented programming, the term polymorphism usually refers to subtype polymorphism. There are also ad hoc polymorphism and parametric polymorphism. In functional programming, the term polymorphism usually refers to parametric polymorphism.&lt;/p&gt;
&lt;h3&gt;Ad hoc polymorphism: method overload&lt;/h3&gt;
&lt;p&gt;Method overloading allows multiple methods to have the same method name, with different parameter numbers and/or types. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Diagnostics
{
    public sealed class Trace
    {
        public static void WriteLine(string message);

        public static void WriteLine(object value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, the WriteLine overload for string writes the string message. If this is the only method provided, then all the non-string values have to be manually converted to string representation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Functions
{
    internal static void TraceString(Uri uri, FileInfo file, int int32)
    {
        Trace.WriteLine(uri?.ToString());
        Trace.WriteLine(file?.ToString());
        Trace.WriteLine(int32.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The WriteLine overload for object provides convenience for values of arbitrary types. The above code can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TraceObject(Uri uri, FileInfo file, int int32)
{
    Trace.WriteLine(uri);
    Trace.WriteLine(file);
    Trace.WriteLine(int32);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With multiple overloads, WriteLine method is polymorphic and can be called with different arguments. This is called ad hoc polymorphism. In the .NET core library, the most ad hoc polymorphic method is System.Convert’s ToString method. It has 36 overloads to convert values of different types to string representation, in different ways:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public static class Convert
    {
        public static string ToString(bool value);

        public static string ToString(int value);

        public static string ToString(long value);

        public static string ToString(decimal value);

        public static string ToString(DateTime value);

        public static string ToString(object value);

        public static string ToString(int value, IFormatProvider provider);

        public static string ToString(int value, int toBase);

        // More overloads and other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#/.NET, constructors can have parameters too, so they can also be overloaded. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public struct DateTime : IComparable, IFormattable, IConvertible, IComparable&amp;lt;DateTime&amp;gt;, IEquatable&amp;lt;DateTime&amp;gt;
    {
        public DateTime(long ticks);

        public DateTime(int year, int month, int day);

        public DateTime(int year, int month, int day, int hour, int minute, int second);

        public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);

        // Other constructor overloads and other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Indexers are essentially get_Item/set_Item methods with parameters, so they can be overloaded as well. Take System.Data.DataRow as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data
{
    public class DataRow
    {
        public object this[DataColumn column] { get; set; }

        public object this[string columnName] { get; set; }

        public object this[int columnIndex] { get; set; }

        // Other indexer overloads and other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# does not allow method overload with only different return type. The following example cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static string FromInt64(long value)
{
    return value.ToString();
}

internal static DateTime FromInt64(long value)
{
    return new DateTime(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a exception for this. In the above example, 2 explicit type conversion operators are both compiled to op_Explicit methods with a single Data parameter. One op_Explicit method returns a int, the other op_Explicit method returns string. This is the only case where C# allows method overload with only different return type.&lt;/p&gt;
&lt;h3&gt;Parametric polymorphism: generic method&lt;/h3&gt;
&lt;p&gt;Besides ad hoc polymorphism, C# also supports parametric polymorphism for methods since 2.0. The following is a normal method that swaps 2 int values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SwapInt32(ref int value1, ref int value2)
{
    (value1, value2) = (value2, value1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above syntax is called tuple assignment, which is a new feature of C# 7.0, and is discussed in the tuple chapter. To reuse this code for values of any other type, just define a generic method, by replacing int with a type parameter. Similar to generic types, generic method’s type parameters are also declared in angle brackets following the method name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Swap&amp;lt;T&amp;gt;(ref T value1, ref T value2)
{
    (value1, value2) = (value2, value1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generic type parameter’s constraints syntax also works for generic method. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IStack&amp;lt;T&amp;gt; PushValue&amp;lt;T&amp;gt;(IStack&amp;lt;T&amp;gt; stack) where T : new()
{
    stack.Push(new T());
    return stack;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generic types as well as generic methods are heavily used in C# functional programming. For example, almost every LINQ query API is parametric polymorphic.&lt;/p&gt;
&lt;h3&gt;Type argument inference&lt;/h3&gt;
&lt;p&gt;When calling generic method, if C# compiler can infer generic method’s all type arguments, then the type arguments can be omitted at design time. For example,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TypeArgumentInference(string value1, string value2)
{
    Swap&amp;lt;string&amp;gt;(ref value1, ref value2);
    Swap(ref value1, ref value2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Swap is called with string values, so C# compiler infers type argument string is passed to the method’s type parameter T. C# compiler can only infer type arguments from type of arguments, not from type of return value. Take the following generic methods as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static T Generic1&amp;lt;T&amp;gt;(T value)
{
    Trace.WriteLine(value);
    return default(T);
}

internal static TResult Generic2&amp;lt;T, TResult&amp;gt;(T value)
{
    Trace.WriteLine(value);
    return default(TResult);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling them, Generic1’s type argument can be omitted, but Generic2’s type arguments cannot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ReturnTypeInference()
{
    int value1 = Generic1(0);
    string value2 = Generic2&amp;lt;int, string&amp;gt;(0); // Generic2&amp;lt;int&amp;gt;(0) cannot be compiled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Generic1, T is used as return type, but it can be inferred from the argument type. So type argument can be omitted for Generic1. For Generic2, T can be inferred from argument type too, but TResult can only possibly be inferred from type of return value, which is not supported by C# compiler. As a result, type arguments cannot be omitted when calling Generic2. Otherwise, C# compiler gives error CS0411: The type arguments for method &apos;Functions.Generic2&amp;lt;T, TResult&amp;gt;(T)&apos; cannot be inferred from the usage. Try specifying the type arguments explicitly.&lt;/p&gt;
&lt;p&gt;Type cannot be inferred from null because null can be of any reference type or nullable value type. For example, when calling above Generic1 with null:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NullArgumentType()
{
    Generic1&amp;lt;FileInfo&amp;gt;(null);
    Generic1((FileInfo)null);
    FileInfo file = null;
    Generic1(file);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;there are some options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provide the type argument&lt;/li&gt;
&lt;li&gt;Explicitly convert null to the expected argument type&lt;/li&gt;
&lt;li&gt;Create a temporary variable of the expected argument type, pass the value to the generic method&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Type argument inference is not supported for generic type’s constructor. Take the following generic type as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Generic&amp;lt;T&amp;gt;
{
    internal Generic(T input) { } // T cannot be inferred.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling above constructor, type arguments must be provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; GenericConstructor(
    IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; input)
{
    return new Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;(input);
    // Cannot be compiled:
    // return new Generic(input);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A solution is to wrap the constructor call in a static factory method , where type parameter can be inferred:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Generic // Not Generic&amp;lt;T&amp;gt;.
{
    internal static Generic&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(T input) =&amp;gt; new Generic&amp;lt;T&amp;gt;(input); // T can be inferred.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the instance can be constructed without type argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Generic&amp;lt;IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; GenericCreate(
    IEnumerable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; input)
{
    return Generic.Create(input);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Static import&lt;/h2&gt;
&lt;p&gt;C# 6.0 introduces using static directive, a syntactic sugar, to enable accessing static member of the specified type, so that a static method can be called type name as if it is a functions on the fly. Since extension are essentially static method, this syntax can also import extension methods from the specified type. It also enables accessing enumeration member without enumeration type name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using static System.DayOfWeek;
using static System.Math;
using static System.Diagnostics.Trace;
using static System.Linq.Enumerable;

internal static partial class Functions
{
    internal static void UsingStatic(int value, int[] array)
    {
        int abs = Abs(value); // Compiled to: Math.Abs(value)
        WriteLine(Monday); // Compiled to: Trace.WriteLine(DayOfWeek.Monday)
        List&amp;lt;int&amp;gt; list = array.ToList(); // Compiled to: Enumerable.ToList(array)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The using directive imports the specified all types’ extension methods under the specified namespace, while the using static directive only import the specified type’s extension methods.&lt;/p&gt;
&lt;h2&gt;Partial method&lt;/h2&gt;
&lt;p&gt;Partial methods can be defined in partial class or partial structure. One part of the type can have the partial method signature, and the partial method can be optionally implemented in another part of the type. This syntactic sugar is useful for code generation. For example, LINQ to SQL can generate entity type in the following pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;Production.Product&quot;)]
public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
{
    public Product()
    {
        this.OnCreated(); // Call.
    }

    partial void OnCreated(); // Signature.

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The constructor calls partial method OnCreate, which is a hook. If needed, developer can provide another part of the entity type to implement OnCreate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    partial void OnCreated() // Optional implementation.
    {
        Trace.WriteLine($&quot;{nameof(Product)} is created.&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a partial method is implemented, it is compiled to a normal private method. If a partial method is not implemented, the compiler ignores the method signature, and remove all the method calls. For this reason, access modifiers (like public, etc.), attributes, non-void return value are not allowed for partial method.&lt;/p&gt;
</content:encoded></item><item><title>C# functional programming in-depth (1) C# language fundamentals</title><link>https://dixin.github.io/posts/functional-csharp-fundamentals-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/functional-csharp-fundamentals-7/</guid><description>C# 1.0 was initially released in 2002, as its first language specification says at the beginning, C# is a “simple, modern, object oriented, and type-safe” programming language for general purpose. Now</description><pubDate>Fri, 01 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Functional%20C%23&quot;&gt;C# functional programming in-depth series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version:&lt;/strong&gt; &lt;a href=&quot;/posts/functional-csharp-fundamentals&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/functional-csharp-fundamentals&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C# 1.0 was initially released in 2002, as its first language specification says at the beginning, C# is a “simple, modern, object oriented, and type-safe” programming language for general purpose. Now C# has evolved to 7.2. During the years, a lot of great language features, especially rich functional programming features, has been added to C#. Now C# language has been productive and elegant, imperative and declarative, object-oriented and functional. With frameworks like .NET Framework, .NET Core, Mono, Xamarin, Unity, etc., C# is used by millions of people cross different platforms, including Windows, Linux, Mac, iOS, Android, etc.&lt;/p&gt;
&lt;p&gt;This tutorial is totally for C# language focusing on its functional aspects. The readers are assumed to have the general concepts on programming and C# language. This chapter reviews the basic but important elements and syntax of C# 1.0 - 7.x, to warm up the beginner level readers, as well as readers who are not yet familiar with some new syntax introduced in recent C# releases. The other advanced features and concepts will be discussed in detail in later chapters. This tutorial does not cover the topics and language features out of the scope of functional programming and LINQ, like inheritance of object-oriented programming, pointer in unsafe code, interop with other unmanaged code, dynamic programming, etc..&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;635&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;Features in this chapter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Features in other chapters&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;Features not covered&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;1.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;Class Structure Interface Enumeration using statement&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Delegate Event Function member ref parameter out parameter Parameter array foreach statement&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;Inheritance Pointer Interop&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;1.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;pragma directive&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;1.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;foreach for IDisposable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;2.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;Static class Partial type Generic type Nullable value type Null coalescing operator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Anonymous method Generator Covariance and contravariance Generic method&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;3.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;Auto property Object initializer Collection initializer&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Anonymous type Implicitly typed local variable Query expression Lambda expression Extension method Partial method&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;4.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Named argument Optional argument Generic covariance and contravariance&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;Dynamic binding&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;5.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Asynchronous function Caller info argument&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;6.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;Property initializer Dictionary initializer Null propagation operator Exception filter String interpolation nameof operator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Static import Expression bodied member await in catch/finally block&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;7.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;throw expression Digit separator&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Out variable Tuple and deconstruction Local function Expanded expression bodied member ref return and local Discard Generalized asynchronous return throw expression Pattern matching&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;7.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;default literal expression&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Async Main method Inferred tuple element name&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;48&quot;&amp;gt;7.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;180&quot;&amp;gt;ref structure Leading underscores in numeric literals&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;249&quot;&amp;gt;Non-trailing named arguments in parameter ref readonly return and local Readonly structure&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;156&quot;&amp;gt;private protected modifier&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;Types and members&lt;/h2&gt;
&lt;p&gt;C# is strongly typed. In C#, any value has a type. C# supports &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/zcx1eb1e.aspx&quot;&gt;5 kinds of types&lt;/a&gt;: class, structure, enumeration, delegate, and interface.&lt;/p&gt;
&lt;p&gt;A class is a reference type defined with the class keyword. It can have fields, properties, methods, events, operators, indexers, constructors, destructor, and nested class, structure, enumeration, delegate, and interface types. A class is always derived from &lt;strong&gt;System.Object&lt;/strong&gt; class.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public class Object
    {
        public Object();

        public static bool Equals(Object objA, Object objB);

        public static bool ReferenceEquals(Object objA, Object objB);

        public virtual bool Equals(Object obj);

        public virtual int GetHashCode();

        public Type GetType();

        public virtual string ToString();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object has a static Equals method to test whether 2 instances are considered equal, an instance Equals method to test whether the current instance and the other instance are considered equal, and a static ReferenceEquals method to test whether 2 instances are the same instance. It has a GetHashCode method as the default hash function to return a hash code number for quick test of instances. It also has a GetType method to return the type of current instance, and a ToString method to return the text representation of the current instance.&lt;/p&gt;
&lt;p&gt;The following example is a segment of System.Exception class implementation in .NET Framework. It demonstrates the syntax to define a class and different kinds of members**.** This class implements the System.ISerializable interface, and derives the System._Exception class. When defining a class, base class System.Object can be omitted.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [Serializable]
    public class Exception : ISerializable, _Exception // , System.Object
    {
        internal string _message; // Field.
        
        private Exception _innerException; // Field.

        [OptionalField(VersionAdded = 4)]
        private SafeSerializationManager _safeSerializationManager; // Field.

        public Exception InnerException { get { return this._innerException; } } // Property.

        public Exception(string message, Exception innerException) // Constructor.
        {
            this.Init();
            this._message = message;
            this._innerException = innerException;
        }

        public virtual Exception GetBaseException() // Method.
        {
            Exception innerException = this.InnerException;
            Exception result = this;
            while (innerException != null)
            {
                result = innerException;
                innerException = innerException.InnerException;
            }
            return result;
        }

        protected event EventHandler&amp;lt;SafeSerializationEventArgs&amp;gt; SerializeObjectState // Event.
        {
            add
            {
                this._safeSerializationManager.SerializeObjectState += value;
            }
            remove
            {
                this._safeSerializationManager.SerializeObjectState -= value;
            }
        }

        internal enum ExceptionMessageKind // Nested enumeration type.
        {
            ThreadAbort = 1,
            ThreadInterrupted = 2,
            OutOfMemory = 3
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A structure is value type defined with the struct keyword, which is then derived from &lt;strong&gt;System.Object&lt;/strong&gt; class. It can have all kinds of members of class except destructor. A structure always derives from &lt;strong&gt;System.ValueType&lt;/strong&gt; class, and interestingly, System.ValueType is a reference type derived from System.Object. In practice, a structure is usually defined to represent very small and immutable data structure, in order to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms229017.aspx&quot;&gt;improve the performance&lt;/a&gt; of memory allocation/deallocation. For example, the . In .NET Core System. is implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public struct TimeSpan : IComparable, IComparable&amp;lt;TimeSpan&amp;gt;, IEquatable&amp;lt;TimeSpan&amp;gt;, IFormattable // , System.ValueType
    {
        public const long TicksPerMillisecond = 10000; // Constant.

        public static readonly TimeSpan Zero = new TimeSpan(0); // Field.

        internal long _ticks; // Field.

        public TimeSpan(long ticks) // Constructor.
        {
            this._ticks = ticks;
        }

        public long Ticks { get { return _ticks; } } // Property.

        public int Milliseconds // Property.
        {
            get { return (int)((_ticks / TicksPerMillisecond) % 1000); }
        }

        public static bool Equals(TimeSpan t1, TimeSpan t2) // Method.
        {
            return t1._ticks == t2._ticks;
        }

        public static bool operator ==(TimeSpan t1, TimeSpan t2) // Operator.
        {
            return t1._ticks == t2._ticks;
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An enumeration is a value type derived from System.Enum class, which is derived from System.ValueType class. It can only have constant fields of the specified underlying integral type (&lt;strong&gt;int&lt;/strong&gt; by default). For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    [Serializable]
    public enum DayOfWeek // : int
    {
        Sunday = 0,
        Monday = 1,
        Tuesday = 2,
        Wednesday = 3,
        Thursday = 4,
        Friday = 5,
        Saturday = 6,
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A delegate is a reference type derived from &lt;strong&gt;System.MulticastDelegate&lt;/strong&gt; class, which is derived from &lt;strong&gt;System.Delegate&lt;/strong&gt; class. Delegate type represents function type, and is discussed in detail in the functional programming chapter.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate void Action();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An interface is a contract to be implemented by class or structure. Interface can only have public and abstract properties, methods, and events without implementation. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.ComponentModel
{
    public interface INotifyDataErrorInfo
    {
        event EventHandler&amp;lt;DataErrorsChangedEventArgs&amp;gt; ErrorsChanged; // Event.

        bool HasErrors { get; } // Property.

        IEnumerable GetErrors(string propertyName); // Method.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Any class or structure implementing the above interface must have the specified 3 members as public.&lt;/p&gt;
&lt;h3&gt;Built-in types&lt;/h3&gt;
&lt;p&gt;There are basic. NET types most commonly used in C# programming, so C# provides language keywords as aliases of those types, which are called built-in types of C#:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;1&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;320&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;C# keyword&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;.NET type&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;bool&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Boolean&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;sbyte&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.SByte&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;byte&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Byte&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;char&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Char&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;short&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Init16&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;ushort&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.UInit16&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;int&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Init32&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;uint&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.UInit32&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;long&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Init54&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;ulong&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.UInit54&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;float&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Single&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;double&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Double&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;decimal&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Decimal&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;object&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.Object&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;140&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;Reference type vs. value type&lt;/h2&gt;
&lt;p&gt;In C#/.NET, classes are reference types, including object, string, array, etc.. Delegates is also reference type, which is discussed later. Structures are value types, including primitive types (&lt;strong&gt;bool&lt;/strong&gt;, &lt;strong&gt;sbyte&lt;/strong&gt;, &lt;strong&gt;byte&lt;/strong&gt;, &lt;strong&gt;char&lt;/strong&gt;, &lt;strong&gt;short&lt;/strong&gt;, &lt;strong&gt;ushort&lt;/strong&gt;, &lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;uint&lt;/strong&gt;, &lt;strong&gt;long&lt;/strong&gt;, &lt;strong&gt;ulong&lt;/strong&gt;, &lt;strong&gt;float&lt;/strong&gt;, &lt;strong&gt;double&lt;/strong&gt;), &lt;strong&gt;decimal&lt;/strong&gt;, &lt;strong&gt;System.DateTime&lt;/strong&gt;, &lt;strong&gt;System.DateTimeOffset&lt;/strong&gt;, &lt;strong&gt;System.TimeSpan&lt;/strong&gt;, &lt;strong&gt;System.Guid&lt;/strong&gt;, &lt;strong&gt;System.Nullable&amp;lt;T&amp;gt;&lt;/strong&gt;, enumeration (since enumeration’s underlying type is always a numeric primitive type), etc. The following example defines a reference type and a value type, which look similar to each other:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Point
{
    private readonly int x;

    private readonly int y;

    internal Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    internal int X { get { return this.x; } }

    internal int Y { get { return this.y; } }
}

internal readonly struct ValuePoint
{
    private readonly int x;

    private readonly int y;

    internal ValuePoint(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    internal int X { get { return this.x; } }

    internal int Y { get { return this.y; } }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instances of reference type and value type are allocated differently. Reference type is always allocated on the managed heap, and deallocated by garbage collection. Value type is either allocated on the stack and deallocated by stack unwinding, or is allocated and deallocated inline with the container. So generally value type can have better performance for allocation and deallocation. Usually, a type &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms229017.aspx&quot;&gt;can be designed as value type&lt;/a&gt; if it is small, immutable, and logically similar to a primitive type. The above &lt;strong&gt;System.TimeSpan&lt;/strong&gt; type structure represents a duration of time, it is designed to be value type, because it is just a immutable wrapper of a long value, which represents ticks. The following example demonstrates this difference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Fundamentals
{
    internal static void ValueTypeReferenceType()
    {
        Point reference1 = new Point(1, 2);
        Point reference2 = reference1;
        Trace.WriteLine(object.ReferenceEquals(reference1, reference2)); // True

        ValuePoint value1 = new ValuePoint(3, 4);
        ValuePoint value2 = value1;
        Trace.WriteLine(object.ReferenceEquals(value1, value2)); // False

        Point[] referenceArray = new Point[] { new Point(5, 6) };
        ValuePoint[] valueArray = new ValuePoint[] { new ValuePoint(7, 8) };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a &lt;strong&gt;Point&lt;/strong&gt; instance is constructed as a local variable, since it is reference type, it is allocated in the managed heap. Its fields are value types, so the fields are allocated inline on the managed heap too. The local variable &lt;strong&gt;reference1&lt;/strong&gt; can be viewed as a pointer, pointing to managed heap location that holds the data. When assigning &lt;strong&gt;reference1&lt;/strong&gt; to &lt;strong&gt;reference2&lt;/strong&gt;, the pointer is copied. So &lt;strong&gt;reference1&lt;/strong&gt; and &lt;strong&gt;reference2&lt;/strong&gt; both point to the same &lt;strong&gt;Point&lt;/strong&gt; instance in the managed heap. When &lt;strong&gt;ValuePoint&lt;/strong&gt; is constructed as a local variable, since it is value type. it is allocated in the stack. Its fields are also allocated inline in the stack. The local variable &lt;strong&gt;value1&lt;/strong&gt; holds the actual data. When assigning value1 to &lt;strong&gt;value2&lt;/strong&gt;, the entire instance is copied, so &lt;strong&gt;value1&lt;/strong&gt; and &lt;strong&gt;value2&lt;/strong&gt; are 2 different &lt;strong&gt;ValuePoint&lt;/strong&gt; instances in stack. In C#, array always derives from System.Array class and is reference type. So referenceArray and valueArray are both allocated on heap, and their elements are both on heap too.&lt;/p&gt;
&lt;p&gt;Reference type can be null and value type cannot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Default()
{
    Point defaultReference = default(Point);
    Trace.WriteLine(defaultReference is null); // True

    ValuePoint defaultValue = default(ValuePoint);
    Trace.WriteLine(defaultValue.X); // 0
    Trace.WriteLine(defaultValue.Y); // 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The default value of reference type is simply null. The default of value type is an actual instance, with all fields initialized to their default values. Actually, the above local variables’ initialization is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledDefault()
{
    Point defaultReference = null;

    ValuePoint defaultValue = new ValuePoint();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A structure always virtually has a parameterless default constructor. Calling this default constructor instantiates the structure and sets all its fields to default values. Here &lt;strong&gt;defaultValue&lt;/strong&gt;’s &lt;strong&gt;int&lt;/strong&gt; fields are initialized to 0. If &lt;strong&gt;ValuePoint&lt;/strong&gt; has a reference type field, the reference type field is initialized to null.&lt;/p&gt;
&lt;h3&gt;default literal expression&lt;/h3&gt;
&lt;p&gt;Since C# 7.1, the type in the default value expression can be omitted, if the type can be inferred. So the above default value syntax can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultLiteralExpression()
{
    Point defaultReference = default;

    ValuePoint defaultValue = default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ref structure&lt;/h3&gt;
&lt;p&gt;C# 7.2 enables the ref keyword for structure definition, so that the structure can be only allocated on stack. This can be helpful for performance critical scenarios, where memory allocation/deallocation on heap can be performance overhead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal ref struct OnStackOnly { }

internal static void Allocation()
{
    OnStackOnly valueOnStack = new OnStackOnly();
    OnStackOnly[] arrayOnHeap = new OnStackOnly[10]; // Cannot be compiled.
}

internal class OnHeapOnly
{
    private OnStackOnly fieldOnHeap; // Cannot be compiled.
}

internal struct OnStackOrHeap
{
    private OnStackOnly fieldOnStackOrHeap; // Cannot be compiled.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, array is reference type allocated on heap, so the compiler does not allow an array of ref structure. A instance of class is always instantiated on heap, so ref structure cannot be used as its field. A instance of normal structure can be on stack or heap, so ref structure cannot be used as its field either.&lt;/p&gt;
&lt;h2&gt;Static class&lt;/h2&gt;
&lt;p&gt;C# 2.0 enables &lt;strong&gt;static&lt;/strong&gt; modifier for class definition. Take System.Math as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public static class Math
    {
        // Static members only.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A static class can only have static members, and cannot be instantiated. Static class is compiled to abstract sealed class. In C# static is frequently used to host a series of static methods.&lt;/p&gt;
&lt;h2&gt;Partial type&lt;/h2&gt;
&lt;p&gt;C# 2.0 introduces the &lt;strong&gt;partial&lt;/strong&gt; keyword to split the definition of class, structure, or interface at design time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
{
    private string name;

    internal string Name
    {
        get { return this.name; }
        set { this.name = value; }
    }
}

internal partial class Device
{
    public string FormattedName
    {
        get { return this.name.ToUpper(); }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is good for managing large type by splitting it into multiple smaller files. Partial type are also frequently used in code generation, so that user can append custom code to types generated by tool. At compile time, the multiple parts of a type are merged.&lt;/p&gt;
&lt;h2&gt;Interface and implementation&lt;/h2&gt;
&lt;p&gt;When a type implements an interface, this type can implement each interface member either implicitly or explicitly. The following interface has 2 member methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IInterface
{
    void Implicit();

    void Explicit();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following type implementing this interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Implementation : IInterface
{
    public void Implicit() { }

    void IInterface.Explicit() { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;strong&gt;Implementations&lt;/strong&gt; type has a public &lt;strong&gt;Implicit&lt;/strong&gt; method with the same signature as the &lt;strong&gt;IInterface&lt;/strong&gt;’s &lt;strong&gt;Implicit&lt;/strong&gt; method, so C# compiler takes **Implementations.**Implicit method as the implementation of **IInterface.**Implicit method. This syntax is called implicit interface implementation. The other method Explicit, is implemented explicitly as a interface member, not as a member method of Implementations type. The following example demonstrates how to use these interface members:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InterfaceMembers()
{
    Implementation @object = new Implementation();
    @object.Implicit(); // @object.Explicit(); cannot be compiled.

    IInterface @interface = @object;
    @interface.Implicit();
    @interface.Explicit();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An implicitly implemented interface member can be accessed from the instance of the implementation type and interface type, but an explicitly implemented interface member can only be accessed from the instance of the interface type. Here the variable name &lt;strong&gt;@object&lt;/strong&gt; and &lt;strong&gt;@interface&lt;/strong&gt; are prefixed with special character @, because &lt;strong&gt;object&lt;/strong&gt; and &lt;strong&gt;interface&lt;/strong&gt; are C# language keywords, and cannot be directly used as identifier.&lt;/p&gt;
&lt;h3&gt;IDisposable interface and using statement&lt;/h3&gt;
&lt;p&gt;At runtime, CLR/CoreCLR manage memory automatically. It allocates memory for .NET objects and release the memory with garbage collector. A .NET object can also allocate other resources unmanaged by CLR/CoreCLR, like opened files, window handles, database connections, etc. .NET provides a standard contract for these types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public interface IDisposable
    {
        void Dispose();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A type implementing the above System.IDisposable interface must have a Dispose method, which explicitly releases its unmanaged resources when called. For example, System.Data.SqlClient.SqlConnection represents a connection to a SQL database, it implements IDisposable and provides Dispose method to release the underlying database connection. The following example is the standard try-finally pattern to use IDisposable object and call Dispose method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Dispose(string connectionString)
{
    SqlConnection connection = new SqlConnection(connectionString);
    try
    {
        connection.Open();
        Trace.WriteLine(connection.ServerVersion);
        // Work with connection.
    }
    finally
    {
        if ((object)connection != null)
        {
            ((IDisposable)connection).Dispose();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Dispose method is called in finally block, so it is ensured to be called, even if exception is thrown from the operations in the try block, or if the current thread is aborted. IDisposable is widely used, so C# introduces a using statement syntactic sugar since 1.0. The above code is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Using(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        Trace.WriteLine(connection.ServerVersion);
        // Work with connection.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is more declarative at design time, and the try-finally is generated at compile time. Disposable instances should &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/yh598w02.aspx&quot;&gt;be always used with this syntax&lt;/a&gt;, to ensure its Dispose method is called in the right way.&lt;/p&gt;
&lt;h2&gt;Generic type&lt;/h2&gt;
&lt;p&gt;C# 2.0 introduces generic programming. Generic programming is a paradigm that supports type parameters, so that type information are allowed to be provided later. The following stack data structure of &lt;strong&gt;int&lt;/strong&gt; values is non generic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IInt32Stack
{
    void Push(int value);

    int Pop();
}

internal class Int32Stack : IInt32Stack
{
    private int[] values = new int[0];

    public void Push(int value)
    {
        Array.Resize(ref this.values, this.values.Length + 1);
        this.values[this.values.Length - 1] = value;
    }

    public int Pop()
    {
        if (this.values.Length == 0)
        {
            throw new InvalidOperationException(&quot;Stack empty.&quot;);
        }
        int value = this.values[this.values.Length - 1];
        Array.Resize(ref this.values, this.values.Length - 1);
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code is not very reusable. Later, if stacks are needed for values of other data types, like string, decimal, etc., then there are some options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For each new data type, make a copy of above code and modify the int type information. So &lt;strong&gt;IStringStack&lt;/strong&gt; and &lt;strong&gt;StringStack&lt;/strong&gt; can be defined for &lt;strong&gt;string&lt;/strong&gt;, &lt;strong&gt;IDecimalStack&lt;/strong&gt; and Decimal&lt;strong&gt;Stack&lt;/strong&gt; for &lt;strong&gt;decimal&lt;/strong&gt;, and so on and on. Apparently this way is not feasible.&lt;/li&gt;
&lt;li&gt;Since every type is derived from &lt;strong&gt;object&lt;/strong&gt;, a general stack for &lt;strong&gt;object&lt;/strong&gt; can be defined, which is &lt;strong&gt;IObjectStack&lt;/strong&gt; and &lt;strong&gt;ObjectStack&lt;/strong&gt;. The &lt;strong&gt;Push&lt;/strong&gt; method accepts &lt;strong&gt;object&lt;/strong&gt;, and &lt;strong&gt;Pop&lt;/strong&gt; method returns &lt;strong&gt;object&lt;/strong&gt;, so the stack can be used for values of any data type. However, this design loses the compile time type checking. Calling &lt;strong&gt;Push&lt;/strong&gt; with any argument can be compiled. Also, at runtime, whenever &lt;strong&gt;Pop&lt;/strong&gt; is called, the returned object has to be casted to the expected type, which is a performance overhead and a chance to fail.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Type parameter&lt;/h3&gt;
&lt;p&gt;With generics, a much better option is to replace the concrete type int with a type parameter T, which is declared in angle brackets following the stack type name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal interface IStack&amp;lt;T&amp;gt;
{
    void Push(T value);

    T Pop();
}

internal class Stack&amp;lt;T&amp;gt; : IStack&amp;lt;T&amp;gt;
{
    private T[] values = new T[0];

    public void Push(T value)
    {
        Array.Resize(ref this.values, this.values.Length + 1);
        this.values[this.values.Length - 1] = value;
    }

    public T Pop()
    {
        if (this.values.Length == 0)
        {
            throw new InvalidOperationException(&quot;Stack empty.&quot;);
        }
        T value = this.values[this.values.Length - 1];
        Array.Resize(ref this.values, this.values.Length - 1);
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When using this generic stack, specify a concrete type for parameter T:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Stack()
{
    Stack&amp;lt;int&amp;gt; stack1 = new Stack&amp;lt;int&amp;gt;();
    stack1.Push(int.MaxValue);
    int value1 = stack1.Pop();

    Stack&amp;lt;string&amp;gt; stack2 = new Stack&amp;lt;string&amp;gt;();
    stack2.Push(Environment.MachineName);
    string value2 = stack2.Pop();

    Stack&amp;lt;Uri&amp;gt; stack3 = new Stack&amp;lt;Uri&amp;gt;();
    stack3.Push(new Uri(&quot;https://weblogs.asp.net/dixin&quot;));
    Uri value3 = stack3.Pop();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So generics enables code reuse with type safety. &lt;strong&gt;IStack&amp;lt;T&amp;gt;&lt;/strong&gt; and &lt;strong&gt;Stack&amp;lt;T&amp;gt;&lt;/strong&gt; are strong typed, where **IStack&amp;lt;T&amp;gt;.**&lt;strong&gt;Push&lt;/strong&gt;/&lt;strong&gt;Stack&amp;lt;T&amp;gt;.Push&lt;/strong&gt; accept a value of type &lt;strong&gt;T&lt;/strong&gt;, and **IStack&amp;lt;T&amp;gt;**&lt;strong&gt;Pop&lt;/strong&gt;/&lt;strong&gt;IStack&amp;lt;T&amp;gt;.Pop&lt;/strong&gt; return a value of type &lt;strong&gt;T&lt;/strong&gt;. For example, When &lt;strong&gt;T&lt;/strong&gt; is &lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;IStack&amp;lt;int&amp;gt;&lt;/strong&gt;.&lt;strong&gt;Push&lt;/strong&gt;/&lt;strong&gt;Stack&amp;lt;int&amp;gt;.Push&lt;/strong&gt; accept an &lt;strong&gt;int&lt;/strong&gt; value; When &lt;strong&gt;T&lt;/strong&gt; is &lt;strong&gt;string&lt;/strong&gt;, &lt;strong&gt;IStack&amp;lt;string&amp;gt;.Pop&lt;/strong&gt;/&lt;strong&gt;Stack&amp;lt;int&amp;gt;.Pop&lt;/strong&gt; returns a &lt;strong&gt;string&lt;/strong&gt; value; etc. So &lt;strong&gt;IStack&amp;lt;T&amp;gt;&lt;/strong&gt; and &lt;strong&gt;Stack&amp;lt;T&amp;gt;&lt;/strong&gt; are polymorphic types, and this is called parametric polymorphism.&lt;/p&gt;
&lt;p&gt;In .NET, a generic type with type parameters are called open type (or open constructed type). If generic type’s all type parameters are specified with concrete types, then it is called closed type (or closed constructed type). Here &lt;strong&gt;Stack&amp;lt;T&amp;gt;&lt;/strong&gt; is open type, and &lt;strong&gt;Stack&amp;lt;int&amp;gt;&lt;/strong&gt;, &lt;strong&gt;Stack&amp;lt;string&amp;gt;&lt;/strong&gt;, &lt;strong&gt;Stack&amp;lt;Uri&amp;gt;&lt;/strong&gt; are closed types.&lt;/p&gt;
&lt;p&gt;The syntax for generic structure is the same as above generic class. Generic delegate and generic method will be discussed later.&lt;/p&gt;
&lt;h3&gt;Type parameter constraints&lt;/h3&gt;
&lt;p&gt;For above generic types and the following generic type, the type parameter can be arbitrary value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Constraint&amp;lt;T&amp;gt;
{
    internal void Method()
    {
        T value = null;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above code cannot be compiled, with error CS0403: Cannot convert null to type parameter &apos;T&apos; because it could be a non-nullable value type. The reason is, as fore mentioned, only values of reference types (instances of classes) can be &lt;strong&gt;null&lt;/strong&gt;, but here &lt;strong&gt;T&lt;/strong&gt; is allowed be structure type too. For this kind of scenario, C# supports constraints for type parameters, with the where keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Constraint&amp;lt;T&amp;gt; where T: class
{
    internal static void Method()
    {
        T value1 = null;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here T must be reference type, for example, &lt;strong&gt;Constraint&amp;lt;string&amp;gt;&lt;/strong&gt; is allowed by compiler, and &lt;strong&gt;Constraint&amp;lt;int&amp;gt;&lt;/strong&gt; causes a compiler error. Here are some more examples of constraints syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;
    where T1 : struct
    where T2 : class
    where T3 : DbConnection
    where T4 : IDisposable
    where T5 : struct, IComparable, IComparable&amp;lt;T5&amp;gt;
    where T6 : new()
    where T7 : T2, T3, T4, IDisposable, new() { }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above generic type has 7 type parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;T1&lt;/strong&gt; must be value type (structure)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T2&lt;/strong&gt; must be reference type (class)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T3&lt;/strong&gt; must be the specified type, or derive from the specified type&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T4&lt;/strong&gt; must be the specified interface, or implement the specified interface&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T5&lt;/strong&gt; must be value type (structure), and must implement all the specified interfaces&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T6&lt;/strong&gt; must have a public parameterless constructor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T7&lt;/strong&gt; must be or derive from or implement &lt;strong&gt;T2&lt;/strong&gt;, &lt;strong&gt;T3&lt;/strong&gt;, &lt;strong&gt;T4&lt;/strong&gt;, and must implement the specified interface, and must have a public parameterless constructor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take &lt;strong&gt;T3&lt;/strong&gt; as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;
{
    internal static void Method(T3 connection)
    {
        using (connection) // DbConnection implements IDisposable.
        {
            connection.Open(); // DbConnection has Open method.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regarding &lt;strong&gt;System.Data.Common.DbConnection&lt;/strong&gt; implements &lt;strong&gt;System.IDisposable&lt;/strong&gt;, and has a &lt;strong&gt;CreateCommand&lt;/strong&gt; method, so the above t3 object can be used with using statement, and the &lt;strong&gt;CreateCommand&lt;/strong&gt; call can be compiled too.&lt;/p&gt;
&lt;p&gt;The following is an example closed type of &lt;strong&gt;Constraints&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CloseType()
{
    Constraints&amp;lt;bool, object, DbConnection, IDbConnection, int, Exception, SqlConnection&amp;gt; closed = default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bool is value type&lt;/li&gt;
&lt;li&gt;object is reference type&lt;/li&gt;
&lt;li&gt;DbConnection is DbConnection&lt;/li&gt;
&lt;li&gt;System.Data.Common.IDbConnection implements IDisposable&lt;/li&gt;
&lt;li&gt;int is value type, implements System.IComparable, and implements System.IComparable&amp;lt;int&amp;gt; too&lt;/li&gt;
&lt;li&gt;System.Exception has a public parameterless constructor&lt;/li&gt;
&lt;li&gt;System.Data.SqlClient.SqlConnection derives from object, derives from DbConnection, implements IDbConnection, and has a public parameterless constructor&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Nullable value type&lt;/h2&gt;
&lt;p&gt;As fore mentioned, In C#/.NET, instance of type cannot be null. However, there are still some scenarios for value type to represent logical null. A typical example is database table. A value retrieved from a nullable integer column can be either integer value, or null. C# 2.0 introduces a nullable value type syntax T?, for example int? reads nullable int. T? is just a shortcut of the System.Nullable&amp;lt;T&amp;gt; generic structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public struct Nullable&amp;lt;T&amp;gt; where T : struct
    {
        private bool hasValue;

        internal T value;

        public Nullable(T value)
        {
            this.value = value;
            this.hasValue = true;
        }

        public bool HasValue
        {
            get { return this.hasValue; }
        }

        public T Value
        {
            get
            {
                if (!this.hasValue)
                {
                    throw new InvalidOperationException(&quot;Nullable object must have a value.&quot;);
                }
                return this.value;
            }
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example demonstrates how to use nullable int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Nullable()
{
    int? nullable = null;
    nullable = 1;
    if (nullable != null)
    {
        int value = (int)nullable;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, int? is the Nullable&amp;lt;int&amp;gt; structure, and cannot be real null. Above code is syntactic sugar and compiled to normal structure usage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledNullable()
{
    Nullable&amp;lt;int&amp;gt; nullable = new Nullable&amp;lt;int&amp;gt;();
    nullable = new Nullable&amp;lt;int&amp;gt;(1);
    if (nullable.HasValue)
    {
        int value = nullable.Value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When nullable is assigned with null, it is actually assigned with a instance of Nullable&amp;lt;int&amp;gt; instance. Here the structure’s default parameterless constructor is called, so a Nullable&amp;lt;int&amp;gt; instance is initialized, with each data field is initialized with its default value. So nullable’s hasValue field is false, indicating this instance logically represents null. Then nullable is reassigned with normal int value, it is actually assigned with another Nullable&amp;lt;int&amp;gt; instance, where hasValue field is set to true and value field is set to the specified int value. The non null check is compiled to HasValue property call. And the type conversion from int? to int is compiled to the Value property call.&lt;/p&gt;
&lt;h2&gt;Auto property&lt;/h2&gt;
&lt;p&gt;A property is essentially a getter with body and/or a setter with body. In many cases, a property’s setter and getter just wraps a data field, like the above Device type’s Name property. This pattern can be annoying when a type has many properties for wrapping data fields, so C# 3.0 introduces auto property syntactic sugar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Device
{
    internal decimal Price { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The backing field definition and the body of getter/setter are generated by compiler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class CompiledDevice
{
    [CompilerGenerated]
    private decimal priceBackingField;

    internal decimal Price
    {
        [CompilerGenerated]
        get { return this.priceBackingField; }

        [CompilerGenerated]
        set { this.priceBackingField = value; }
    }

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since C# 6.0, auto property can be getter only:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Category
{
    internal Category(string name)
    {
        this.Name = name;
    }

    internal string Name { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above Name property is compiled to have getter only, and the backing field becomes read only:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class CompiledCategory
{
    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly string nameBackingField;

    internal CompiledCategory(string name)
    {
        this.nameBackingField = name;
    }

    internal string Name
    {
        [CompilerGenerated]
        get { return this.nameBackingField; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Property initializer&lt;/h2&gt;
&lt;p&gt;C# 6.0 introduces property initializer syntactic sugar, so that property’s initial value can be provided inline:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Category
{
    internal Guid Id { get; } = Guid.NewGuid();

    internal string Description { get; set; } = string.Empty;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The property initializer is compiled to backing field initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class CompiledCategory
{
    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly Guid idBackingField = Guid.NewGuid();

    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string descriptionBackingField = string.Empty;

    internal Guid Id
    {
        [CompilerGenerated]
        get { return this.idBackingField; }
    }

    internal string Description
    {
        [CompilerGenerated]
        get { return this.descriptionBackingField; }

        [CompilerGenerated]
        set { this.descriptionBackingField = value; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Object initializer&lt;/h2&gt;
&lt;p&gt;A Device instance can be initialized with a sequence of imperative property assignment statements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SetProperties()
{
    Device device = new Device();
    device.Name = &quot;Surface Book&quot;;
    device.Price = 1349M;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 3.0 introduces object initializer syntactic sugar, above call constructor and set properties code can be merged in a declarative style:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ObjectInitializer()
{
    Device device = new Device() { Name = &quot;Surface Book&quot;, Price = 1349M };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The object initializer syntax in the second example is compiled to a sequence of assignments in the first example.&lt;/p&gt;
&lt;h2&gt;Collection initializer&lt;/h2&gt;
&lt;p&gt;Similarly, C# 3.0 also introduces collection initializer syntactic sugar for type that implements System.Collections.IEnumerable interface and has a parameterized Add method. Take the following device collection as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class DeviceCollection : IEnumerable
{
    private Device[] devices = new Device[0];

    internal void Add(Device device)
    {
        Array.Resize(ref this.devices, this.devices.Length + 1);
        this.devices[this.devices.Length - 1] = device;
    }

    public IEnumerator GetEnumerator() // From IEnumerable.
    {
        return this.devices.GetEnumerator();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be initialized declaratively too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CollectionInitializer(Device device1, Device device2)
{
    DeviceCollection devices = new DeviceCollection() { device1, device2 };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code is compiled to a normal constructor call followed by a sequence of Add method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledCollectionInitializer(Device device1, Device device2)
{
    DeviceCollection devices = new DeviceCollection();
    devices.Add(device1);
    devices.Add(device2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Index initializer&lt;/h2&gt;
&lt;p&gt;C# 6.0 introduces index initializer for type with indexer setter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class DeviceDictionary
{
    internal Device this[int id] { set { } }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is another declarative syntactic sugar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void IndexInitializer(Device device1, Device device2)
{
    DeviceDictionary devices = new DeviceDictionary { [10] = device1, [11] = device2 };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above syntax is compiled to normal constructor call followed by a sequence of indexer calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledIndexInitializer(Device device1, Device device2)
{
    DeviceDictionary devices = new DeviceDictionary();
    devices[0] = device1;
    devices[1] = device2;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Null coalescing operator&lt;/h2&gt;
&lt;p&gt;C# 2.0 introduces a null coalescing operator ??. It works with 2 operand as left ?? right. If the left operand is not null, it returns the left operand, otherwise, it returns the right operand. For example, when working with reference or nullable value, it is very common to have null check at runtime, and have null replaced:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Point
{
    internal static Point Default { get; } = new Point(0, 0);
}

internal partial struct ValuePoint
{
    internal static ValuePoint Default { get; } = new ValuePoint(0, 0);
}

internal static void DefaultValueForNull(Point reference, ValuePoint? nullableValue)
{
    Point point = reference != null ? reference : Point.Default;

    ValuePoint valuePoint = nullableValue != null ? (ValuePoint)nullableValue : ValuePoint.Default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be simplified with the null coalescing operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultValueForNullWithNullCoalescing(Point reference, ValuePoint? nullableValue)
{
    Point point = reference ?? Point.Default;
    ValuePoint valuePoint = nullableValue ?? ValuePoint.Default;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Null conditional operators&lt;/h2&gt;
&lt;p&gt;It is also very common to check null before member or indexer access:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NullCheck(Category category, Device[] devices)
{
    string categoryText = null;
    if (category != null)
    {
        categoryText = category.ToString();
    }
    string firstDeviceName;
    if (devices != null)
    {
        Device firstDevice = devices[0];
        if (first != null)
        {
            firstDeviceName = firstDevice.Name;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 6.0 introduces null conditional operators (also called null propagation operators), ?. for member access and ?[] for indexer access, to simplify this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NullCheckWithNullConditional(Category category, Device[] devices)
{
    string categoryText = category?.ToString();
    string firstDeviceName = devices?[0]?.Name;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;throw expression&lt;/h2&gt;
&lt;p&gt;Since C# 7.0, throw statement can be used as expression. The throw expression is frequently used with the conditional operator and above null coalescing operator to simplify argument check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Subcategory
{
    internal Subcategory(string name, Category category)
    {
        this.Name = !string.IsNullOrWhiteSpace(name) ? name : throw new ArgumentNullException(&quot;name&quot;);
        this.Category = category ?? throw new ArgumentNullException(&quot;category&quot;);
    }

    internal Category Category { get; }

    internal string Name { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Exception filter&lt;/h2&gt;
&lt;p&gt;In C#, it used to be common to catch an exception, filter, and then handle/rethrow. The following example tries to download HTML string from the specified URI, and it can handle the download failure if there is response status of bad request. So it catches the exception to check. If the exception has expected info, it handles the exception; otherwise, it rethrows the exception.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CatchFilterRethrow(WebClient webClient)
{
    try
    {
        string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
    }
    catch (WebException exception)
    {
        if ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
        {
            // Handle exception.
        }
        else
        {
            throw;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 6.0 introduces exception filter at the language level. the catch block can have a expression to filter the specified exception before catching. If the expression returns true, the catch block is executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExceptionFilter(WebClient webClient)
{
    try
    {
        string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
    }
    catch (WebException exception) when ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
    {
        // Handle exception.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exception filter is not a syntactic sugar, but a CLR feature. The above exception filter expression is compiled to filter clause in CIL. The following cleaned CIL virtually demonstrates the compilation result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.method assembly hidebysig static void ExceptionFilter(class [System]System.Net.WebClient webClient) cil managed
{
  .try
  {
    // string html = webClient.DownloadString(&quot;http://weblogs.asp.net/dixin&quot;);
  }
  filter
  {
    // when ((exception.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.BadRequest)
  }
  {
    // Handle exception.
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the filter expression returns false, the catch clause is never executed, so there is no need to rethrow exception. Rethrowing exception causes stack unwinding, as if the exception is from the throw statement, and the original call stack and other info is lost. So this feature is very helpful for diagnostics and debugging.&lt;/p&gt;
&lt;h2&gt;String interpolation&lt;/h2&gt;
&lt;p&gt;For many years, string &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/txafckwd.aspx&quot;&gt;composite formatting&lt;/a&gt; is widely used in C#. It inserts values to indexed placeholders in string format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Log(Device device)
{
    string message = string.Format(&quot;{0}: {1}, {2}&quot;, DateTime.Now.ToString(&quot;o&quot;), device.Name, device.Price);
    Trace.WriteLine(message);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 6.0 introduces string interpolation syntactic sugar to declare the values in place, without maintaining the orders separately:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LogWithStringInterpolation(Device device)
{
    string message = string.Format($&quot;{DateTime.Now.ToString(&quot;o&quot;)}: {device.Name}, {device.Price}&quot;);
    Trace.WriteLine(message);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second interpolation version is more declarative and productive, without maintaining a series of indexes. This syntax is actually compiled to the first composite formatting.&lt;/p&gt;
&lt;h2&gt;nameof operator&lt;/h2&gt;
&lt;p&gt;C# 6.0 introduces a nameof operator to obtain the string name of variable, type, or member. Take argument check as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ArgumentCheck(int count)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(&quot;count&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parameter name is a hard coded string, and cannot be checked by compiler. Now with nameof operator, the compiler can generated the above parameter name string constant:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NameOf(int count)
{
    if (count &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(nameof(count));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Digit separator and leading underscore&lt;/h2&gt;
&lt;p&gt;C# 7.0 introduces underscore as the digit separator, as well as the 0b prefix for binary number. C# 7.1 supports an optional underscore at the beginning of the number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DigitSeparator()
{
    int value1 = 10_000_000;
    double value2 = 0.123_456_789;

    int value3 = 0b0001_0000; // Binary.
    int value4 = 0b_0000_1000; // Binary.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These small features greatly improve the readability of long numbers and binary numbers at design time.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This chapter walk through fundamental and important knowledge of C#, like reference type, value type, generic type, nullable value type, and some basic syntax of initializers, operators, expressions, etc., including some new syntax introduced in recent releases of C#. After getting familiar with these basics, the readers should be ready to dive into other advanced topics of C# language, functional programming and LINQ.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (3) Programming Paradigms and Functional Programming</title><link>https://dixin.github.io/posts/introducing-linq-3-waht-is-functional-programming/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-3-waht-is-functional-programming/</guid><description>Programming paradigm is the fundamental style of programming. There are , for example:</description><pubDate>Wed, 30 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;Latest version: &lt;a href=&quot;/posts/introducing-linq-3-what-is-functional-programming&quot;&gt;https://weblogs.asp.net/dixin/introducing-linq-3-what-is-functional-programming&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Programming paradigm is the fundamental style of programming. There are &lt;a href=&quot;https://en.wikipedia.org/wiki/Programming_paradigm&quot;&gt;many paradigms for programming&lt;/a&gt;, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Declarative_programming&quot;&gt;Declarative programming:&lt;/a&gt; designs what is the logic of operations, without describing its control flow (SQL, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Functional_programming&quot;&gt;Functional programming&lt;/a&gt;: uses expressions to describe operations, which are treated as call of functions (Lisp, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Purely_functional_programming&quot;&gt;Purely functional programming&lt;/a&gt;: does not rely on mutable state (Haskell, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Logic_programming&quot;&gt;Logic programming&lt;/a&gt;: designs the program with facts and rules in logical form (Prolog, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_programming_language&quot;&gt;Dynamic programming&lt;/a&gt;: executes compile time behaviors at runtime (PHP, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Event-driven_programming&quot;&gt;Event-driven programming&lt;/a&gt;: drives the operations with events (JavaScript, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Generic_programming&quot;&gt;Generic programming&lt;/a&gt;: supports type parameters for data structures and operations (Swift, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Imperative_programming&quot;&gt;Imperative programming:&lt;/a&gt; uses commands/statements to specify how the program operates (Assembly language, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;Object-oriented programming:&lt;/a&gt; designs the program in objects, containing data in the form of fields, and behaviors in the forms of methods&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Class-based_programming&quot;&gt;Class-based programming&lt;/a&gt;: defines the data structure and behaviors as classes, and implements inheritance for classes (C++, etc.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Prototype-based_programming&quot;&gt;Prototype-based programming&lt;/a&gt;: implements classless prototypal inheritance and behavior reuse (Self, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Procedural_programming&quot;&gt;Procedural programming&lt;/a&gt;: designs program in procedures and sub-procedures (C, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Metaprogramming&quot;&gt;Metaprogramming&lt;/a&gt;: accesses program code as data (Ruby, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Reflection_(computer_programming)&quot;&gt;Reflective programming&lt;/a&gt;: accesses the structure and behavior of the program itself at runtime (Ruby, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;One programming language can adopt multiple paradigms. For example: C# supports many paradigms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;declarative programming: attributes, data annotations, code contracts, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;functional programming: first class functions, lambda expressions, LINQ query expressions, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dynamic programming: the dynamic type&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;event-driven programming: events, event handlers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;generic programming: generics&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;imperative programming: statements, control flows.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;object-oriented and class-based programming: classes, encapsulation, inheritance, polymorphism, etc.&lt;/li&gt;
&lt;li&gt;procedural programming: static class, static method, using static, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;metaprogramming: code DOM, expression tree, CIL emit, compiler as a service, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reflective programming: reflection&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C# is such a powerful, flexible and productive language for general purpose, and all these C# language features live in in harmony. This tutorial discusses functional programming of C#, but other features, like generics, objects, attributes, expression trees, etc., is used a lot in functional C# code.&lt;/p&gt;
&lt;h2&gt;Imperative programming vs. declarative programming&lt;/h2&gt;
&lt;p&gt;Functional programming is declarative, and describes what to do; Object-oriented programming is imperative, and specifies how to do. To compare these 2 paradigms. The following examples query the delegate types in the .NET core library (mscorlib.dll of .NET Framework, System.Private.CoreLib.dll of .NET Core). The task is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;filter the types to get delegate types&lt;/li&gt;
&lt;li&gt;group the delegate types by their namespaces&lt;/li&gt;
&lt;li&gt;sort the groups by each group’s delegate type count in descending order, and if groups have identical delegate type count, then sort them by their namespaces&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following query is implemented this with traditional C# object-oriented programming. It is imperative. The code is a sequence of statements and commands, specifying how to execute the query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DelegateTypes()
{
    Assembly coreLibrary = typeof(object).Assembly;
    Dictionary&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; delegateTypes = new Dictionary&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;();
    foreach (Type type in coreLibrary.GetExportedTypes())
    {
        if (type.BaseType == typeof(MulticastDelegate))
        {
            if (!delegateTypes.TryGetValue(type.Namespace, out List&amp;lt;Type&amp;gt; namespaceTypes))
            {
                namespaceTypes = delegateTypes[type.Namespace] = new List&amp;lt;Type&amp;gt;();
            }
            namespaceTypes.Add(type);
        }
    }
    List&amp;lt;KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;&amp;gt; delegateTypesList =
        new List&amp;lt;KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt;&amp;gt;(delegateTypes);
    for (int index = 0; index &amp;lt; delegateTypesList.Count - 1; index++)
    {
        int currentIndex = index;
        KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; after = delegateTypesList[index + 1];
        while (currentIndex &amp;gt;= 0)
        {
            KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; before = delegateTypesList[currentIndex];
            int compare = before.Value.Count.CompareTo(after.Value.Count);
            if (compare == 0)
            {
                compare = string.Compare(after.Key, before.Key, StringComparison.Ordinal);
            }
            if (compare &amp;gt;= 0)
            {
                break;
            }
            delegateTypesList[currentIndex + 1] = delegateTypesList[currentIndex];
            currentIndex--;
        }
        delegateTypesList[currentIndex + 1] = after;
    }
    foreach (KeyValuePair&amp;lt;string, List&amp;lt;Type&amp;gt;&amp;gt; namespaceTypes in delegateTypesList) // Output.
    {
        Trace.Write(namespaceTypes.Value.Count + &quot; &quot; + namespaceTypes.Key + &quot;:&quot;);
        foreach (Type delegateType in namespaceTypes.Value)
        {
            Trace.Write(&quot; &quot; + delegateType.Name);
        }
        Trace.WriteLine(null);
    }
    // 30 System: Action`1 Action Action`2 Action`3 Action`4 Func`1 Func`2 Func`3 Func`4 Func`5 Action`5 Action`6 Action`7 Action`8 Func`6 Func`7 Func`8 Func`9 Comparison`1 Converter`2 Predicate`1 ResolveEventHandler AssemblyLoadEventHandler AppDomainInitializer CrossAppDomainDelegate AsyncCallback ConsoleCancelEventHandler EventHandler EventHandler`1 UnhandledExceptionEventHandler
    // 8 System.Threading: SendOrPostCallback ContextCallback ParameterizedThreadStart WaitCallback WaitOrTimerCallback IOCompletionCallback ThreadStart TimerCallback
    // 3 System.Reflection: ModuleResolveEventHandler MemberFilter TypeFilter
    // 3 System.Runtime.CompilerServices: TryCode CleanupCode CreateValueCallback
    // 2 System.Runtime.Remoting.Messaging: MessageSurrogateFilter HeaderHandler
    // 1 System.Runtime.InteropServices: ObjectCreationDelegate
    // 1 System.Runtime.Remoting.Contexts: CrossContextDelegate
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example is functional LINQ implementation, it is declarative. The code describes the logic, without specifying the execution details:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Linq
{
    internal static void DelegateTypesQueryExpression()
    {
        Assembly coreLibrary = typeof(object).Assembly;
        IEnumerable&amp;lt;IGrouping&amp;lt;string, Type&amp;gt;&amp;gt; delegateTypes =
            from type in coreLibrary.GetExportedTypes()
            where type.BaseType == typeof(MulticastDelegate)
            group type by type.Namespace into namespaceTypes
            orderby namespaceTypes.Count() descending, namespaceTypes.Key
            select namespaceTypes;
        foreach (IGrouping&amp;lt;string, Type&amp;gt; namespaceTypes in delegateTypes) // Output.
        {
            Trace.Write(namespaceTypes.Count() + &quot; &quot; + namespaceTypes.Key + &quot;:&quot;);
            foreach (Type delegateType in namespaceTypes)
            {
                Trace.Write(&quot; &quot; + delegateType.Name);
            }
            Trace.WriteLine(null);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following is the identical query in query method syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Linq
{
    internal static void DelegateTypesQueryMethods()
    {
        Assembly coreLibrary = typeof(object).Assembly;
        IEnumerable&amp;lt;IGrouping&amp;lt;string, Type&amp;gt;&amp;gt; delegateTypes = coreLibrary.GetExportedTypes()
            .Where(type =&amp;gt; type.BaseType == typeof(MulticastDelegate))
            .GroupBy(type =&amp;gt; type.Namespace)
            .OrderByDescending(namespaceTypes =&amp;gt; namespaceTypes.Count())
            .ThenBy(namespaceTypes =&amp;gt; namespaceTypes.Key);
        foreach (IGrouping&amp;lt;string, Type&amp;gt; namespaceTypes in delegateTypes) // Output.
        {
            Trace.Write(namespaceTypes.Count() + &quot; &quot; + namespaceTypes.Key + &quot;:&quot;);
            foreach (Type delegateType in namespaceTypes)
            {
                Trace.Write(&quot; &quot; + delegateType.Name);
            }
            Trace.WriteLine(null);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So imperative programming and declarative programming are quite different paradigms and approaches. Imperative programming has a history to think from lower level up. The computer hardware’s implementation usually is imperative and stateful, so machine code is designed to be imperative and change hardware states during the execution. Then low level programming languages are designed, which usually have strong correspondence to the machine code with a little or no abstractions, so they are also imperative and stateful, like assembly language. Later, higher level programming languages are designed as abstraction of low level languages, which is usually more portable, but still imperative and stateful. For example, C is the abstractions of assembly languages, C++ was initially called C with Classes and designed as extension of C. When Microsoft designed modern languages, C# is rooted in C family of languages to make immediately familiar to programmers of C, C++, and Java, etc., so C# can be imperative and stateful too - Actually C# was initially called COOL (C-like Object Oriented Language). In above imperative example, all execution details of logic have to be specified.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how to filter: scan the types, if a type is not a delegate type, ignore it.&lt;/li&gt;
&lt;li&gt;how to group: use a dictionary to store the groups, where each dictionary key is namespace, and each dictionary value is a list of delegate types under a namespace; for each delegate type, if the dictionary does not have the delegate type’s namespace as a key yet, add a key-value pair to the dictionary, where key is the namespace, and value is an empty list of types; now the current namespace must have a corresponding type list, so add the delegate type to the type list.&lt;/li&gt;
&lt;li&gt;and how to sort: copy the groups (key-value pairs of dictionary) to a list, so that the groups have an order. then scan the list of groups to apply insertion sort; when comparing 2 groups, first comparing their delegate type counts, if they have the same count, then compare their namespaces; after growing the sorted sub list of groups, eventually all groups are sorted in place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above sequence of statements and commands is a control flow, where the business logic is less intuitive.&lt;/p&gt;
&lt;p&gt;In contrast, declarative programming is to think from higher level. It is usually abstractions of the mathematics and logic, disregarding how exactly the operations should be executed. This usually includes avoiding specifying how to change state and how to mutate data. In above LINQ examples, the query simply declares:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what is the filter logic: keep delegate types&lt;/li&gt;
&lt;li&gt;what is the group logic: group delegate types by namespaces&lt;/li&gt;
&lt;li&gt;what is the sorting logic: sort the delegate type groups in descending order of delegate type counts, then in ascending order of namespaces&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above is an data flow, where the business logic is more intuitive.&lt;/p&gt;
&lt;p&gt;The previous part demonstrated the traditional XML data and SQL database queries in imperative, object-oriented paradigm. They specify how exactly to access the specific data sources, like opening SQL database connection, etc., pass the query logic to data source with domain specific SQL and XPath languages, etc. In contrast, the LINQ to XML and LINQ to Entities queries are functional and declarative, they describe the query logic without specifying execution details.&lt;/p&gt;
&lt;p&gt;Regarding computer hardware is usually imperative, declarative code eventually needs to translated to imperative code to execute in hardware. This process is usually done by compilers at compile time, and also API calls at runtime, so that at design time, the code can be declarative and functional. Later, this tutorial will discuss how functional and declarative LINQ is implemented by C# compiler and the LINQ query APIs’ internals.&lt;/p&gt;
&lt;p&gt;Besides LINQ and functional programming, C#/.NET also provide other declarative features and APIs. For example, attribute is a powerful feature to associate declarative information with code, including assemblies, modules, types, type members:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestClass]
public class QueryMethodsTests
{
    [TestMethod]
    public void FilteringTest()
    {
        // Unit test.
    }

    [TestMethod]
    public void GroupingTest()
    {
        // Unit test.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Attributes are widely used in C#/.NET programming. For example, data annotation is a technology to use attributes to modeling, display, and validate data entities. The following type uses attributes to declare validation rules for its properties, and the error messages when the validation fails:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Contact
{
    [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.NameRequired))]
    [StringLength(maximumLength: 50, MinimumLength = 1, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.NameInvalid))]
    public string Name { get; set; }

    [EmailAddress(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.EmailInvalid))]
    public string Email { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Code contracts is also a declarative technology to describes the behavior of code. The following example describes type members’ precondition, postcondition, and purity, which is intuitive and readable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Product
{
    private readonly string name;

    private readonly decimal price;

    public Product(string name, decimal price)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(!string.IsNullOrWhiteSpace(name));
        Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(price &amp;gt;= 0);

        this.name = name;
        this.price = price;
    }

    public string Name
    {
        [Pure]
        get
        {
            Contract.Ensures(!string.IsNullOrWhiteSpace(Contract.Result&amp;lt;string&amp;gt;()));

            return this.name;
        }
    }

    public decimal Price
    {
        [Pure]
        get
        {
            Contract.Ensures(Contract.Result&amp;lt;int&amp;gt;() &amp;gt;= 0);

            return this.price;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Object-oriented programming vs. functional programming&lt;/h2&gt;
&lt;p&gt;Object-oriented programming has first class objects., while in functional programming treats functions are first class citizen. To demonstrate the difference, the following example builds a document in object-oriented paradigm. It downloads HTML content from the specified URI, converts it to a word document file, and upload to OneDrive to share:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class WebClient
{
    internal FileInfo Download(Uri uri)
    {
        return default;
    }
}

internal class DocumentConverter
{
    internal DocumentConverter(FileInfo template)
    {
        this.Template = template;
    }

    internal FileInfo Template { get; private set; }

    internal FileInfo ToWord(FileInfo htmlDocument)
    {
        return default;
    }
}

internal class OneDriveClient
{
    internal void Upload(FileInfo file) { }
}

internal class DocumentBuilder
{
    private readonly WebClient webClient;

    private readonly DocumentConverter documentConverter;

    private readonly OneDriveClient oneDriveClient;

    internal DocumentBuilder(
        WebClient webClient, DocumentConverter documentConverter, OneDriveClient oneDriveClient)
    {
        this.webClient = webClient;
        this.documentConverter = documentConverter;
        this.oneDriveClient = oneDriveClient;
    }

    internal void Build(Uri uri)
    {
        FileInfo htmlDocument = this.webClient.Download(uri);
        FileInfo wordDocument = this.documentConverter.ToWord(htmlDocument);
        this.oneDriveClient.Upload(wordDocument);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above WebClient class provides the operation to download HTML content to a document. DocumentConverter class provides the operation to convert HTML document to Word document, with a specified template. And OneDriveClient class provides the operation to upload file to OneDrive. To focus on the paradigm, the implementations are omitted (If interested, the complete web content to Word document building implementation can be found &lt;a href=&quot;/posts/convert-html-to-well-formatted-microsoft-word-document&quot;&gt;here&lt;/a&gt;). To build the document, DocumentBuilder class is defined to compose everything together. The following code demonstrates how these objects works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Imperative
{
    internal static void BuildDocument(Uri uri, FileInfo template)
    {
        DocumentBuilder builder = new DocumentBuilder(
            new WebClient(), new DocumentConverter(template), new OneDriveClient());
        builder.Build(uri);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In functional paradigm, each operation can be simply represented by a functions, and functions can be composed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functional
{
    internal static FileInfo DownloadHtml(Uri uri)
    {
        return default;
    }

    internal static FileInfo ConvertToWord(FileInfo htmlDocument, FileInfo template)
    {
        return default;
    }

    internal static void UploadToOneDrive(FileInfo file) { }

    internal static Action&amp;lt;Uri, FileInfo&amp;gt; CreateDocumentBuilder(
        Func&amp;lt;Uri, FileInfo&amp;gt; download, Func&amp;lt;FileInfo, FileInfo, FileInfo&amp;gt; convert, Action&amp;lt;FileInfo&amp;gt; upload)
    {
        return (uri, wordTemplate) =&amp;gt;
        {
            FileInfo htmlDocument = download(uri);
            FileInfo wordDocument = convert(htmlDocument, wordTemplate);
            upload(wordDocument);
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how these functions work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Functional
{
    internal static void BuildDocument(Uri uri, FileInfo template)
    {
        Action&amp;lt;Uri, FileInfo&amp;gt; buildDocument = CreateDocumentBuilder(
            DownloadHtml, ConvertToWord, UploadToOneDrive);
        buildDocument(uri, template);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here CreateDocumentBuilder function is called with DownloadHtml, ConvertToWord, and UploadToOneDrive functions as arguments, and its return value is a buildDocument function. These function variables work just like object variables. For example, buildDocument is of type Action&amp;lt;Uri, FileInfo&amp;gt;, which means accepting a Uri parameter, and returning void. This demonstrates in C# functions are first class citizens just like objects. Internally, CreateDocumentBuilder function composes the input functions and return a new function.&lt;/p&gt;
&lt;p&gt;The above LINQ query example is also an example of function composition. The entire query is composed by Where, GroupBy, OrderBy, and ThenBy.&lt;/p&gt;
&lt;p&gt;In object oriented programming, objects can have behaviors in the form of methods, comparing to functions in functional programming, they are both modularized, reusable code block, they can both be called, and they can both have parameters and return values. The main difference is, functional programming is a subtype of declarative programming. Besides declarative, functional programming encourages modeling operations as pure functions. A pure function can be viewed as a mathematical relation between a set of inputs and a set of outputs, and each certain input is related to a certain output. In another word, a pure function’s output only depends on the input. It is also self contained and does not produce side effects, like data mutation, state changes, data mutation, I/O, etc.&lt;/p&gt;
&lt;p&gt;In the above object-oriented example of delegate type query introduces a lot of variable mutations, also the dictionary object changes its state for grouping, and the list object changes its state for sorting. In contrast, the LINQ query examples do not involve mutation and state changes at all, and all the involved functions are pure functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where’s argument type =&amp;gt; type.BaseType == typeof(MulticastDelegate) is a pure function, which accepts Type instance as input (left side of the =&amp;gt; operator), and relates to a new bool value as output (right side of the =&amp;gt; operator). It predicts whether the input type represents a delegate type. This syntax is called lambda expression, which will be discussed in details later. The output bool value only depends on the input type. And this function does not change states. When it is called with the the same Type object for multiple times, it produces the same bool value.&lt;/li&gt;
&lt;li&gt;GroupBy’s argument type =&amp;gt; type.Namespace is a pure function too, which accepts Type instance as input, and relates to namespace string value as output, which is used as the grouping key. Again, the output namespace string value only depends on the input type. And this function does not change states. When it is called with the same Type object for multiple times, it produces the sane namespace string.&lt;/li&gt;
&lt;li&gt;OrderByDescending’s argument namespaceTypes =&amp;gt; namespaceTypes.Count() is also a pure function, which accepts a group of Type instances as input, and relates to that group’s object count integer value as output, which is used as the sorting key. Again, the output object count integer value only depends on the input group. And this function does not change states. When it function is called with the same group for multiple times, it produces the sane count integer.&lt;/li&gt;
&lt;li&gt;Similarly, ThenBy’s parameter namespaceTypes =&amp;gt; namespaceTypes.Key is still a pure function.&lt;/li&gt;
&lt;li&gt;Where, GroupBy, OrderByDescending, ThenBy are called LINQ query methods, and they are also pure functions. When they are called, they do not actually execute the filtering, grouping, and sorting logic. They have a source sequence and a function as input, and relate to a new generator object as output, which wraps the input source sequence and input function. They do not change state either. If each of these query methods is called with the same source sequence and function, it produces the same generator. This will be discussed later in detail.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So function programming paradigm treats functions as first class citizen, encourages and self-contained functions focusing on input and output, and also encourages purity and avoids mutation and state changes. Functional programming is declarative and expressive, so it can be easy to read, maintain, parallelize, and test, etc.&lt;/p&gt;
&lt;p&gt;Many C# functional programming features, like lambda expression, local function, pattern matching, etc., are introduced to C# since 3.0 and later, but the functional paradigm and concepts has a long history.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lambda expression and functional programming came from lambda calculus, which was invented in 1930s.&lt;/li&gt;
&lt;li&gt;The first functional programming language, Lisp, was designed in 1950s. Lisp is also the second oldest high level programming language still widely used today. It is only 1 year younger than Fortran, an imperative programming language.&lt;/li&gt;
&lt;li&gt;LINQ query expression is rooted in monad, a concept of category theory. Category theory was started in 1940s, and monad was introduced into category theory in 1950s. Then monad programming appeared in Opal language in 1980s. In 1990s it was already heavily used in Haskell language.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides covering C# language’s functional features and functional LINQ queries, this tutorial also discusses lambda calculus and category theory. By demystifying the rationale and foundations , these knowledge can build a in depth understanding of functional programming, also greatly help understanding other functional programming languages.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (2) LINQ Overview</title><link>https://dixin.github.io/posts/introducing-linq-2-what-is-linq-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-2-what-is-linq-7/</guid><description>As fore mentioned, LINQ consists of syntax in languages and APIs in libraries:</description><pubDate>Tue, 29 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version:&lt;/strong&gt; https://weblogs.asp.net/dixin/introducing-linq-2-what-is-linq&lt;/h2&gt;
&lt;p&gt;As fore mentioned, LINQ consists of syntax in languages and APIs in libraries:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For a certain language, like C#, there is only 1 set of LINQ query syntax, which works with many LINQ API sets, and each API set works with a specific data domain. Here are examples of these API sets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In .NET Standard, Microsoft provides:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to Objects: a set of LINQ APIs for .NET objects in memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parallel LINQ: another set of LINQ APIs also for .NET objects in memory, but in parallel&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to XML: a set of LINQ APIs for XML data objects in memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft also provides other libraries based on .NET Standard:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to Entities: a set of LINQ APIs in Entity Framework (EF) and Entity Framework Core (EF Core) NuGet packages for relational databases, including Microsoft SQL Server, Microsoft Azure SQL Database (aka SQL Azure), as well as SQLite, Oracle, MySQL, PostgreSQL, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to NoSQL: a set of LINQ APIs for Azure CosmosDB, the Microsoft NoSQL database service&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In .NET Framework for Windows, Microsoft provides:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to DataSets: a set of LINQ APIs for data cached in data sets&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to SQL: a set of LINQ APIs for relational data in Microsoft SQL Server&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are also also third party LINQ libraries/APIs:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to JSON, s set of LINQ APIs for JSON data in memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to Twitter, a set of LINQ APIs for Twitter data in Twitter’s services&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;849&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ APIs&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;.NET Framework: Nuget package or .dll assembly&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;.NET Standard: Nuget package&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;Namespace&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to Objects&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Core.dll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;NETStandard.Library&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to Objects Interactive Extension (Ix)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Interactive&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;System.Interactive&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;Parallel LINQ&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Core.dll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;NETStandard.Library&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to XML&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Xml.Linq.dll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;NETStandard.Library&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Xml.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to Entities&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;EntityFramework, Microsoft.EntityFrameworkCore&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;Microsoft.EntityFrameworkCore&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Data.Entity (EF), Microsoft.EntityFrameworkCore (EF Core)&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to NoSQL&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;Microsoft.Azure.DocumentDB&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;Microsoft.Azure.DocumentDB.Core&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;Microsoft.Azure.Documents.Client&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to SQL&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Data.Linq.dll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;Not available&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Data.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to DataSets&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;System.Data.DataSetExtensions.dll&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;Not available&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;System.Data&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to JSON&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;Newtonsoft.Json&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;Newtonsoft.Json&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;Newtonsoft.Json.Linq&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;131&quot;&amp;gt;LINQ to Twitter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;222&quot;&amp;gt;linqtotwitter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;223&quot;&amp;gt;linqtotwitter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;271&quot;&amp;gt;LinqToTwitter&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;One language for different data domains&lt;/h2&gt;
&lt;p&gt;C# developer can use a single LINQ language syntax to work with different data. At compile time, the LINQ syntax can be compiled to different API calls according to different contexts. At runtime, these specific API calls work with specific data domains.&lt;/p&gt;
&lt;h3&gt;LINQ to Objects&lt;/h3&gt;
&lt;p&gt;When using any LINQ technology to work with data, there are usually 3 steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get the data source for LINQ query&lt;/li&gt;
&lt;li&gt;Define the LINQ query&lt;/li&gt;
&lt;li&gt;Execute the LINQ query&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;LINQ to Objects queries .NET objects in memory. The following example queries positive integers from the integer array in memory, and get the integers’ square roots in ascending order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Linq
{
    internal static void LinqToObjectsQueryExpression()
    {
        IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
        IEnumerable&amp;lt;double&amp;gt; query =
            from int32 in source
            where int32 &amp;gt; 0
            orderby int32
            select Math.Sqrt(int32); // Define query.
        foreach (double result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the data source is a sequence of integers in memory. The query is created declaratively in native C# language keywords (where, orderby, select, etc.), which is called query expression:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The from clause specifies data source&lt;/li&gt;
&lt;li&gt;The where clause filters the data source and keeps the integers greater than 0,&lt;/li&gt;
&lt;li&gt;The orderby clause sort the filtered integers in ascending order&lt;/li&gt;
&lt;li&gt;The select clause maps the sorted integers to their square roots.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Creating the query is only building the filter-sort-map query flow without executing it. Later, when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;p&gt;Besides above query expression syntax. There is another query method call syntax to create LINQ query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToObjectsQueryMethods()
{
    IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
    IEnumerable&amp;lt;double&amp;gt; query = source
        .Where(int32 =&amp;gt; int32 &amp;gt; 0)
        .OrderBy(int32 =&amp;gt; int32)
        .Select(int32 =&amp;gt; Math.Sqrt(int32)); // Define query.
    foreach (double result in query) // Execute query.
    {
        Trace.WriteLine(result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, the query is built by calling &lt;strong&gt;Where&lt;/strong&gt;, &lt;strong&gt;OrderBy&lt;/strong&gt;, &lt;strong&gt;Select&lt;/strong&gt; methods. These 2 versions of query are identical. The query expression is compiled to query method calls, which will be discussed in detail in the Functional Programming and LINQ to Objects chapters.&lt;/p&gt;
&lt;h3&gt;Parallel LINQ&lt;/h3&gt;
&lt;p&gt;The above LINQ to Object queries execute sequentially. The filter-sort-map computation are executed for all integers with a single thread, and the query results are produced one by one in a deterministic order. Parallel LINQ (to Objects) is the parallel version of the LINQ to Objects APIs. It also work with objects in memory, but can execute the query in parallel with multiple threads, in order to utilize all processor cores and improve the LINQ query performance. The following are the parallel version of the above queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ParallelLinq()
{
    int[] values = { 4, 3, 2, 1, 0, -1 };
    ParallelQuery&amp;lt;int&amp;gt; source = values.AsParallel(); // Get source.
    ParallelQuery&amp;lt;double&amp;gt; query =
        from int32 in source
        where int32 &amp;gt; 0
        orderby int32
        select Math.Sqrt(int32); // Define query.
    // Equivalent to:
    // ParallelQuery&amp;lt;double&amp;gt; query = source
    //    .Where(int32 =&amp;gt; int32 &amp;gt; 0)
    //    .OrderBy(int32 =&amp;gt; int32)
    //    .Select(int32 =&amp;gt; Math.Sqrt(int32));
    query.ForAll(result =&amp;gt; Trace.WriteLine(result)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query creation syntax is exactly the same as sequential LINQ to Objects. The query execution syntax is different. In the previous LINQ to Objects query execution, a foreach loop is used to pull the results one by one sequentially. Here Parallel LINQ provides a special ForAll method to execute the pulling in parallel. Since the results are computed in parallel, the query results can be produced in nondeterministic order.&lt;/p&gt;
&lt;h3&gt;LINQ to XML&lt;/h3&gt;
&lt;p&gt;LINQ to XML queries XML data. Take an ASP.NET blog RSS feed &lt;a href=&quot;/posts/rss&quot;&gt;https://weblogs.asp.net/dixin/rss&lt;/a&gt; as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;rss version=&quot;2.0&quot;&amp;gt;
  &amp;lt;channel&amp;gt;
    &amp;lt;title&amp;gt;Dixin&apos;s Blog&amp;lt;/title&amp;gt;
    &amp;lt;link&amp;gt;https://weblogs.asp.net:443/dixin/&amp;lt;/link&amp;gt;
    &amp;lt;description&amp;gt;https://weblogs.asp.net:443/dixin/&amp;lt;/description&amp;gt;
    &amp;lt;item&amp;gt;
      &amp;lt;title&amp;gt;EntityFramework.Functions: Code First Functions for Entity Framework&amp;lt;/title&amp;gt;
      &amp;lt;link&amp;gt;https://weblogs.asp.net/dixin/entityframework.functions&amp;lt;/link&amp;gt;
      &amp;lt;description&amp;gt;&amp;lt;!-- Description. --&amp;gt;&amp;lt;/description&amp;gt;
      &amp;lt;pubDate&amp;gt;Mon Dec 17, 2015 06:27:56 GMT&amp;lt;/pubDate&amp;gt;
      &amp;lt;guid isPermaLink=&quot;true&quot;&amp;gt;https://weblogs.asp.net/dixin/entityframework.functions&amp;lt;/guid&amp;gt;
      &amp;lt;category&amp;gt;.NET&amp;lt;/category&amp;gt;
      &amp;lt;category&amp;gt;LINQ&amp;lt;/category&amp;gt;
      &amp;lt;category&amp;gt;Entity Framework&amp;lt;/category&amp;gt;
      &amp;lt;category&amp;gt;LINQ to Entities&amp;lt;/category&amp;gt;
      &amp;lt;category&amp;gt;Code First&amp;lt;/category&amp;gt;
    &amp;lt;/item&amp;gt;
    &amp;lt;!-- More items. --&amp;gt;
  &amp;lt;/channel&amp;gt;
&amp;lt;/rss&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a XML document, and can be the source of LINQ to XML. This following example queries the items with permalink from the feed, and get the items’ titles. in ascending order of the items’ publish dates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToXml()
{
    XDocument feed = XDocument.Load(&quot;https://weblogs.asp.net/dixin/rss&quot;);
    IEnumerable&amp;lt;XElement&amp;gt; source = feed.Descendants(&quot;item&quot;); // Get source.
    IEnumerable&amp;lt;string&amp;gt; query =
        from item in source
        where (bool)item.Element(&quot;guid&quot;).Attribute(&quot;isPermaLink&quot;)
        orderby (DateTime)item.Element(&quot;pubDate&quot;)
        select (string)item.Element(&quot;title&quot;); // Define query.
    // Equivalent to:
    // IEnumerable&amp;lt;string&amp;gt; query = source
    //    .Where(item =&amp;gt; (bool)item.Element(&quot;guid&quot;).Attribute(&quot;isPermaLink&quot;))
    //    .OrderBy(item =&amp;gt; (DateTime)item.Element(&quot;pubDate&quot;))
    //    .Select(item =&amp;gt; (string)item.Element(&quot;title&quot;));
    foreach (string result in query) // Execute query.
    {
        Trace.WriteLine(result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the data source is XML data loaded in memory. It queries all &amp;lt;item&amp;gt; elements in the XML document, filter them and only keep the &amp;lt;item&amp;gt; elements with child &amp;lt;guid&amp;gt; elements, whose isPermaLink attributes have the value true, then sort the &amp;lt;item&amp;gt; element by the time represented by the child &amp;lt;pubDate&amp;gt; elements in descending order; then get &amp;lt;item&amp;gt; elements’ child &amp;lt;title&amp;gt; elements’ values. Again, later when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;h3&gt;LINQ to DataSets&lt;/h3&gt;
&lt;p&gt;.NET Framework provides &lt;strong&gt;System.Data.DataSet&lt;/strong&gt; type to cache data in memory. Each &lt;strong&gt;DataSet&lt;/strong&gt; instance contains &lt;strong&gt;System.Data.DataTable&lt;/strong&gt; instances, and each &lt;strong&gt;DataTable&lt;/strong&gt; instance contains &lt;strong&gt;System.Data.DataRow&lt;/strong&gt; instances. &lt;strong&gt;DataSet&lt;/strong&gt;s are frequently used to cache tabular data from relational database. When working with relational database, this tutorial uses Microsoft SQL database and Microsoft AdventureWorks sample database for demonstration. In the following example, data is read from the &lt;strong&gt;AdventureWorks&lt;/strong&gt; database’s &lt;strong&gt;Production.Product&lt;/strong&gt; table, and cached in a &lt;strong&gt;DataSet&lt;/strong&gt; instance. This LINQ query use this cached data in memory (not the data stored in database) as data source, and queries the products in the specified subcategory, and get the products’ names, in ascending order of products’ list prices.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToDataSets(string connectionString)
{
    using (DataSet dataSet = new DataSet())
    using (DataAdapter dataAdapter = new SqlDataAdapter(
        @&quot;SELECT [Name], [ListPrice], [ProductSubcategoryID] FROM [Production].[Product]&quot;, connectionString))
    {
        dataAdapter.Fill(dataSet);
        EnumerableRowCollection&amp;lt;DataRow&amp;gt; source = dataSet.Tables[0].AsEnumerable(); // Get source.
        EnumerableRowCollection&amp;lt;string&amp;gt; query =
            from product in source
            where product.Field&amp;lt;int&amp;gt;(&quot;ProductSubcategoryID&quot;) == 1
            orderby product.Field&amp;lt;decimal&amp;gt;(&quot;ListPrice&quot;)
            select product.Field&amp;lt;string&amp;gt;(&quot;Name&quot;); // Define query.
        // Equivalent to:
        // EnumerableRowCollection&amp;lt;string&amp;gt; query = source
        //    .Where(product =&amp;gt; product.Field&amp;lt;int&amp;gt;(&quot;ProductSubcategoryID&quot;) == 1)
        //    .OrderBy(product =&amp;gt; product.Field&amp;lt;decimal&amp;gt;(&quot;ListPrice&quot;))
        //    .Select(product =&amp;gt; product.Field&amp;lt;string&amp;gt;(&quot;Name&quot;));
        foreach (string result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the query is created to filter the products in the &lt;strong&gt;DataSet&lt;/strong&gt; object, and only keeps the products under the specified subcategory, then sort the products by their list price fields, then get the products’ name fields. Later, when pulling the results from the query with a foreach loop, the query is executed.&lt;/p&gt;
&lt;h3&gt;LINQ to Entities&lt;/h3&gt;
&lt;p&gt;Microsoft EF/Core providesLINQ to Entities enables LINQ queries directly working with data in relational databases. The AdventureWorks sample database includes the following 3 related tables:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb31_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb31_thumb_thumb.png&quot; alt=&quot;image_thumb31_thumb&quot; title=&quot;image_thumb31_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following example queries &lt;strong&gt;Production.Product&lt;/strong&gt; table for the products under the specified category, and get the products’ names in the order of their list prices:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToEntities()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products; // Get source.
        IQueryable&amp;lt;string&amp;gt; query =
            from product in source
            where product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;
            orderby product.ListPrice
            select product.Name; // Define query.
        // Equivalent to:
        // IQueryable&amp;lt;string&amp;gt; query = source
        //    .Where(product =&amp;gt; product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;)
        //    .OrderBy(product =&amp;gt; product.ListPrice)
        //    .Select(product =&amp;gt; product.Name);
        foreach (string result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the data source is the relational data stored in the remote database table, not local .NET objects in memory. The above &lt;strong&gt;AdventureWorks&lt;/strong&gt; type is the LINQ to Entities data context and represents the database, and its &lt;strong&gt;Products&lt;/strong&gt; property represents the table. The query is created to filter the products in the table, and only keeps the products under the specified category, then sort the products by their list prices, and get the products’ names. Later, when pulling the results from the query with a foreach loop, the query is executed to read from the database.&lt;/p&gt;
&lt;h3&gt;LINQ to SQL&lt;/h3&gt;
&lt;p&gt;LINQ to SQL is a lightweight database access technology provided by .NET Framework. As the name suggests, LINQ to SQL only works with Microsoft SQL Server. Its APIs are similar to LINQ to Entities APIs. So if the above queries are implemented by LINQ to SQL, the code can have the same looking:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#if NETFX
internal static void LinqToSql()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;Product&amp;gt; source = adventureWorks.Products; // Get source.
        IQueryable&amp;lt;string&amp;gt; query =
            from product in source
            where product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;
            orderby product.ListPrice
            select product.Name; // Define query.
        // Equivalent to:
        // IQueryable&amp;lt;string&amp;gt; query = source
        //    .Where(product =&amp;gt; product.ProductSubcategory.ProductCategory.Name == &quot;Bikes&quot;)
        //    .OrderBy(product =&amp;gt; product.ListPrice)
        //    .Select(product =&amp;gt; product.Name);
        foreach (string result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the &lt;strong&gt;AdventureWorks&lt;/strong&gt; type is a LINQ to SQL data context, which is different from the LINQ to Entities data context. So the pulling execution on the query triggers LINQ to SQL API calls, which read data from the database.&lt;/p&gt;
&lt;h3&gt;LINQ to NoSQL (LINQ to CosmosDB)&lt;/h3&gt;
&lt;p&gt;LINQ can also work with non relational database (aka NoSQL database). Microsoft Azure CosmosDB is such a NoSQL database service, and it provides client library to enable LINQ queries. To setup a data source for LINQ, &lt;a href=&quot;https://azure.microsoft.com/en-us/free/&quot;&gt;create a free account&lt;/a&gt;, then follow the Microsoft documents to import some JSON documents representing some stores with addresses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[
    {
        &quot;id&quot;: &quot;1424&quot;,
        &quot;Name&quot;: &quot;Closeout Boutique&quot;,
        &quot;Address&quot;: {
            &quot;AddressType&quot;: &quot;Main Office&quot;,
            &quot;AddressLine1&quot;: &quot;1050 Oak Street&quot;,
            &quot;Location&quot;: {
                &quot;City&quot;: &quot;Seattle&quot;,
                &quot;StateProvinceName&quot;: &quot;Washington&quot;
            },
            &quot;PostalCode&quot;: &quot;98104&quot;,
            &quot;CountryRegionName&quot;: &quot;United States&quot;
        }
    },
    // More documents.
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the source is the database’s Store collection. The following example queries the stores in the specified city, and get their names in the alphabetic order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToNoSql(string key)
{
    using (DocumentClient client = new DocumentClient(
        new Uri(&quot;https://dixin.documents.azure.com:443/&quot;), key))
    {
        IOrderedQueryable&amp;lt;Store&amp;gt; source = client.CreateDocumentQuery&amp;lt;Store&amp;gt;(
            UriFactory.CreateDocumentCollectionUri(&quot;dixin&quot;, &quot;Store&quot;)); // Get source.
        IQueryable&amp;lt;string&amp;gt; query = from store in source
                                    where store.Address.Location.City == &quot;Seattle&quot;
                                    orderby store.Name
                                    select store.Name; // Define query.
        // Equivalent to:
        // IQueryable&amp;lt;string&amp;gt; query = source
        //    .Where(store =&amp;gt; store.Address.CountryRegionName == &quot;United States&quot;)
        //    .OrderBy(store =&amp;gt; store.Address.PostalCode)
        //    .Select(store =&amp;gt; store.Name);
        foreach (string result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query is created to filter the products in the collection, and only keeps the stores in the specified city, then sort the stores by their names, then get the the stores’ names.&lt;/p&gt;
&lt;h3&gt;LINQ to JSON&lt;/h3&gt;
&lt;p&gt;LINQ to JSON is a third party set of APIs enabling LINQ for JSON data. Tumblr provides APIs returning JSON data, which can be a data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;meta&quot;: {
    &quot;status&quot;: 200,
    &quot;msg&quot;: &quot;OK&quot;
  },
  &quot;response&quot;: {
    &quot;blog&quot;: {
      &quot;title&quot;: &quot;Dixin Yan&quot;,
      &quot;name&quot;: &quot;dixinyan&quot;,
      &quot;total_posts&quot;: 20,
      &quot;posts&quot;: 20,
      &quot;url&quot;: &quot;http://dixinyan.tumblr.com/&quot;,
      &quot;updated&quot;: 1487649099,
      &quot;description&quot;: &quot;Blog - https://weblog.asp.net/dixin&quot;,
      &quot;is_nsfw&quot;: false,
      &quot;ask&quot;: true,
      &quot;ask_page_title&quot;: &quot;Ask me anything&quot;,
      &quot;ask_anon&quot;: true,
      &quot;share_likes&quot;: false
    },
    &quot;posts&quot;: [
      {
        &quot;type&quot;: &quot;photo&quot;,
        &quot;blog_name&quot;: &quot;dixinyan&quot;,
        &quot;id&quot;: 94086491678,
        &quot;post_url&quot;: &quot;http://dixinyan.tumblr.com/post/94086491678/microsoft-way-microsoft-campus-microsoft-campus&quot;,
        &quot;slug&quot;: &quot;microsoft-way-microsoft-campus-microsoft-campus&quot;,
        &quot;date&quot;: &quot;2014-08-07 19:11:43 GMT&quot;,
        &quot;timestamp&quot;: 1407438703,
        &quot;state&quot;: &quot;published&quot;,
        &quot;format&quot;: &quot;html&quot;,
        &quot;reblog_key&quot;: &quot;FZQVzcFD&quot;,
        &quot;tags&quot;: [ &quot;Microsoft&quot; ],
        &quot;short_url&quot;: &quot;https://tmblr.co/Z_W6Et1Nd-UuU&quot;,
        &quot;summary&quot;: &quot;Microsoft Way, Microsoft Campus  Microsoft Campus is the informal name of Microsoft&apos;s corporate headquarters, located at One...&quot;,
        &quot;recommended_source&quot;: null,
        &quot;recommended_color&quot;: null,
        &quot;note_count&quot;: 4,
        &quot;caption&quot;: &quot;&amp;lt;h2&amp;gt;Microsoft Way, Microsoft Campus &amp;lt;/h2&amp;gt;&amp;lt;p&amp;gt;Microsoft Campus is the informal name of Microsoft&amp;amp;rsquo;s corporate headquarters, located at One Microsoft Way in Redmond, Washington. Microsoft initially moved onto the grounds of the campus on February 26, 1986. &amp;lt;a href=\&quot;http://en.wikipedia.org/wiki/Microsoft_Redmond_Campus\&quot; target=\&quot;_blank\&quot;&amp;gt;en.wikipedia.org/wiki/Microsoft_Redmond_Campus&amp;lt;/a&amp;gt;\n\n&amp;lt;a href=\&quot;https://www.flickr.com/dixin\&quot; target=\&quot;_blank\&quot;&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&quot;,
        &quot;image_permalink&quot;: &quot;http://dixinyan.tumblr.com/image/94086491678&quot;,
        &quot;can_like&quot;: true,
        &quot;can_reblog&quot;: true,
        &quot;can_send_in_message&quot;: true,
        &quot;can_reply&quot;: false,
        &quot;display_avatar&quot;: true
        // More post info.
      },
      // More posts.
    ],
    &quot;total_posts&quot;: 20
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example queries the posts with specified tag, and get their summary in the order of items’ publish date:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task LinqToJson(string apiKey)
{
    using (HttpClient httpClient = new HttpClient())
    {
        string feedUri = $&quot;https://api.tumblr.com/v2/blog/dixinyan.tumblr.com/posts/photo?api_key={apiKey}&quot;;
        JObject feed = JObject.Parse((await httpClient.GetStringAsync(feedUri)));
        IEnumerable&amp;lt;JToken&amp;gt; source = feed[&quot;response&quot;][&quot;posts&quot;]; // Get source.
        IEnumerable&amp;lt;string&amp;gt; query =
            from post in source
            where post[&quot;tags&quot;].Any(tag =&amp;gt; &quot;Microsoft&quot;.Equals((string)tag, StringComparison.OrdinalIgnoreCase))
            orderby (DateTime)post[&quot;date&quot;]
            select (string)post[&quot;summary&quot;]; // Define query.
        // Equivalent to:
        // IEnumerable&amp;lt;string&amp;gt; query = source
        //    .Where(post =&amp;gt; post[&quot;tags&quot;].Any(tag =&amp;gt;
        //        &quot;Microsoft&quot;.Equals((string)tag, StringComparison.OrdinalIgnoreCase)))
        //    .OrderBy(post =&amp;gt; (DateTime)post[&quot;date&quot;])
        //    .Select(post =&amp;gt; (string)post[&quot;summary&quot;]);
        foreach (string result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It queries all posts in the JSON document, filter them and only keep the items with the specified tag, then sort the posts by their publish dates, then get the items’ titles.&lt;/p&gt;
&lt;h3&gt;LINQ to Twitter&lt;/h3&gt;
&lt;p&gt;LINQ to Twitter is another third party library enabling LINQ queries for Twitter data. To access Twitter as a data source, &lt;a href=&quot;https://apps.twitter.com/&quot;&gt;registering an app with Twitter&lt;/a&gt; to get the consumer key, consumer secrete, OAuth token, and OAuth token secrete. The following example queries the tweets with specified search keyword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LinqToTwitter(
    string consumerKey, string consumerSecret, string oAuthToken, string oAuthTokenSecret)
{
    SingleUserAuthorizer credentials = new SingleUserAuthorizer()
    {
        CredentialStore = new InMemoryCredentialStore()
        {
            ConsumerKey = consumerKey,
            ConsumerSecret = consumerSecret,
            OAuthToken = oAuthToken,
            OAuthTokenSecret = oAuthTokenSecret
        }
    };
    using (TwitterContext twitter = new TwitterContext(credentials))
    {
        IQueryable&amp;lt;Search&amp;gt; source = twitter.Search; // Get source.
        IQueryable&amp;lt;List&amp;lt;Status&amp;gt;&amp;gt; query =
            from search in source
            where search.Type == SearchType.Search &amp;amp;&amp;amp; search.Query == &quot;LINQ&quot;
            orderby search.SearchMetaData.Count
            select search.Statuses; // Define query.
        // Equivalent to:
        // IQueryable&amp;lt;List&amp;lt;Status&amp;gt;&amp;gt; query = source
        //    .Where(search =&amp;gt; search.Type == SearchType.Search &amp;amp;&amp;amp; search.Query == &quot;LINQ&quot;)
        //    .OrderBy(search =&amp;gt; search.SearchMetaData.Count)
        //    .Select(search =&amp;gt; search.Statuses);
        foreach (List&amp;lt;Status&amp;gt; search in query) // Execute query.
        {
            foreach (Status status in search)
            {
                Trace.WriteLine(status.Text);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes the query result could be &lt;a href=&quot;https://twitter.com/LinQ_official&quot;&gt;funny&lt;/a&gt;, because a Japanese idol girl music group is also named LinQ (Love in Qshu):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.facebook.com/loveinq&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/71aaD4GcBeL._SL1416__3.jpg&quot; alt=&quot;71aaD4GcBeL.SL1416&quot; title=&quot;71aaD4GcBeL._SL1416_&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Productivity&lt;/h2&gt;
&lt;p&gt;When LINQ was first released with .NET Framework 3.5, &lt;a href=&quot;http://msdn.microsoft.com/en-us/netframework/aa904594.aspx&quot;&gt;MSDN&lt;/a&gt; describes it as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LINQ is one of Microsoft’s most exciting, powerful new development technologies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Traditionally, to work with a specific data domain, a domain specific language and a set of domain specific APIs are used. For example, the following example is equivalent to above LINQ to XML query logic, implemented in traditional programming model, which calls XML APIs to execute query expression in XPath language:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Imperative
{
    internal static void Xml()
    {
        XPathDocument feed = new XPathDocument(&quot;https://weblogs.asp.net/dixin/rss&quot;);
        XPathNavigator navigator = feed.CreateNavigator();
        XPathExpression selectExpression = navigator.Compile(&quot;//item[guid/@isPermaLink=&apos;true&apos;]/title/text()&quot;);
        XPathExpression sortExpression = navigator.Compile(&quot;../../pubDate/text()&quot;);
        selectExpression.AddSort(sortExpression, Comparer&amp;lt;DateTime&amp;gt;.Default);
        XPathNodeIterator nodes = navigator.Select(selectExpression);
        foreach (object node in nodes)
        {
            Trace.WriteLine(node);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For SQL database, the traditional programming model implements the above LINQ to Entities query logic by calling ADO.NET data access APIs to execute query statement in SQL language:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Sql(string connectionString)
{
    using (DbConnection connection = new SqlConnection(connectionString))
    using (DbCommand command = connection.CreateCommand())
    {
        command.CommandText =
            @&quot;SELECT [Product].[Name]
            FROM [Production].[Product] AS [Product]
            LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Subcategory] 
                ON [Subcategory].[ProductSubcategoryID] = [Product].[ProductSubcategoryID]
            LEFT OUTER JOIN [Production].[ProductCategory] AS [Category] 
                ON [Category].[ProductCategoryID] = [Subcategory].[ProductCategoryID]
            WHERE [Category].[Name] = @categoryName
            ORDER BY [Product].[ListPrice] DESC&quot;;
        DbParameter parameter = command.CreateParameter();
        parameter.ParameterName = &quot;@categoryName&quot;;
        parameter.Value = &quot;Bikes&quot;;
        command.Parameters.Add(parameter);
        connection.Open();
        using (DbDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                string productName = (string)reader[&quot;Name&quot;];
                Trace.WriteLine(productName);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, for Twitter data, there are network APIs to query Twitter’s REST endpoints, etc. LINQ implements an unified and consistent language syntax and programming model for many different data domains. Above examples demonstrated the same C# syntax builds filter-sort-map query flows for CLR objects, XML data, cached tabular data, SQL database, NoSQL database, JSON, Twitter data. This capability makes LINQ a powerful and productive solution for working with data.&lt;/p&gt;
&lt;p&gt;C# is a strongly typed language. In C#, any value has a type, including any value in LINQ query. And any expression is evaluated to a type, including LINQ query expressions. Any method has a type for each parameter and a type for return value, including LINQ query methods. So LINQ queries are checked by compiler and CLR for type safety, which is great help for productivity, unless &lt;strong&gt;dynamic&lt;/strong&gt; typing is used to bypass the compiler check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Linq
{
    internal static void Dynamic()
    {
        IEnumerable&amp;lt;int&amp;gt; source = new int[] { 4, 3, 2, 1, 0, -1 }; // Get source.
        IEnumerable&amp;lt;dynamic&amp;gt; query =
            from dynamic value in source
            where value.ByPass.Compiler.Check &amp;gt; 0
            orderby value.ByPass().Compiler().Check()
            select value &amp;amp; new object(); // Define query.
        foreach (dynamic result in query) // Execute query.
        {
            Trace.WriteLine(result);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Strong typing also enables IntelliSense for IDE, which also improves the productivity:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb3_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programming-and-LINQ-Paradigm_150FF/image_thumb3_thumb.png&quot; alt=&quot;image_thumb3&quot; title=&quot;image_thumb3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LINQ also supports deferred execution. Usually, LINQ query is executed only when the results are pulled from the query. This enables creating query with arbitrary complexity. In above examples, during the composition of filter-sort-map, no execution is triggered. Later, when the results are pulled, the entire filter-sort-map query executes is triggered. This is also important for productivity. Take above LINQ to Entities query as example, when the query is executed against the SQL database, the entire filter-sort-map query logic is submitted to database as a single database query. Without deferred execution, this cannot be done.&lt;/p&gt;
&lt;p&gt;LINQ is not only about data query. Many LINQ libraries provide rich APIs to manipulate and change the data too, like LINQ to XML, LINQ to SQL, and EF/Core, and DocumentDB client, etc. Parallel LINQ is a special set of LINQ APIs, it can significantly improve the query performance for CLR objects, it also provides an simple programming model for general parallel computing.&lt;/p&gt;
&lt;h2&gt;Local query vs. remote query&lt;/h2&gt;
&lt;p&gt;Generally, there are 2 kinds of LINQ technologies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local query: The data source for local query is .NET objects in local memory of current .NET application or service. Apparently, (sequential) LINQ to Objects queries, and Parallel LINQ (to Objects) queries are local queries. LINQ to XML have XML data loaded to memory as specialized .NET objects representing the XML data structure, then query these objects, so LINQ to XML queries are also local queries too. Similarly, LINQ to DataSets and LINQ to JSON queries are local queries too. As demonstrated above, the local sequential LINQ data source and query is represented by &lt;strong&gt;System.Collections.Generics.IEnumerable&amp;lt;T&amp;gt;&lt;/strong&gt; interface, and the local parallel LINQ data source and query is represented by &lt;strong&gt;System.Linq.ParallelQuery&amp;lt;T&amp;gt;&lt;/strong&gt; type.&lt;/li&gt;
&lt;li&gt;Remote query: The data source for remote query is not in the local memory. For example, LINQ to Entities queries the data stored in a relational database, apparently the data source is not available as .NET objects in the memory of current .NET application or service. So LINQ to Entities queries are remote queries. So are LINQ to SQL, LINQ to DocumentDB and LINQ to Twitter. As demonstrated above, the remote LINQ data source and query is represented by &lt;strong&gt;System.Linq.IQueryable&amp;lt;T&amp;gt;&lt;/strong&gt; interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are so many LINQ technologies, it is infeasible and also unnecessary to have one tutorial for all of them. This tutorial covers C# language&apos;s LINQ features, and the most used LINQ APIs: LINQ to Object (sequential local queries), LINQ to XML (specialized local queries), Parallel LINQ (parallel local queries), as well as EF/Core (remote queries). With the unified and consistent LINQ programming model, mastering these LINQ knowledge enables developers working any other local or remote LINQ technologies, understanding the internal implementation of these LINQ technologies also enables developer to build custom LINQ APIs to for other local or remote data scenarios.&lt;/p&gt;
</content:encoded></item><item><title>Functional Programming and LINQ Paradigm (1) Getting Started with .NET/Core, C# and LINQ</title><link>https://dixin.github.io/posts/linq-via-csharp-introduction-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-via-csharp-introduction-7/</guid><description>This is a tutorial of functional programming and LINQ in C# language. The contents was initially based on my . Hope it helps.</description><pubDate>Mon, 28 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;Latest version:&lt;/strong&gt; &lt;a href=&quot;/posts/linq-via-csharp-introduction&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/linq-via-csharp-introduction&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is a tutorial of functional programming and LINQ in C# language. The contents was initially based on my &lt;a href=&quot;/posts/linq-via-csharp-events-posters-design&quot;&gt;LINQ via C# talks&lt;/a&gt;. Hope it helps.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/LINQ-via-CSharp_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/LINQ-via-CSharp_thumb_thumb.png&quot; alt=&quot;LINQ-via-CSharp_thumb&quot; title=&quot;LINQ-via-CSharp_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Cross platform .NET, C# and LINQ&lt;/h2&gt;
&lt;p&gt;In 2002, C# was initially introduced with .NET Framework on Windows. Since then, many functional features including LINQ has been built into C# language and .NET Framework. There are also many other frameworks joins the .NET family, which enable C# and LINQ to work on many platforms.&lt;/p&gt;
&lt;h3&gt;.NET Framework&lt;/h3&gt;
&lt;p&gt;Microsoft &lt;a href=&quot;https://en.wikipedia.org/wiki/.NET_Framework&quot;&gt;.NET Framework&lt;/a&gt; (pronounced “dot net”) is a free development framework on Windows, widely used to build applications and services with simple programming model and great productivity. .NET Framework is based on &lt;a href=&quot;https://en.wikipedia.org/wiki/Common_Intermediate_Language&quot;&gt;Common Intermediate Language&lt;/a&gt; (CIL), and consists of &lt;a href=&quot;https://en.wikipedia.org/wiki/Common_Language_Runtime&quot;&gt;Common Language Runtime&lt;/a&gt; (CLR), &lt;a href=&quot;https://en.wikipedia.org/wiki/Framework_Class_Library&quot;&gt;Framework Class Library&lt;/a&gt; (FCL):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CIL is the object-oriented assembly language used by .NET Framework.&lt;/li&gt;
&lt;li&gt;FCL is a set of built-in libraries of rich APIs implemented as classes, interfaces, and structures, etc. It is the fundamental used by .NET applications and services to access system functionality. FCL provides primitive types, exceptions, collections, I/O, threading, reflection, text processing, database access, and LINQ, etc.&lt;/li&gt;
&lt;li&gt;CLR is the runtime environment that works like a virtual machine. All .NET applications and services are executed by CLR. CLR provides features including &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/f144e03t.aspx&quot;&gt;automatic memory management&lt;/a&gt;, thread management, structured exception handling, type safety, security, just-in-time (JIT) compiler which compiles CIL to machine code, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms228593.aspx&quot;&gt;C#&lt;/a&gt; language (pronounced “c sharp”) is a general purpose high level language, and standardized by ECMA-334 and ISO/IEC 23270 standards. Microsoft’s C# compiler is an implementation of these standards. It compiles C# to CIL, which can be executed by CLR. C# is type-safe, generic, object-oriented and functional programming language. It is modern, expressive and productive. There are also &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_CLI_languages&quot;&gt;other high level languages&lt;/a&gt; that can be used to build .NET applications and services, like VB.NET, F#, etc., which are compiled or interpreted to CIL as well. C# is the most popular .NET language used by millions of people. Microsoft provides &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Visual_Studio&quot;&gt;Visual Studio,&lt;/a&gt; a powerful integrated development environment (IDE), with built-in support for .NET and C# software development.&lt;/p&gt;
&lt;p&gt;The real world applications and services work with data, which can be of any form, like data objects in local memory, data in XML format, data stored with database, etc. Traditionally, a specific programming model is required to work with each kind of data source. For example, traditionally, querying a sequence of data objects in local memory can be quite different from querying data rows from a table in database. For .NET and C# programming, Microsoft provides a general purpose solution applies to many data sources, that is LINQ. When searching “LINQ” with &lt;a href=&quot;https://www.bing.com/search?q=linq&quot;&gt;Bing&lt;/a&gt; or &lt;a href=&quot;https://www.google.com/search?q=linq&quot;&gt;Google&lt;/a&gt;, the top item on the first result page is an ad of the &lt;a href=&quot;https://www.caesars.com/linq&quot;&gt;LINQ hotel &amp;amp; casino&lt;/a&gt; in Las Vegas:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/8753178_25_z_thumb_2.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Introducing-LINQ-1-What-Is-LINQ_10D64/8753178_25_z_thumb_thumb.jpg&quot; alt=&quot;8753178_25_z_thumb&quot; title=&quot;8753178_25_z_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, in this tutorial, LINQ stands for something more serious, “Language-INtegrated Query” (pronounced “link”). It is a set of general purpose data query features enabling a simple, consistent, and powerful bridge between the programming domain and many different data domains. LINQ consists of language features and .NET FCL features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Native .NET languages features are added for data query capabilities. For C#, language features, including lambda expression, query expression, etc., are added to compose declarative and functional data queries.&lt;/li&gt;
&lt;li&gt;Data access APIs are implemented in .NET FCL, including interfaces and classes representing the data sources, query methods implementing the query logic, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For .NET applications and services using LINQ, at compile time, the data queries in native languages are compiled to regular API calls; At runtime, CLR executes these API calls to query the data sources. Microsoft implements LINQ syntaxes for languages including C#, VB.NET, F#, etc., and also implements LINQ APIs in FCL to work with CLR objects, XML data, and database. The language features can work FCL APIs as well as custom APIs, which enables LINQ to work with many data sources.&lt;/p&gt;
&lt;p&gt;LINQ is rooted in Microsoft&apos;s &lt;a href=&quot;http://en.wikipedia.org/wiki/C%CF%89&quot;&gt;Cω&lt;/a&gt; research project, and was first released as a part of &lt;a href=&quot;http://en.wikipedia.org/wiki/.NET_Framework_3.5&quot;&gt;.NET Framework 3.5&lt;/a&gt; and C# 3.0. The following table shows the position of LINQ in the history roadmap of .NET Framework and C# language:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;535&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;53&quot;&amp;gt;Year&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;Visual Studio&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;.NET Framework&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Framework features&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;CLR&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;55&quot;&amp;gt;2002&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;.NET 2002&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;1.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;CLR, FCL (ADO.NET, ASP.NET, etc.)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;1.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;1.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;56&quot;&amp;gt;2003&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;.NET 2003&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;1.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;IPv6, Oracle database, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;1.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;1.1&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;57&quot;&amp;gt;2003&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;1.2&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2005&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2005&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;2.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Generics, full 64 bit computing, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;2.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;2.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2006&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;3.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;WCF, WPF, WF, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;&amp;lt;strong&amp;gt;2007&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;strong&amp;gt;2008&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;&amp;lt;strong&amp;gt;3.5&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;strong&amp;gt;LINQ&amp;lt;/strong&amp;gt;, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;3.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2010&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2010&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;TPL, &amp;lt;strong&amp;gt;Parallel LINQ&amp;lt;/strong&amp;gt;, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;4 (&amp;lt;a href=&quot;https://msdn.microsoft.com/en-us/library/8bs2ecf4.aspx&quot; target=&quot;_blank&quot;&amp;gt;not “4.0”&amp;lt;/a&amp;gt;)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;4.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2012&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2012&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.5&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Zip, &amp;lt;strong&amp;gt;Parallel LINQ improvement&amp;lt;/strong&amp;gt;, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;5.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2013&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2013&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.5.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Automatic binding redirection, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2014&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.5.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;New ASP.NET APIs, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2015&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2015&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.6&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;New 64-bit JIT compiler, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;6.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2015&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.6.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Cryptography improvement, .NET Standard 2.0 support with additional files, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.6.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;SQL Server client improvement, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;7.0&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.7&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;Azure SQL Database connectivity improvement, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;7.1&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;4.7.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;a href=&quot;https://github.com/dotnet/announcements/issues/32&quot; target=&quot;_blank&quot;&amp;gt;Built-in&amp;lt;/a&amp;gt; .NET Standard 2.0 support, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;58&quot;&amp;gt;2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;83&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;181&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;76&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;47&quot;&amp;gt;7.2&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;.NET Core, UWP, Mono, Xamarin and Unity&lt;/h3&gt;
&lt;p&gt;After 15+ years, .NET Framework has been a rich ecosystem on Windows. Besides .NET Framework, C# also works on many other frameworks and platforms. In 2016, Microsoft released .NET Core, a free, open source and cross-platform version of .NET Framework. .NET Core is essentially a fork a .NET Framework. it is still based on CIL, with a runtime called CoreCLR, and class libraries called CoreFX. The same C# language works with .NET Core, as well as fore mentioned F# and VB.NET. As the name suggests, .NET Core implements the core features of .NET Framework. So it can be viewed as a subset of .NET Framework. It is designed to be a lightweight and high performance framework to build applications and services on Windows, macOS, and many Linux distributions, including Read Hat, Ubuntu, CentOS, Debian, Fedora, OpenSUSE, Oracle Linux, etc., so that it works on a wide range of devices, clouds, and embedded/IoT scenarios. The following table shows .NET Core is released in a more agile iteration:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;557&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;Year&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;109&quot;&amp;gt;.NET Core&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;332&quot;&amp;gt;.Features&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;119&quot;&amp;gt;Jun 2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;113&quot;&amp;gt;1.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;336&quot;&amp;gt;CoreCLR, CoreFX, WCF, ASP.NET Core, etc.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;Sep 2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;115&quot;&amp;gt;1.0.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;335&quot;&amp;gt;Update for 1.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Oct 2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;117&quot;&amp;gt;1.0.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;333&quot;&amp;gt;Update for 1.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;123&quot;&amp;gt;Nov 2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;119&quot;&amp;gt;1.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;331&quot;&amp;gt;More APIs, performance improvements, etc.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;123&quot;&amp;gt;Dec 2016&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;120&quot;&amp;gt;1.0.3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;330&quot;&amp;gt;Update for 1.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;123&quot;&amp;gt;Mar 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;1.0.4/1.1.1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;330&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;May 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;123&quot;&amp;gt;1.0.5/1.1.2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Aug 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;2.0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;.NET Standard 2.0, performance improvement, etc.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Sep 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;1.0.6/1.1.3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Nov 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;1.0.7/1.1.4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 1.0/1.1.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Nov 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;1.0.8/1.1.5/2.0.3&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Dec 2017&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;2.0.4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 2.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;122&quot;&amp;gt;Jan 2018&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;124&quot;&amp;gt;1.0.9/1.1.6/2.0.5&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;328&quot;&amp;gt;Update for 1.0/1.1/2.0.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Microsoft also released Universal Windows Platform (UWP), the app model for Windows 10. UWP enables C# (as well as VB.NET, C++, JavaScript) to develop Microsoft Store application that can work cross all Windows 10 device families, including PC, tablet, phone, Xbox, HoloLens, Surface Hub, IoT, etc. &lt;a href=&quot;https://msdn.microsoft.com/en-us/magazine/mt814993.aspx&quot;&gt;UWP takes advantage of .NET Core&lt;/a&gt;. In Debug mode, UWP app is compiled to CIL, and runs against CoreCLR. In Release mode, UWP app is compiled to native binaries for better performance, and runs against &lt;a href=&quot;https://blogs.windows.com/buildingapps/2015/08/20/net-native-what-it-means-for-universal-windows-platform-uwp-developers/&quot;&gt;.NET Native&lt;/a&gt; runtime.&lt;/p&gt;
&lt;p&gt;Besides .NET Core and UWP, Mono (Monkey in Spanish) is another open source implementation of .NET Framework based on the ECMA standards for C# and CLR. Mono was initially released in 2004. It works cross many platforms, including Windows, macOS, most Linux distributions, BSD, Solaris, Android, iOS, and game consoles like Xbox, PlayStation, Wii, etc.. Based on Mono, Xamarin is a framework for building native mobile apps on Windows, Android and iOS with C#. Microsoft acquired Xamarin in 2016 and has made it open source and available as free.&lt;/p&gt;
&lt;p&gt;C# is also the language for Unity, a &lt;a href=&quot;https://docs.unity3d.com/Manual/PlatformDependentCompilation.html&quot;&gt;cross platform&lt;/a&gt; game engine developed by Unity Technologies. Unity also &lt;a href=&quot;https://msdn.microsoft.com/en-us/magazine/dn759441.aspx&quot;&gt;takes advantage of Mono&lt;/a&gt; to enable C# to develop games for Windows, macOS, Linux, Android, iOS, and game consoles like Xbox, PlayStation, Wii, etc. Unity used to support UnityScript, a JavaScript-like language, and Boo language. Now UnityScript and Boo are being &lt;a href=&quot;https://blogs.unity3d.com/2017/08/11/unityscripts-long-ride-off-into-the-sunset/&quot;&gt;deprecated&lt;/a&gt; regarding the popularity of C#.&lt;/p&gt;
&lt;p&gt;The following table summarizes these framework&apos;s languages, base API surface, runtime for managed code, supported application models, and supported platforms:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;604&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;.NET Framework&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;.NET Core&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;94&quot;&amp;gt;UWP&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;Xamarin&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;Unity&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Languages&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;C#, VB.NET, F#, etc.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;C#, F#, VB.NET&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;C#, VB.NET, C++, JavaScript&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;C#, UnityScript (deprecated), Boo (deprecated)&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;100&quot;&amp;gt;Base API surface&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;.NET FCL&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;CoreFX&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Universal device family APIs&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;Mono base libraries&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;Mono base libraries&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;100&quot;&amp;gt;Managed runtime&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;CLR&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;CoreCLR&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;94&quot;&amp;gt;.NET Native runtime&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;Mono runtime&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;Mono runtime&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Application models&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;Windows desktop applications and services&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;Cross-platform services&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;Microsoft Store apps&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;Mobile apps&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;Games&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Platforms&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;114&quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;111&quot;&amp;gt;Windows, macOS, Linux&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;93&quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;98&quot;&amp;gt;Windows, Android, iOS&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;90&quot;&amp;gt;Windows, macOS, Linux, Android, iOS, game consoles&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;.NET Standard&lt;/h3&gt;
&lt;p&gt;The same C# language works on many frameworks and platforms. However, each framework provides its own base API surface for C# developers. To prevent APIs’ fragmentation, provide a unified development experience, and enable better code sharing, Microsoft defines .NET Standard specification. .NET Standard is a list of APIs, which is the base API surface should be implemented by any framework in the .NET family. .NET Standard is represented by NuGet package NETStandard.Library, which has a reference assembly netstandard.dll. The latest major release of .NET Standard is 2.0. It has 32k+ APIs. It is &lt;a href=&quot;https://github.com/dotnet/standard/blob/master/docs/versions.md&quot;&gt;supported&lt;/a&gt; by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET Framework 4.6.1/4.6.2/4.7 (support with additional files), .NET Framework 4.7.1 (built-in support)&lt;/li&gt;
&lt;li&gt;.NET Core 2.0&lt;/li&gt;
&lt;li&gt;Mono 5.4&lt;/li&gt;
&lt;li&gt;UWP 10.0.16299&lt;/li&gt;
&lt;li&gt;Xamarin.Forms 2.4, Xamarin.Mac 3.8, Xamarin.Android 8.0, Xamarin.iOS 10.14&lt;/li&gt;
&lt;li&gt;Unity 2018&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This standardization provides great consistency and productivity for C# developers – one language and one set of base APIs can be used to develop many kinds of applications working cross many platforms. In the perspective of C# developer, the development experience becomes to use one lanuage and one set of base APIs to develop many kinds of applications and servers on many platforms:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;605&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;94&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;.NET Framework&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;.NET Core&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;UWP&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Xamarin&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Unity&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;96&quot;&amp;gt;Language&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;C#&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Base API surface&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;.NET Standard&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;.NET Standard&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;.NET Standard&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;.NET Standard&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;.NET Standard&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Application models&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;Windows desktop applications and services&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Cross-platform services&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Microsoft Store apps&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Mobile apps&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Games&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Platforms&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;121&quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Windows, macOS, Linux&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;97&quot;&amp;gt;Windows, Android, iOS&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Windows, macOS, Linux, Android, iOS, game consoles&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;The LINQ language features are part of the C# language standard, and the LINQ APIs are part of the .NET Standard, so LINQ is available on all frameworks in the .NET family, with one set of language syntax and one set of APIs. This tutorial covers the cross platform C# language and cross-platform LINQ technologies provided by Microsoft and adopting to .NET Standard 2.0, including LINQ to Objects, Parallel LINQ, LINQ to XML, LINQ to Entities.&lt;/p&gt;
&lt;h3&gt;C# functional programming&lt;/h3&gt;
&lt;p&gt;.NET Standard is an object-oriented collection of reusable types, CIL is a object-oriented assembly language, and C# is also initially an object-oriented programming language, fully supporting encapsulation, inheritance, and polymorphism, so that .NET APIs and C# language work together seamlessly. In the meanwhile, C# also supports functional programming. As a typical example, LINQ is extensively functional. In C#, functions are first class citizens just like objects are. C# has plenty of functional features, like closure, higher-order function, anonymous function, etc. The LINQ features, like query expressions, lambda expression, etc., are also functional features instead of object-oriented features.&lt;/p&gt;
&lt;p&gt;Functional programming is different from object-oriented programming in many aspects. Functional programming is usually more self-contained, more stateless, more immutable, more lazy, more side effects management, etc. The most intuitive difference is, functional programming is more declarative instead of imperative. It focus on describing what to do, instead of specifying the execution details of how to do. As a result, functional programming can be very expressive and productive. When working with data, as a typical example, functional LINQ queries provide the general capabilities of describing what is the query logic for different data source, rather than specifying the execution details of how to access and query each specific data source, so that LINQ can be one powerful language to work with many data sources. Functional programming can also be more scalable. For example, when working with data using LINQ, it can be very easy to parallelize the workload multiple processor cores.&lt;/p&gt;
&lt;p&gt;In C# development, object-oriented programming and functional programming live in harmony. For example, when a functional LINQ query works with data in local memory, the LINQ query actually works with CLR objects which represent the data. Also, when a LINQ query is executed, LINQ APIs are called, and the LINQ APIs can be internally implemented with imperative object-oriented programming.&lt;/p&gt;
&lt;h2&gt;This tutorial&lt;/h2&gt;
&lt;p&gt;This tutorial discusses &lt;strong&gt;cross-platform functional programming and LINQ programming via the latest C# 7.0 language, from real world development to underlying theories. It covers both .NET Framework (for Windows) and .NET Core (for Windows, macOS and Linux).&lt;/strong&gt; This entire tutorial is based on the latest language and frameworks. It covers C#’s functional features and functional programming aspects, and the detailed usage and internal mechanisms of mainstream LINQ technologies for different data domains, including LINQ to Objects, Parallel LINQ, LINQ to XML, and LINQ to Entities. It also demystifies the underlying quintessential theories of functional programming and LINQ, including Lambda Calculus and Category Theory.&lt;/p&gt;
&lt;p&gt;As an in-depth tutorial, some basic understanding of programming and C# is necessary. The target audiences are those who want to learn C# functional programming for Windows development and cross-platform development, and those who want to learn how to use LINQ in C# to work with data in applications and services. This tutorial is also for advanced audiences who want to learn the quintessence of functional programming to build a deep and general understanding, and those who want to learn internal details of LINQ in order to build custom LINQ APIs or providers.&lt;/p&gt;
&lt;p&gt;The contents are organized as the following chapters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1 Code&lt;/strong&gt; - covers functional programming via C#, and fundamentals of LINQ.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 1 Functional programming and LINQ paradigm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;What is LINQ, how LINQ uses language to work with many different data domains.&lt;/li&gt;
&lt;li&gt;Programming paradigm, imperative vs. declarative programming, object-oriented vs. functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 2 C# functional programming in-depth&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C# fundamentals for beginners.&lt;/li&gt;
&lt;li&gt;Aspects of functional programming via C#, including function type, named/anonymous/local function, closure, lambda, higher-order function, currying, partial application, first class function, function composition, query expression, covariance/contravariance, immutability, tuple, purity, async function, pattern matching, etc., including how C# is processed at compile time and runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 2 Data&lt;/strong&gt; - covers how to use functional LINQ to work with different data domains in the real world, and how LINQ works internally.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 3 LINQ to Objects&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use functional LINQ queries to work with objects, covering all LINQ and Ix.&lt;/li&gt;
&lt;li&gt;How the LINQ to Objects query methods are implemented, how to implement useful custom LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 4 LINQ to XML&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to modeling XML data, and use functional LINQ queries to work with XML data.&lt;/li&gt;
&lt;li&gt;How to use the other LINQ to XML APIs to manipulate XML data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 5 Parallel LINQ&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to use parallelized functional LINQ queries to work with objects.&lt;/li&gt;
&lt;li&gt;Performance analysis for parallel/sequential LINQ queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 6 Entity Framework/Core and LINQ to Entities&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;How to model database with object-relational mapping, and use functional LINQ queries to work with relational data in database.&lt;/li&gt;
&lt;li&gt;How the C# LINQ to Entities queries are implemented to work with database.&lt;/li&gt;
&lt;li&gt;How to change data in database, and handle concurrent conflicts.&lt;/li&gt;
&lt;li&gt;Performance tips and asynchrony.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 3 Theories&lt;/strong&gt; - demystifies the abstract mathematics theories, which are the rationale and foundations of LINQ and functional programming.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 7 Lambda Calculus via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of lambda calculus, bound and free variables, reduction (α-conversion, β-reduction, η-conversion), etc.&lt;/li&gt;
&lt;li&gt;How to use lambda functions to represent values, data structures and computation, including Church Boolean, Church numbers, Church pair, Church list, and their operations.&lt;/li&gt;
&lt;li&gt;Combinators and combinatory logic, including SKI combinator calculus, fixed point combinator for function recursion, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 8 Category Theory via C#&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Core concepts of category theory, including category, object, morphism, monoid, functor, natural transformation, applicative functor, monad, and their laws.&lt;/li&gt;
&lt;li&gt;How these concepts are applied in functional programming and LINQ.&lt;/li&gt;
&lt;li&gt;How to manage I/O, state, exception handling, shared environment, logging, and continuation, etc., in functional programming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial delivers highly reusable knowledge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It covers C# knowledge in detail, which can be generally used in any programming paradigms other than functional programming.&lt;/li&gt;
&lt;li&gt;It is a cross platform tutorial, covering both .NET Framework for Windows and .NET Core for Windows, macOS, Linux&lt;/li&gt;
&lt;li&gt;It delivers LINQ usage and implementation for mainstream data domains, which also enables developer to use the LINQ technologies for other data domains, or build custom LINQ APIs for specific data scenarios.&lt;/li&gt;
&lt;li&gt;It also demystifies the abstract mathematics knowledge for functional programming, which applies to all functional languages, so it greatly helps understanding any other functional languages too.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Code examples&lt;/h2&gt;
&lt;p&gt;All code examples are available on GitHub: &lt;a href=&quot;https://github.com/Dixin/Tutorial&quot;&gt;https://github.com/Dixin/Tutorial&lt;/a&gt;. If there is any issue, please feel free to file it here: &lt;a href=&quot;https://github.com/Dixin/Tutorial/issues/new&quot;&gt;https://github.com/Dixin/Tutorial/issues/new&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To save the space and paper, all code examples in this tutorial omit argument null check.&lt;/p&gt;
&lt;h2&gt;Author&lt;/h2&gt;
&lt;p&gt;I have been a developer for 12 years. I was a Software Development Engineer in Microsoft during 2010 - 2016. Before I join Microsoft, I was a C# MVP.&lt;/p&gt;
&lt;p&gt;I have a physics degree, and I learnt computer science by myself, so I understand it is not so that easy. In this tutorial, I try to discuss C#, LINQ, functional programming with simple words and intuitive examples.&lt;/p&gt;
&lt;h2&gt;Start coding&lt;/h2&gt;
&lt;p&gt;All tools, libraries, services involved in this tutorial are either free, or with free option available. In theory, any text editor can be used for C# programming, but a power tools can greatly improve the productivity. The following are the free tools provided by Microsoft:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx&quot;&gt;Visual Studio Community Edition&lt;/a&gt;: the free and fully featured Visual Studio for Windows, the powerful and productive flagship integrated development environment (IDE) for C#/.NET and other development.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;: the free and rich code editor for Windows, macOS and Linux, supporting coding of C# and other languages with extensions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/mac/&quot;&gt;Visual Studio for Mac&lt;/a&gt;: the free and sophisticated IDE for macOS, supporting development of .NET Core, Xamarin, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Start coding with Visual Studio (Windows)&lt;/h3&gt;
&lt;p&gt;The free Community Edition of Visual Studio can be downloaded from the Microsoft official website: &lt;a href=&quot;https://visualstudio.com/&quot;&gt;https://visualstudio.com&lt;/a&gt;. To start C# programming with .NET Core, select the “.NET Core cross-platform development” workload; To start C# programming with .NET Framework on Windows, select the “.NET desktop development” workload:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb3_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb3_thumb.png&quot; alt=&quot;image_thumb3&quot; title=&quot;image_thumb3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb2_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb2_thumb.png&quot; alt=&quot;image_thumb2&quot; title=&quot;image_thumb2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This installs Visual Studio along with .NET Framework SDK/.NET Core SDK. To install the latest version of .NET Framework SDK/.NET Core SDK, follow the steps from the Microsoft official website: &lt;a href=&quot;https://dot.net/&quot;&gt;https://dot.net&lt;/a&gt;. After all installation is done, launch Visual Studio. For .NET Core, click File =&amp;gt; New =&amp;gt; Project to create a new console application:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb7_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb7_thumb.png&quot; alt=&quot;image_thumb7&quot; title=&quot;image_thumb7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Solution Explorer, under this application, there is a Program.cs file, which has the application’s entry point Main:.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(&quot;Hello World!&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then right click the project, click Properties. In the project property window, go to the Build tab, click the Advanced button, and change the language version to latest:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb9_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb9_thumb.png&quot; alt=&quot;image_thumb9&quot; title=&quot;image_thumb9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now right click the project again, click “Manage NuGet Packages” to install the NuGet packages used in this tutorial:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FSharp.Core&lt;/li&gt;
&lt;li&gt;linqtotwitter&lt;/li&gt;
&lt;li&gt;Microsoft.Azure.DocumentDB.Core&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/li&gt;
&lt;li&gt;Microsoft.Extensions.Configuration.Json&lt;/li&gt;
&lt;li&gt;Mono.Cecil&lt;/li&gt;
&lt;li&gt;System.Interactive&lt;/li&gt;
&lt;li&gt;System.Memory&lt;/li&gt;
&lt;li&gt;System.Reflection.Emit.Lightweight&lt;/li&gt;
&lt;li&gt;System.Threading.Tasks.Extensions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb4_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb4_thumb.png&quot; alt=&quot;image_thumb4&quot; title=&quot;image_thumb4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For .NET Framework, create a console application of Windows classic desktop:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb8_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb8_thumb.png&quot; alt=&quot;image_thumb8&quot; title=&quot;image_thumb8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Change the language version to latest as well, and install the following packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ConcurrencyVisualizer&lt;/li&gt;
&lt;li&gt;EntityFramework&lt;/li&gt;
&lt;li&gt;FSharp.Core&lt;/li&gt;
&lt;li&gt;linqtotwitter&lt;/li&gt;
&lt;li&gt;Microsoft.Azure.DocumentDB&lt;/li&gt;
&lt;li&gt;Microsoft.TeamFoundationServer.ExtendedClient&lt;/li&gt;
&lt;li&gt;Mono.Cecil&lt;/li&gt;
&lt;li&gt;System.Collections.Immutable&lt;/li&gt;
&lt;li&gt;System.Interactive&lt;/li&gt;
&lt;li&gt;System.Memory&lt;/li&gt;
&lt;li&gt;System.Threading.Tasks.Extensions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then right click the created project’s References child node, click Add Reference…, add the following framework assemblies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Configuration&lt;/li&gt;
&lt;li&gt;System.Transactions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This Parallel LINQ chapter also uses a free Visual Studio extensions for .NET Framework, Concurrent Visualizer provided by Microsoft. it can be installed from Tools =&amp;gt; Extensions and Updates….&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More code files can be added under the application. Now press F5 to build, run and debug the application in Visual Studio.&lt;/p&gt;
&lt;h3&gt;Start coding with Visual Studio Code (Windows, macOS and Linux)&lt;/h3&gt;
&lt;p&gt;The free Visual Studio Code can be downloaded and installed from Microsoft official website: &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;https://code.visualstudio.com&lt;/a&gt;. This tutorial also uses 2 extensions for Visual Studio Code: C# extension for C# programming, and mssql extension for SQL execution in the LINQ to Entities chapter. These extensions are both provided by Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb5_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb5_thumb.png&quot; alt=&quot;image_thumb5&quot; title=&quot;image_thumb5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The .NET Core SDK needs to be installed separately, by following the steps from Microsoft official website: &lt;a href=&quot;https://dot.net/&quot;&gt;https://dot.net&lt;/a&gt;. The installation can be verified by the &lt;strong&gt;dotnet –version&lt;/strong&gt; command, which outputs the version of .NET Core SDK. To start coding, create a directory for a new console application, then go to this directory, run &lt;strong&gt;dotnet new console&lt;/strong&gt;. 2 files are created, Program.cs and ConsoleApp.csproj. Program.cs is the C# code file, which is the same as above Program.cs created by Visual Studio. ConsoleApp.csproj is the project file containing the metadata and build information for this console application.&lt;/p&gt;
&lt;p&gt;The NuGet packages used by this tutorial can be added with the &lt;strong&gt;dotnet add package {package name}&lt;/strong&gt; command. For the packages only available as preview, the version has to be specified: &lt;strong&gt;dotnet add package {package name} –version {version}&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;From this directory, run code . command to start Visual Studio Code. Visual Studio Code should prompt “Required assets to build and debug are missing from ‘ConsoleApp’. Add them?”. Click Yes, Visual Studio Code should create the debug configuration files in a .vscode subdirectory. Now, press F5 to build, run and debug the application in Visual Studio Code.&lt;/p&gt;
&lt;h3&gt;Start coding with Visual Studio for Mac (macOS)&lt;/h3&gt;
&lt;p&gt;The free Visual Studio for Mac can be downloaded and installed from Microsoft official website: &lt;a href=&quot;https://www.visualstudio.com/vs/visual-studio-mac&quot;&gt;https://www.visualstudio.com/vs/visual-studio-mac&lt;/a&gt;. Then launch Visual Studio for Mac, click New Project button on the welcome page to create a new .NET Core console application:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb12_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb12_thumb.png&quot; alt=&quot;image_thumb12&quot; title=&quot;image_thumb12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project, click Options. In the opened project options window, click the General tab under Build, change the language version to latest:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb11_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb11_thumb.png&quot; alt=&quot;image_thumb11&quot; title=&quot;image_thumb11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then right click the created project’s Dependencies child node, click Add Packages, install the fore mentioned NuGet packages:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb13_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Functional-Programmin.NETCore-C-and-LINQ_14FDE/image_thumb13_thumb.png&quot; alt=&quot;image_thumb13&quot; title=&quot;image_thumb13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, just press F5 to build, run and debug the code in Visual Studio for Mac.&lt;/p&gt;
</content:encoded></item><item><title>Remote desktop connection authentication error due to CredSSP encryption oracle remediation</title><link>https://dixin.github.io/posts/remote-desktop-connection-authentication-error-due-to-credssp-encryption-oracle-remediation/</link><guid isPermaLink="true">https://dixin.github.io/posts/remote-desktop-connection-authentication-error-due-to-credssp-encryption-oracle-remediation/</guid><description>Recently, when connecting to another Windows machine with RD, I got the following RDP authentication error due to CredSSP encryption oracle remediation:</description><pubDate>Sun, 13 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, when connecting to another Windows machine with RD, I got the following RDP authentication error due to CredSSP encryption oracle remediation:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An authentication error has occurred. The function requested is not supported&lt;/p&gt;
&lt;p&gt;Remote computer: &amp;lt;computer name&amp;gt; This could be due to CredSSP encryption oracle remediation. For more information, see https:/go.microsoft.com/fwlink/?linkid=866660&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Windows client&lt;/h2&gt;
&lt;p&gt;Following the above link, and searching around, this seems caused by the client Windows is patched with a CredSSP (Credential Security Support Provider protocol) update for &lt;a href=&quot;https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2018-0886&quot;&gt;CVE-2018-0886&lt;/a&gt;, while the remote Windows is not. The solution is certainly patching the remote Windows. However, if you do not have the permission to patch the remote Windows (In this case, I am connecting to a build VM provided by AppVeyor), then you have to compromise the client.&lt;/p&gt;
&lt;h3&gt;Windows Pro Edition (with group policy editor)&lt;/h3&gt;
&lt;p&gt;The workable solution I found is to edit client Windows’ local group policy (gpedit.msc):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Under Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; Credentials Delegation, there is a setting “Encryption Oracle Remediation”. Its default value is “Not configured”. Just change it to “Enabled”, and set “Protection Level” as “Vulnerable”.&lt;/p&gt;
&lt;p&gt;Windows 10:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Windows 7:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now your remote desktop should be able to connect. Remember to revert the setting after you are done.&lt;/p&gt;
&lt;h3&gt;Windows Home Edition client (without above option)&lt;/h3&gt;
&lt;p&gt;If your Windows client does not have group policy editor or above “Oracle Remediation” option (like Windows Home Edition), then you can temporarily uninstall the security update patch in May 2018, KB41037XX:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on Windows 10 17134.48, it is KB4103721 : &lt;a href=&quot;https://support.microsoft.com/en-au/help/4103721/windows-10-update-kb4103721&quot;&gt;https://support.microsoft.com/en-au/help/4103721/windows-10-update-kb4103721&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;on Windows 10 16299.431, it is KB4103727: &lt;a href=&quot;https://support.microsoft.com/en-us/help/4103727/windows-10-update-kb4103727&quot;&gt;https://support.microsoft.com/en-us/help/4103727/windows-10-update-kb4103727&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;On Windows 7 it is KB4103718: &lt;a href=&quot;https://support.microsoft.com/en-us/help/4103718/windows-7-update-kb4103718&quot;&gt;https://support.microsoft.com/en-us/help/4103718/windows-7-update-kb4103718&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Windows 10:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Windows 7:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember to reinstall it when you are done.&lt;/p&gt;
&lt;h2&gt;Windows server&lt;/h2&gt;
&lt;p&gt;In the comment area, @Rome mentioned that, on server side, this can be mitigated by disabling “Allow connections only from computers running Remote Desktop with Network Level Authentication (recommended)” in server’s system properties.&lt;/p&gt;
&lt;p&gt;Windows Server 2016:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Remote-desktop-connection-authentication_1CE9/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I strongly suggest not to compromise the server-side security, but mitigate it from client Windows temporarily. You should patch the server-side or ask server administrator to patch it.&lt;/p&gt;
</content:encoded></item><item><title>End-to-end: Setup PHP Debugging for Visual Studio Code on Windows</title><link>https://dixin.github.io/posts/setup-php-debugging-for-visual-studio-code-on-windows/</link><guid isPermaLink="true">https://dixin.github.io/posts/setup-php-debugging-for-visual-studio-code-on-windows/</guid><description>This is a quick tutorial of minimum installation and configurations of development environment for PHP programming, including Apache, PHP, and Visual Studio Code (VSCode) on 64 bit Windows.</description><pubDate>Sat, 07 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is a quick tutorial of minimum installation and configurations of development environment for PHP programming, including Apache, PHP, and Visual Studio Code (VSCode) on 64 bit Windows.&lt;/p&gt;
&lt;h2&gt;Prerequisite&lt;/h2&gt;
&lt;p&gt;Check if Visual C++ 2015 Redistributable (x64) or higher version is installed for Windows.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_7.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If not, install it from Microsoft &lt;a href=&quot;https://www.visualstudio.com/downloads/&quot;&gt;https://www.visualstudio.com/downloads/&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup Apache&lt;/h2&gt;
&lt;p&gt;Go to Apache website: &lt;a href=&quot;https://httpd.apache.org/docs/current/platform/windows.html#down&quot;&gt;https://httpd.apache.org/docs/current/platform/windows.html#down&lt;/a&gt;, and download the Windows version, for example, httpd-2.4.25-win64-VC14.zip.&lt;/p&gt;
&lt;p&gt;Extract the files to a folder, for example, D:\Software\Apache.&lt;/p&gt;
&lt;p&gt;Then go to the Apache installation directory, under conf directory, open httpd.conf file, replace all “&lt;strong&gt;c:/Apache24&lt;/strong&gt;” strings with relative path “&lt;strong&gt;..&lt;/strong&gt;”.&lt;/p&gt;
&lt;h2&gt;Setup PHP&lt;/h2&gt;
&lt;p&gt;Go to PHP website: &lt;a href=&quot;http://windows.php.net/download&quot;&gt;http://windows.php.net/download&lt;/a&gt;, download the Windows version, for example, VC14 x64 Thread Safe.&lt;/p&gt;
&lt;p&gt;Extract the files to a folder, for example, D:\Software\Php.&lt;/p&gt;
&lt;p&gt;Go to the PHP directory, copy the php.ini-development file, and paste as php.ini.&lt;/p&gt;
&lt;p&gt;Open the file,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uncomment &lt;strong&gt;; extension_dir = &quot;ext&quot;&lt;/strong&gt;, and replace with relative path &lt;strong&gt;extension_dir = &quot;..\..\Php\ext&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enable the extensions, like curl, gd2, mbstring, sockets, etc., by comment the configurations, like &lt;strong&gt;extension=php_curl.dll&lt;/strong&gt;, etc.&lt;/li&gt;
&lt;li&gt;Replace the temporary directory “&lt;strong&gt;..\tmp&lt;/strong&gt;” with the correct path, for example “&lt;strong&gt;..\..\Temp\Php&lt;/strong&gt;”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go back to Apache’s conf/httpd.conf file,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add &lt;strong&gt;LoadModule php7_module &quot;../Php/php7apache2_4.dll&quot;&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;add &lt;strong&gt;AddType application/x-httpd-php .php&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;add &lt;strong&gt;PHPIniDir ../php&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Setup XDebug&lt;/h3&gt;
&lt;p&gt;Go to XDebug website: &lt;a href=&quot;https://xdebug.org/download.php&quot;&gt;https://xdebug.org/download.php&lt;/a&gt;, download the Windows version, for example, PHP 7.1 VC14 TS (64 bit) in this case.&lt;/p&gt;
&lt;p&gt;Extract the single file to PHP extensions directory, for example, D:\Software\Php\ext\php_xdebug-2.5.4-7.1-vc14-x86_64.dll in this case.&lt;/p&gt;
&lt;p&gt;Go to php.ini, add relative path of XDebug, for example, &lt;strong&gt;zend_extension = ..\..\Php\ext\php_xdebug-2.5.4-7.1-vc14-x86_64.dll&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Setup Visual Studio Code&lt;/h2&gt;
&lt;p&gt;Go to Visual Studio Code website: &lt;a href=&quot;https://code.visualstudio.com&quot;&gt;https://code.visualstudio.com&lt;/a&gt;, install Visual Studio Code.&lt;/p&gt;
&lt;p&gt;Launch Visual Studio Code, install the PHP Debug extension: &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug&quot;&gt;https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go to the settings, change the &quot;&lt;strong&gt;php.validate.executablePath&lt;/strong&gt;&quot; item to PHP binary path, for example, &quot;&lt;strong&gt;D:\\Software\\Php\\php.exe&lt;/strong&gt;&quot;.&lt;/p&gt;
&lt;h2&gt;Setup Website&lt;/h2&gt;
&lt;p&gt;Go to Apache’s conf/httpd.conf,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set the port, for example, change &lt;strong&gt;Listen 80&lt;/strong&gt; to &lt;strong&gt;Listen 81&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Uncomment server name, for example &lt;strong&gt;ServerName localhost:81&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Set document root to website directory, for example, change &lt;strong&gt;DocumentRoot &quot;c:/Apache24/htdocs&quot;&lt;/strong&gt; to &lt;strong&gt;DocumentRoot &quot;../../../Code/Website&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Change &lt;strong&gt;&amp;lt;Directory &quot;c:/Apache24/htdocs&quot;&amp;gt;&lt;/strong&gt; to the website directory too &lt;strong&gt;&amp;lt;Directory &quot;../../../Code/Website&quot;&amp;gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Inside &lt;strong&gt;&amp;lt;Directory /&amp;gt;&lt;/strong&gt;, change &lt;strong&gt;Require all denied&lt;/strong&gt; to &lt;strong&gt;Require all granted&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add index.php as directory index, by changing &lt;strong&gt;DirectoryIndex index.html&lt;/strong&gt; to &lt;strong&gt;DirectoryIndex index.php index.html&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In command line, run D:\Software\Apache\bin\httpd.exe.&lt;/p&gt;
&lt;p&gt;Open the website directory with Visual Studio Code, create a file index.php with one line of code: &lt;strong&gt;&amp;lt;?php phpinfo(); ?&amp;gt;&lt;/strong&gt;, add a break point. Press F5 to start debugging.&lt;/p&gt;
&lt;p&gt;Open the website in browser: &lt;a href=&quot;http://localhost:81&quot;&gt;http://localhost:81&lt;/a&gt;, the index.php is executed, and the break point is triggered in Visual Studio Code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Setup-PHP-for-Visual-Studio-Code-on-Wind_12515/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Port Microsoft Concurrency Visualizer SDK to .NET Standard and NuGet</title><link>https://dixin.github.io/posts/port-microsoft-concurrency-visualizer-sdk-to-net-standard-and-nuget-2017/</link><guid isPermaLink="true">https://dixin.github.io/posts/port-microsoft-concurrency-visualizer-sdk-to-net-standard-and-nuget-2017/</guid><description>I uploaded a NuGet package of Microsoft Concurrency Visualizer SDK: . [Microsoft Concurrency Visualizer](https://docs.micr</description><pubDate>Wed, 04 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I uploaded a NuGet package of Microsoft Concurrency Visualizer SDK: &lt;a href=&quot;https://www.nuget.org/packages/ConcurrencyVisualizer/&quot;&gt;ConcurrencyVisualizer&lt;/a&gt;. &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/profiling/concurrency-visualizer&quot;&gt;Microsoft Concurrency Visualizer&lt;/a&gt; is an extension tool for Visual Studio. It is a great tool for performance profiling and multithreading execution visualization. It also has a &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/profiling/concurrency-visualizer-sdk&quot;&gt;SDK library&lt;/a&gt; to be invoked by code and draw markers and spans in the timeline. I used it to visualize sequential LINQ and Parallel LINQ (PLINQ) execution in my Functional Programming and LINQ tutorials. For example, array.Where(…).Select(…) sequential LINQ query and array.AsParallel().Where(…).Select(…) Parallel LINQ query can be visualized as following spans:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb11_thumb%5B6%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb11_thumb%5B6%5D_thumb.png&quot; alt=&quot;image_thumb11_thumb[6]&quot; title=&quot;image_thumb11_thumb[6]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Concurrency Visualizer is available in Visual Studio Marketplace:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb%5B4%5D_thumb.png&quot; alt=&quot;image_thumb[4]&quot; title=&quot;image_thumb[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the SDK library is available for .NET Framework, and can be installed from menu item:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb1%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb1%5B4%5D_thumb.png&quot; alt=&quot;image_thumb1[4]&quot; title=&quot;image_thumb1[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This adds a reference to local assembly C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\4hhyuhoo.ghy\SDK\Managed\4.0\Microsoft.ConcurrencyVisualizer.Markers.dll. For your convenience, I have made a NuGet package:&lt;/p&gt;
&lt;p&gt;Install-Package ConcurrencyVisualizer&lt;/p&gt;
&lt;p&gt;It makes your code more potable. I have also ported the code to .NET Standard, so now the SDK can work with .NET Framework, .NET Core, etc.:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb2%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb2%5B4%5D_thumb.png&quot; alt=&quot;image_thumb2[4]&quot; title=&quot;image_thumb2[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now the Concurrency Visualizer tool can visualize markers and spans of .NET Core correctly.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb4_thumb%5B4%5D.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Open-Live-Writer/Port-Microsoft-Co.NET-Standard-and-NuGet_E96/image_thumb4_thumb%5B4%5D_thumb.png&quot; alt=&quot;image_thumb4_thumb[4]&quot; title=&quot;image_thumb4_thumb[4]&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (4) Query Methods</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-4-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-4-query-methods/</guid><description>This part discusses how to query SQL database with the defined mapping classes. Entity Framework and LINQ to Entities supports most of the extension methods provided by Queryable class:</description><pubDate>Tue, 31 May 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-4-query-methods&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-4-query-methods&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This part discusses how to query SQL database with the defined mapping classes. Entity Framework and LINQ to Entities supports most of the extension methods provided by Queryable class:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Return a new IQueryable&amp;lt;T&amp;gt; source:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Generation: DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Filtering (restriction): Where, OfType&lt;/li&gt;
&lt;li&gt;Mapping (projection): Select&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Join: Join, GroupJoin, SelectMany, Select&lt;/li&gt;
&lt;li&gt;Apply: GroupBy, GroupJoin, Select&lt;/li&gt;
&lt;li&gt;Concatenation: Concat&lt;/li&gt;
&lt;li&gt;Set: Distinct, GroupBy, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Convolution: ~Zip~&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, ~TakeWhile~, ~SkipWhile~&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, ~Reverse~&lt;/li&gt;
&lt;li&gt;Conversion: Cast, AsQueryable&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Return a single value:
&lt;ul&gt;
&lt;li&gt;Element: First, FirstOrDefault, ~Last~, ~LastOrDefault~, ~ElementAt~, ~ElementAtOrDefault~, Single, SingleOrDefault&lt;/li&gt;
&lt;li&gt;Aggregation: ~Aggregate~, Count, LongCount, Min, Max, Sum, Average&lt;/li&gt;
&lt;li&gt;Quantifier: All, Any, Contains&lt;/li&gt;
&lt;li&gt;Equality: ~SequenceEqual~&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If a Queryable method has no proper target SQL translation, this method is not supported by LINQ to Entities. Query with such a methods will result NotSupportedException. In above list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The crossed methods are not supported (&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb738550.aspx&quot;&gt;the list in MDSN&lt;/a&gt; is not up to date), because there is no general translation to SQL, e.g. SQL database has no built-in Zip operation, etc..&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The underlined methods have some overloads not supported:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For GroupBy, Join, GroupJoin, Distinct, Union, Intersect, Except, Contains, the overloads with IEqualityComparer&amp;lt;T&amp;gt; parameter are not supported, because apparently IEqualityComparer&amp;lt;T&amp;gt; has no equivalent SQL translation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For OrderBy, ThenBy, OrderByDescending, ThenByDescending, the overloads with IComparer&amp;lt;T&amp;gt; parameter are not supported&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For Where, Select, SelectMany, the indexed overloads are not supported&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this part, all the LINQ to Entities queries will be demonstrated with query methods. All kinds of LINQ queries share the same query expression pattern, which has been discussed in detail in the LINQ to Objects chapter. Here query expressions will only be demonstrated for join queries, where they may be more intuitive than query methods.&lt;/p&gt;
&lt;p&gt;Here, to make the code shorter, one database object will be reused for all the queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class QueryMethods
{
    private static readonly AdventureWorks AdventureWorks = new AdventureWorks();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In reality, a DbContext object should always be constructed and disposed for each &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Return a new IQueryable&amp;lt;T&amp;gt; source&lt;/h2&gt;
&lt;p&gt;Just like all the other kinds of LINQ, LINQ to Entities implements deferred execution for these query methods. The SQL query is translated and executed only when the values are pulled from IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Generation&lt;/h3&gt;
&lt;p&gt;As fore mentioned, DefaultIfEmpty is the only generation method provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmpty()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.DefaultIfEmpty(); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category?.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When ForEach is called, the query is translated to SQL and executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
    LEFT OUTER JOIN [Production].[ProductCategory] AS [Extent1] ON 1 = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The OUTER JOIN ON 1 = 1 from a single row table guarantees that the SQL query result has at least 1 row. If the right table of JOIN has rows, the JOIN results is the rows; otherwise, the JOIN result will be 1 row, where each column is NULL.&lt;/p&gt;
&lt;p&gt;The other DefaultIfEmpty overload accepts a specified default value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyWithPrimitive()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;int&amp;gt; categories = source
        .Select(category =&amp;gt; category.ProductCategoryID)
        .DefaultIfEmpty(-1); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translation checks if the JOIN result is NULL. If so, the specified default value –1 is used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    CASE WHEN ([Project1].[C1] IS NULL) THEN -1 ELSE [Project1].[ProductCategoryID] END AS [C1]
    FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
    LEFT OUTER JOIN  (SELECT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        cast(1 as tinyint) AS [C1]
        FROM [Production].[ProductCategory] AS [Extent1] ) AS [Project1] ON 1 = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This overload and its translation works for a single column. It throws NotSupportedException for entity type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DefaultIfEmptyWithEntity()
{
    ProductCategory defaultCategory = new ProductCategory();
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.DefaultIfEmpty(defaultCategory); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category?.Name)); // Execute query.
    // NotSupportedException: Unable to create a constant value of type &apos;Dixin.Linq.EntityFramework.ProductCategory&apos;. Only primitive types or enumeration types are supported in this context.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DefaultIfEmpty can also be used to implement outer join, which will be discussed soon.&lt;/p&gt;
&lt;h3&gt;Filtering (restriction)&lt;/h3&gt;
&lt;p&gt;Entity Framework translates Queryable.Where to SQL WHERE clause. And the predicate expression tree (again, not predicate function in Enumerable.Where) is translated to the condition in WHERE clause&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Where()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# || operator in the predicate expression tree is translated to SQL OR operator in WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithOr()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;
        category.ProductCategoryID &amp;lt;= 1 || category.ProductCategoryID &amp;gt;= 4); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE ([Extent1].[ProductCategoryID] &amp;lt;= 1) OR ([Extent1].[ProductCategoryID] &amp;gt;= 4)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# &amp;amp;&amp;amp; operator is translated to SQL AND operator. Also, multiple Where calls are translated to one single WHERE clause with AND too&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithAnd()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source.Where(category =&amp;gt;
        category.ProductCategoryID &amp;gt; 0 &amp;amp;&amp;amp; category.ProductCategoryID &amp;lt; 5); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
}

internal static void WhereAndWhere()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; categories = source
        .Where(category =&amp;gt; category.ProductCategoryID &amp;gt; 0)
        .Where(category =&amp;gt; category.ProductCategoryID &amp;lt; 5); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 LINQ to Entities queries are translated to identical SQL queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE ([Extent1].[ProductCategoryID] &amp;gt; 0) AND ([Extent1].[ProductCategoryID] &amp;lt; 5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other filtering method, OfType, is equivalent to Where with is operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereWithIs()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; products = source.Where(product =&amp;gt; product is UniversalProduct); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.GetType().Name}&quot;)); // Execute query.
    // NotSupportedException: Method &apos;Boolean IsNullOrEmpty(System.String)&apos; has no supported translation to SQL.
}

internal static void OfTypeWithEntiy()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;UniversalProduct&amp;gt; products = source.OfType&amp;lt;UniversalProduct&amp;gt;(); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.GetType().Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Where and OfType queries are both translated to WHERE:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    &apos;0X0X&apos; AS [C1], 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[RowVersion] AS [RowVersion], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ListPrice] AS [ListPrice], 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    FROM [Production].[Product] AS [Extent1]
    WHERE [Extent1].[Style] = N&apos;U&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OfType works for entity type. It throws NotSupportedException for primitive type representing a single column:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OfTypeWithPromitive()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;int&amp;gt; products = source.Select(p =&amp;gt; p.ProductID).OfType&amp;lt;int&amp;gt;(); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
    // NotSupportedException: &apos;System.Int32&apos; is not a valid metadata type for type filtering operations. Type filtering is only valid on entity types and complex types.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Mapping (projection)&lt;/h3&gt;
&lt;p&gt;In above queries, Queryable.Select is not called, so the translated SELECT clause contains all the mapped columns to construct the entity objects; if Select is called, the selector expression tree is translated to specified columns in SELECT clause. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Select()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;string&amp;gt; categories = source.Select(category =&amp;gt; 
        category.Name + category.Name); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category)); // Execute query.
}

internal static void SelectWithStringConcat()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;string&amp;gt; categories = source.Select(category =&amp;gt;
        string.Concat(category.Name, category.Name)); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(category)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 queries are semantically equivalent. The C# + operator and string.Concat method are both translated to SQL + operator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[Name] + [Extent1].[Name] AS [C1]
    FROM [Production].[ProductCategory] AS [Extent1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Select supports Anonymous type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAnonymousType()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source.Select(product =&amp;gt;
        new { Name = product.Name, IsExpensive = product.ListPrice &amp;gt; 1000, Constant = 1 }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [Extent1].[Name] AS [Name], 
    CASE 
        WHEN ([Extent1].[ListPrice] &amp;gt; cast(1000 as decimal(18))) THEN cast(1 as bit) 
        WHEN ( NOT ([Extent1].[ListPrice] &amp;gt; cast(1000 as decimal(18)))) THEN cast(0 as bit) 
    END AS [C2]
    FROM [Production].[Product] AS [Extent1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Grouping&lt;/h3&gt;
&lt;p&gt;The following is a simple GroupBy example, :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupBy()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;IGrouping&amp;lt;int, string&amp;gt;&amp;gt; groups = source.GroupBy(
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        subcategory =&amp;gt; subcategory.Name); // Define query.
    groups.ForEach(group =&amp;gt; Trace.WriteLine($&quot;{group.Key}: {string.Join(&quot;, &quot;, group)}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above GroupBy query is translated to LEFT OUTER JOIN instead of GROUP BY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project2].[ProductCategoryID] AS [ProductCategoryID], 
    [Project2].[C1] AS [C1], 
    [Project2].[Name] AS [Name]
    FROM ( SELECT 
        [Distinct1].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent2].[Name] AS [Name], 
        CASE WHEN ([Extent2].[ProductCategoryID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM   (SELECT DISTINCT 
            [Extent1].[ProductCategoryID] AS [ProductCategoryID]
            FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
        LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
    )  AS [Project2]
    ORDER BY [Project2].[ProductCategoryID] ASC, [Project2].[C1] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because above GroupBy returns hierarchical result (collection of groups, and each group is a collection of values), but SQL query can only result table of rows. So here is how it works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The translated SQL has to first query all the keys with a SELECT DISTINCT query&lt;/li&gt;
&lt;li&gt;Then it has the keys to LEFT OUTER JOIN all the rows. The join result is a table of all group key and group value pairs (ProductCategoryID and Name pairs)&lt;/li&gt;
&lt;li&gt;Then it sorts all the group key and group value pairs by the group keys, to make sure in the final result, the values appears group by group.&lt;/li&gt;
&lt;li&gt;Eventually Entity Framework transforms the SQL result table into .NET hierarchical data structure, a IQueryable&amp;lt;T&amp;gt; collection of IGrouping&amp;lt;T&amp;gt; collections.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To implement SQL GROUP BY query, just have the GroupBy query to return flattened result (collection of values). This can be done with a GroupBy overload accepting a resultSelector, or equivalently, an additional Select query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByWithResultSelector()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var groups = source.GroupBy(
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        subcategory =&amp;gt; subcategory.Name,
        (key, group) =&amp;gt; new { CategoryID = key, SubcategoryCount = group.Count() }); // Define query.
    groups.ForEach(group =&amp;gt; Trace.WriteLine($&quot;{group.CategoryID}: {group.SubcategoryCount}&quot;)); // Execute query.
}

internal static void GroupByAndSelect()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var groups = source
        .GroupBy(
            subcategory =&amp;gt; subcategory.ProductCategoryID,
            subcategory =&amp;gt; subcategory.Name)
        .Select(group =&amp;gt; new { CategoryID = group.Key, SubcategoryCount = group.Count() }); // Define query.
    groups.ForEach(group =&amp;gt; Trace.WriteLine($&quot;{group.CategoryID}: {group.SubcategoryCount}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice aggregate query method Count is called to flattening the result. These 2 queries are semantically equivalent. They are both translated to identical GROUP BY query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [GroupBy1].[K1] AS [ProductCategoryID], 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        [Extent1].[ProductCategoryID] AS [K1], 
        COUNT(1) AS [A1]
        FROM [Production].[ProductSubcategory] AS [Extent1]
        GROUP BY [Extent1].[ProductCategoryID]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SelectMany can also flatten hierarchical result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByAndSelectMany()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; distinct = source
        .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID)
        .SelectMany(group =&amp;gt; group); // Define query.
    distinct.ForEach(subcategory =&amp;gt; Trace.WriteLine(subcategory.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time no aggregate method is called, so above query cannot be translated to GROUP BY. It is translated to INNER JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Extent2].[Name] AS [Name], 
    [Extent2].[ProductCategoryID] AS [ProductCategoryID]
    FROM   (SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    INNER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupBy’s keySelector can return anonymous type to support multiple keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void GroupByMultipleKeys()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var groups = source.GroupBy(
        product =&amp;gt; new { ProductSubcategoryID = product.ProductSubcategoryID, ListPrice = product.ListPrice },
        (key, group) =&amp;gt; new
        {
            ProductSubcategoryID = key.ProductSubcategoryID,
            ListPrice = key.ListPrice,
            Count = group.Count()
        }); // Define query.
    groups.ForEach(group =&amp;gt; Trace.WriteLine(
        $&quot;{group.ProductSubcategoryID}, {group.ListPrice}: {group.Count}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key’s properties are translated to keys in GROUP BY clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [GroupBy1].[K2] AS [ProductSubcategoryID], 
    [GroupBy1].[K1] AS [ListPrice], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
        [Extent1].[ListPrice] AS [K1], 
        [Extent1].[ProductSubcategoryID] AS [K2], 
        COUNT(1) AS [A1]
        FROM [Production].[Product] AS [Extent1]
        GROUP BY [Extent1].[ListPrice], [Extent1].[ProductSubcategoryID]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Join&lt;/h3&gt;
&lt;h3&gt;Inner join&lt;/h3&gt;
&lt;p&gt;Besides above GroupBy, as discussed in the LINQ to Objects chapter, inner join can be done with Join and SelectMany. The following examples simply join the ProductSubcategory and ProductCategory entities with their ProductCategoryID properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithJoin()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories = outer.Join(
        inner,
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        category =&amp;gt; category.ProductCategoryID,
        (subcategory, category) =&amp;gt; new { Subcategory = subcategory.Name, Category = category.Name }); // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}

internal static void InnerJoinWithSelectMany()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories = outer
        .SelectMany(
            subcategory =&amp;gt; inner,
            (subcategory, category) =&amp;gt; new { Subcategory = subcategory, Category = category })
        .Where(crossJoinValue =&amp;gt;
            crossJoinValue.Subcategory.ProductCategoryID == crossJoinValue.Category.ProductCategoryID)
        .Select(crossJoinValue =&amp;gt;
            new { Subcategory = crossJoinValue.Subcategory.Name, Category = crossJoinValue.Category.Name }); // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And their query expression versions are similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithJoin()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories =
        from subcategory in outer
        join category in inner
        on subcategory.ProductCategoryID equals category.ProductCategoryID
        select new { Subcategory = subcategory.Name, Category = category.Name }; // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}

internal static void InnerJoinWithSelectMany()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories =
        from subcategory in outer
        from category in inner
        where subcategory.ProductCategoryID == category.ProductCategoryID
        select new { Subcategory = subcategory.Name, Category = category.Name }; // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inner join can be translated from GroupJoin and Select too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithGroupJoin()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories = outer
        .GroupJoin(
            inner,
            subcategory =&amp;gt; subcategory.ProductCategoryID,
            category =&amp;gt; category.ProductCategoryID,
            (subcategory, categories) =&amp;gt; new { Subcategory = subcategory, Categories = categories })
        .SelectMany(
            subcategory =&amp;gt; subcategory.Categories, // LEFT OUTER JOIN if DefaultIfEmpty is called.
            (subcategory, category) =&amp;gt;
                new { Subcategory = subcategory.Subcategory.Name, Category = category.Name }); // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}

internal static void InnerJoinWithSelect()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var categories = outer
        .Select(subcategory =&amp;gt; new
        {
            Subcategory = subcategory,
            Categories = inner.Where(category =&amp;gt; category.ProductCategoryID == subcategory.ProductCategoryID)
        })
        .SelectMany(
            subcategory =&amp;gt; subcategory.Categories, // LEFT OUTER JOIN if DefaultIfEmpty is called.
            (subcategory, category) =&amp;gt;
                new { Subcategory = subcategory.Subcategory.Name, Category = category.Name }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here GroupJoin and Select returns hierarchical result, collection of collections, so SelectMany is called to flatten it to collection of values. Their query expression versions are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithGroupJoin()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories =
        from subcategory in outer
        join category in inner
        on subcategory.ProductCategoryID equals category.ProductCategoryID into categories
        from category in categories // LEFT OUTER JOIN if DefaultIfEmpty is called.
        select new { Subcategory = subcategory.Name, Category = category.Name }; // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}

internal static void InnerJoinWithSelect()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var categories =
        from subcategory in outer
        select new
        {
            Subcategory = subcategory,
            Categories = from category in inner
                         where category.ProductCategoryID == subcategory.ProductCategoryID
                         select category
        } into subcategory
        from category in subcategory.Categories // LEFT OUTER JOIN if DefaultIfEmpty is called.
        select new { Subcategory = subcategory.Subcategory.Name, Category = category.Name }; // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the ProductCategory and ProductSubCategory entities are associated, also inner join can be implemented by the navigation property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithAssociation()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    var subcategories = outer.Select(subcategory =&amp;gt;
        new { Subcategory = subcategory.Name, Category = subcategory.ProductCategory.Name }); // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the above queries are translated to the same INNER JOIN query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent2].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [Production].[ProductSubcategory] AS [Extent1]
    INNER JOIN [Production].[ProductCategory] AS [Extent2] ON [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, navigation property is the easiest way for join query, as long as the entities are associated. The following example inner joins 3 entities, Product, ProductProductPhoto, ProductPhoto:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void MultipleInnerJoinsWithAssociations()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source.SelectMany(
        product =&amp;gt; product.ProductProductPhotos,
        (product, productProductPhoto) =&amp;gt; new
        {
            Product = product.Name,
            Photo = productProductPhoto.ProductPhoto.LargePhotoFileName
        }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Product}: {product.Photo}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to multiple INNER JOINs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[Name] AS [Name], 
    [Extent3].[LargePhotoFileName] AS [LargePhotoFileName]
    FROM   [Production].[Product] AS [Extent1]
    INNER JOIN [Production].[ProductProductPhoto] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
    INNER JOIN [Production].[ProductPhoto] AS [Extent3] ON [Extent2].[ProductPhotoID] = [Extent3].[ProductPhotoID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If above query is implemented by Join with keys, or by SelectMany with keys, then multiple Join or SelectMany calls are needed.&lt;/p&gt;
&lt;p&gt;Just like LINQ to Objects, to join with multiple keys, have the outerKeySelector and innerKeySelector return anonymous type. The following example joins the ProductSubcategory and ProductCategory entities with their ProductCategoryID properties, and their Name properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void InnerJoinWithMultipleKeys()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; outer = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;ProductCategory&amp;gt; inner = AdventureWorks.ProductCategories;
    var subcategories = outer.Join(
        inner,
        subcategory =&amp;gt;
            new { ProductCategoryID = subcategory.ProductCategoryID, Name = subcategory.Name },
        category =&amp;gt;
            new { ProductCategoryID = category.ProductCategoryID, Name = category.Name },
        (subcategory, category) =&amp;gt; new { Subcategory = subcategory.Name, Category = category.Name }); // Define query.
    subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine($&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The anonymous type’s properties is translated to keys of join:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [Production].[ProductSubcategory] AS [Extent1]
    INNER JOIN [Production].[ProductCategory] AS [Extent2] ON ([Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]) AND ([Extent1].[Name] = [Extent2].[Name]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Left outer join&lt;/h3&gt;
&lt;p&gt;Left outer join can be done with GroupJoin and Select. The following examples joins ProductCategory and ProductSubcategory entities with their ProductCategoryID properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoin()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer.GroupJoin(
        inner,
        category =&amp;gt; category.ProductCategoryID,
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        (category, subcategories) =&amp;gt; new
        {
            Category = category.Name,
            Subcategories = subcategories.Select(subcategory =&amp;gt; subcategory.Name)
        }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {string.Join(&quot;, &quot;, category.Subcategories)}&quot;)); // Execute query.
}

internal static void LeftOuterJoinWithSelect()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer
        .Select(category =&amp;gt; new
        {
            Category = category.Name,
            Subcategories = inner
                .Where(subcategory =&amp;gt; subcategory.ProductCategoryID == category.ProductCategoryID)
                .Select(subcategory =&amp;gt; subcategory.Name)
        }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {string.Join(&quot;, &quot;, category.Subcategories)}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their query expression versions are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoin()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories =
        from category in outer
        join subcategory in inner
        on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories
        select new
        {
            Category = category.Name,
            Subcategories = subcategories.Select(subcategory =&amp;gt; subcategory.Name)
        }; // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {string.Join(&quot;, &quot;, category.Subcategories)}&quot;)); // Execute query.
}

internal static void LeftOuterJoinWithSelect()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories =
        from category in outer
        select new
        {
            Category = category,
            Subcategories = from subcategory in inner
                            where subcategory.ProductCategoryID == category.ProductCategoryID
                            select subcategory
        }; // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {string.Join(&quot;, &quot;, category.Subcategories)}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above GroupJoin and Select returns hierarchical result, so they are both translated to the same pattern as the first GroupBy example above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[ProductCategoryID] AS [ProductCategoryID], 
    [Project1].[Name] AS [Name], 
    [Project1].[C1] AS [C1], 
    [Project1].[Name1] AS [Name1]
    FROM ( SELECT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent1].[Name] AS [Name], 
        [Extent2].[Name] AS [Name1], 
        CASE WHEN ([Extent2].[ProductCategoryID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM  [Production].[ProductCategory] AS [Extent1]
        LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
    )  AS [Project1]
    ORDER BY [Project1].[ProductCategoryID] ASC, [Project1].[C1] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement a simple left outer join query, just call SelectMany to flatten the hierarchical result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoinAndSelectMany()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer
        .GroupJoin(
            inner,
            category =&amp;gt; category.ProductCategoryID,
            subcategory =&amp;gt; subcategory.ProductCategoryID,
            (category, subcategories) =&amp;gt; new { Category = category, Subcategories = subcategories })
        .SelectMany
            (category =&amp;gt; category.Subcategories.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}

internal static void LeftOuterJoinWithSelectAndSelectMany()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer
        .Select(category =&amp;gt; new
        {
            Category = category,
            Subcategories = inner
                .Where(subcategory =&amp;gt; subcategory.ProductCategoryID == category.ProductCategoryID)
        })
        .SelectMany(
            category =&amp;gt; category.Subcategories.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
            (category, subcategory) =&amp;gt;
                new { Category = category.Category.Name, Subcategory = subcategory.Name }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice DefaultIfEmpty must be called in SelectMany, otherwise the queries become inner join. And their query expression versions are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithGroupJoinAndSelectMany()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories =
        from category in outer
        join subcategory in inner
        on category.ProductCategoryID equals subcategory.ProductCategoryID into subcategories
        from subcategory in subcategories.DefaultIfEmpty() // INNER JOIN if DefaultIfEmpty is missing.
        select new { Category = category.Name, Subcategory = subcategory.Name }; // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}

internal static void LeftOuterJoinWithSelectAndSelectMany()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories =
        from category in outer
        select new
        {
            Category = category,
            Subcategories = from subcategory in inner
                            where subcategory.ProductCategoryID == category.ProductCategoryID
                            select subcategory
        } into category
        from subcategory in category.Subcategories.DefaultIfEmpty() // INNER JOIN if DefaultIfEmpty is missing.
        select new { Category = category.Category.Name, Subcategory = subcategory.Name }; // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category}: {category.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to inner join, left outer join can be done with entities association too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LeftOuterJoinWithAssociation()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    var categories = source.SelectMany(
        category =&amp;gt; category.ProductSubcategories.DefaultIfEmpty(), // INNER JOIN if DefaultIfEmpty is missing.
        (category, subcategory) =&amp;gt;
            new { Category = category.Name, Subcategory = subcategory.Name }); // Define query.
    categories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.Category}: {subcategory.Subcategory}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, DefaultIfEmpty must be called in SelectMany, otherwise the query become inner join. The above flattened left outer join queries are translated to identical LEFT OUTER JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [Production].[ProductCategory] AS [Extent1]
    LEFT OUTER JOIN [Production].[ProductSubcategory] AS [Extent2] ON [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Cross join&lt;/h3&gt;
&lt;p&gt;Just like LINQ to Objects, cross join can be done with SelectMany and Join. The following examples query the expensive products (list price greater than 2000) and cheap products (list price less than 100), and then cross join them to get all possible product bundles, where each bundle has one expensive product and one cheap product:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithSelectMany()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles = outer.SelectMany(
        outerProduct =&amp;gt; inner,
        (outerProduct, innerProduct) =&amp;gt;
            new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }); // Define query.
    bundles.ForEach(bundle =&amp;gt; Trace.WriteLine($&quot;{bundle.Expensive}: {bundle.Cheap}&quot;)); // Execute query.
}

internal static void CrossJoinWithJoin()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles = outer.Join(
        inner,
        product =&amp;gt; true,
        product =&amp;gt; true,
        (outerProduct, innerProduct) =&amp;gt;
            new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }); // Define query.
    bundles.ForEach(bundle =&amp;gt; Trace.WriteLine($&quot;{bundle.Expensive}: {bundle.Cheap}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their query expression versions are similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossJoinWithSelectMany()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles =
        from outerProduct in outer
        from innerProduct in inner
        // where true == true
        select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }; // Define query.
    bundles.ForEach(bundle =&amp;gt; Trace.WriteLine($&quot;{bundle.Expensive}: {bundle.Cheap}&quot;)); // Execute query.
}

internal static void CrossJoinWithJoin()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    var bundles =
        from outerProduct in outer
        join innerProduct in inner
        on true equals true
        select new { Expensive = outerProduct.Name, Cheap = innerProduct.Name }; // Define query.
    bundles.ForEach(bundle =&amp;gt; Trace.WriteLine($&quot;{bundle.Expensive}: {bundle.Cheap}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above SelectMany is translated to CROSS JOIN, and Join is translated to INNER JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [Production].[Product] AS [Extent1]
    CROSS JOIN [Production].[Product] AS [Extent2]
    WHERE ([Extent1].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AND ([Extent2].[ListPrice] &amp;lt; cast(100 as decimal(18)))

SELECT 
    1 AS [C1], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [Production].[Product] AS [Extent1]
    INNER JOIN [Production].[Product] AS [Extent2] ON 1 = 1
    WHERE ([Extent1].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AND ([Extent2].[ListPrice] &amp;lt; cast(100 as decimal(18)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 SQL queries are equivalent. They have the same query plan.&lt;/p&gt;
&lt;h3&gt;Self join&lt;/h3&gt;
&lt;p&gt;Entities can join with themselves. The following example joins the Products data source with Products data source with ListPrice, to query each product’s same price products.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelfJoin()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products;
    var products = outer.GroupJoin(
        inner,
        product =&amp;gt; product.ListPrice,
        product =&amp;gt; product.ListPrice,
        (product, samePriceProducts) =&amp;gt; new
        {
            Name = product.Name,
            ListPrice = product.ListPrice,
            SamePriceProducts = samePriceProducts
                .Where(samePriceProduct =&amp;gt; samePriceProduct.ProductID != product.ProductID)
                .Select(samePriceProduct =&amp;gt; samePriceProduct.Name)
        }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(
        $&quot;{product.Name} ({product.ListPrice}): {string.Join(&quot;, &quot;, product.SamePriceProducts)}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The the query expression version is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelfJoin()
{
    IQueryable&amp;lt;Product&amp;gt; outer = AdventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; inner = AdventureWorks.Products;
    var products =
        from outerProduct in outer
        join innerProduct in inner
        on outerProduct.ListPrice equals innerProduct.ListPrice into samePriceProducts
        select new
        {
            Name = outerProduct.Name,
            ListPrice = outerProduct.ListPrice,
            SamePriceProducts = from samePriceProduct in samePriceProducts
                                where samePriceProduct.ProductID != outerProduct.ProductID
                                select samePriceProduct.Name
        }; // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(
        $&quot;{product.Name} ({product.ListPrice}): {string.Join(&quot;, &quot;, product.SamePriceProducts)}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are translated to self join:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[ProductID] AS [ProductID], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice], 
    [Project1].[C1] AS [C1], 
    [Project1].[Name1] AS [Name1]
    FROM ( SELECT 
        [Extent1].[ProductID] AS [ProductID], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        [Extent2].[Name] AS [Name1], 
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM  [Production].[Product] AS [Extent1]
        LEFT OUTER JOIN [Production].[Product] AS [Extent2] ON ([Extent1].[ListPrice] = [Extent2].[ListPrice]) AND ([Extent2].[ProductID] &amp;lt;&amp;gt; [Extent1].[ProductID])
    )  AS [Project1]
    ORDER BY [Project1].[ProductID] ASC, [Project1].[C1] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the translated SQL contains this ORDER BY query, because GroupJoin returns hierarchical result&lt;/p&gt;
&lt;h3&gt;Apply&lt;/h3&gt;
&lt;p&gt;In SQL, APPLY matches each left table row with all rows in the right table. CROSS APPLY is similar to INNER JOIN, each row in left table will be in the result if there is any matching row in the right table; and OUTER APPLY is similar to OUTER JOIN, each row of the left table will be in the result no mater it has a match or not. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [Left].[Count], [Right].[Value] FROM
    (SELECT [Count]
        FROM (VALUES (0), (1), (2), (3)) [0 to 4]([Count])) AS [Left]
    CROSS APPLY 
    (SELECT top ([Count]) [Value]
        FROM (VALUES (N&apos;a&apos;), (N&apos;b&apos;), (N&apos;c&apos;), (N&apos;d&apos;)) [0 to 4]([Value])) AS [Right];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the left table is a table of numbers, the right table is a table of Unicode character strings. Each number will be matched to that number of strings, so the result is:&lt;/p&gt;
&lt;p&gt;&amp;lt;table&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;Count&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;Value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;b&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;b&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;c&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;0 matches 0 strings, so 0 is not in the CROSS APPLY result. It will be in the OUTER APPLY result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [Left].[Count], [Right].[Value] FROM
    (SELECT [Count]
        FROM (VALUES (0), (1), (2), (3)) [0 to 4]([Count])) AS [Left]
    OUTER APPLY 
    (SELECT top ([Count]) [Value]
        FROM (VALUES (N&apos;a&apos;), (N&apos;b&apos;), (N&apos;c&apos;), (N&apos;d&apos;)) [0 to 4]([Value])) AS [Right];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;table&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;Count&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;Value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;0&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;NULL&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;b&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;a&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;b&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;3&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;100&quot;&amp;gt;c&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h3&gt;Cross apply&lt;/h3&gt;
&lt;p&gt;In LINQ to Entities queries, SelectMany can flatten hierarchical data, for example, hierarchical result from GroupBy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossApplyWithGroupByAndTake()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var categories = source
        .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID)
        .SelectMany(
            group =&amp;gt; group.Take(1),
            (group, subcategory) =&amp;gt;
                new { ProductCategoryID = group.Key, FirstSubcategory = subcategory }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.ProductCategoryID}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Take is called when flattening the hierarchical result. Logically, if a group is not empty, there will be 1 row for this group in the query result; and a group is empty, there will not be a row for this group in the query result. so above query is translated to CROSS APPLY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Distinct1].[ProductCategoryID] AS [ProductCategoryID], 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID1]
    FROM   (SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    CROSS APPLY  (SELECT TOP (1) 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, GroupJoin and one-to-many association can produce hierarchical data, which then can be flattened by SelectMany:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CrossApplyWithGroupJoinAndTake()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer
        .GroupJoin(
            inner,
            category =&amp;gt; category.ProductCategoryID,
            subcategory =&amp;gt; subcategory.ProductCategoryID,
            (category, subcategories) =&amp;gt; new { Category = category, Subcategories = subcategories })
        .SelectMany(
            category =&amp;gt; category.Subcategories.Take(1),
            (category, subcategory) =&amp;gt;
                new { Category = category.Category, FirstSubcategory = subcategory }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category.Name}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}

internal static void CrossApplyWithAssociationAndTake()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    var categories = source
        .Select(category =&amp;gt; new { Category = category, Subcategories = category.ProductSubcategories })
        .SelectMany(
            category =&amp;gt; category.Subcategories.Take(1),
            (category, subcategory) =&amp;gt;
                new { Category = category.Category, FirstSubcategory = subcategory }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category.Name}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are semantically equivalent. They will be translated to CROSS APPLY too, because of Take:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name], 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name] AS [Name1], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID1]
    FROM  [Production].[ProductCategory] AS [Extent1]
    CROSS APPLY  (SELECT TOP (1) 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Outer apply&lt;/h3&gt;
&lt;p&gt;FirstOrDefault accepts a IQueryable&amp;lt;T&amp;gt; data source and returns a single value, so it can be used to flatten hierarchical data too. again, take GroupBy as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OuterApplyWithGroupByAndFirstOrDefault()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var categories = source.GroupBy(
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        (key, group) =&amp;gt; new { ProductCategoryID = key, FirstSubcategory = group.FirstOrDefault() }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.ProductCategoryID}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The different from Take is, no matter the group is empty or not, there is always 1 row for this group in the query result. So above query it translated to OUTER APPLY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Distinct1].[ProductCategoryID] AS [ProductCategoryID], 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID1]
    FROM   (SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, when FirstOrDefault is called in GroupJoin or one-to-many association:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OuterApplyWithGroupJoinAndFirstOrDefault()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; outer = AdventureWorks.ProductCategories;
    IQueryable&amp;lt;ProductSubcategory&amp;gt; inner = AdventureWorks.ProductSubcategories;
    var categories = outer.GroupJoin(
        inner,
        category =&amp;gt; category.ProductCategoryID,
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        (category, subcategories) =&amp;gt; 
            new { Category = category, FirstSubcategory = subcategories.FirstOrDefault() }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category.Name}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}

internal static void OuterApplyWithAssociationAndFirstOrDefault()
{
    IQueryable&amp;lt;ProductCategory&amp;gt; source = AdventureWorks.ProductCategories;
    var categories = source.Select(category =&amp;gt; new
    {
        Category = category,
        FirstSubcategory = category.ProductSubcategories.FirstOrDefault()
    }); // Define query.
    categories.ForEach(category =&amp;gt; Trace.WriteLine(
        $&quot;{category.Category.Name}: {category.FirstSubcategory?.Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the translation is OUTER APPLY too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name], 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name] AS [Name1], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID1]
    FROM  [Production].[ProductCategory] AS [Extent1]
    OUTER APPLY  (SELECT TOP (1) 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;The following example concatenates the cheap products’ names with the expensive products’ names:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Concat()
{
    IQueryable&amp;lt;string&amp;gt; first = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt; 100)
        .Select(product =&amp;gt; product.Name);
    IQueryable&amp;lt;string&amp;gt; second = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)
        .Select(product =&amp;gt; product.Name);
    IQueryable&amp;lt;string&amp;gt; concat = first.Concat(second); // Define query.
    concat.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Select is called before Concat. It is equivalent to call Select after Concat:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcatWithSelect()
{
    IQueryable&amp;lt;Product&amp;gt; first = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;lt; 100);
    IQueryable&amp;lt;Product&amp;gt; second = AdventureWorks.Products.Where(product =&amp;gt; product.ListPrice &amp;gt; 2000);
    IQueryable&amp;lt;string&amp;gt; concat = first
        .Concat(second)
        .Select(product =&amp;gt; product.Name); // Define query.
    concat.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are both translate to identical UNION ALL query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [UnionAll1].[Name] AS [C1]
    FROM  (SELECT 
        [Extent1].[Name] AS [Name]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;lt; cast(100 as decimal(18))
    UNION ALL
        SELECT 
        [Extent2].[Name] AS [Name]
        FROM [Production].[Product] AS [Extent2]
        WHERE [Extent2].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AS [UnionAll1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Set&lt;/h3&gt;
&lt;p&gt;The following example queries the subcategories for the distinct ProductCategoryIDs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Distinct()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;int&amp;gt; distinct = source
        .Select(subcategory =&amp;gt; subcategory.ProductCategoryID)
        .Distinct(); // Define query.
    distinct.ForEach(value =&amp;gt; Trace.WriteLine(value)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, as fore mentioned, GroupBy can also query distinct group keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctWithGroupBy()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;int&amp;gt; distinct = source.GroupBy(
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        (key, group) =&amp;gt; key); // Define query.
    distinct.ForEach(value =&amp;gt; Trace.WriteLine(value)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Distinct and GroupBy are translated to identical SELECT DISTINCT query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Distinct1].[ProductCategoryID] AS [ProductCategoryID]
    FROM ( SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1]
    )  AS [Distinct1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To query distinct multiple keys, use anonymous type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctMultipleKeys()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var distinct = source
        .Select(subcategory =&amp;gt; 
            new { ProductCategoryID = subcategory.ProductCategoryID, Name = subcategory.Name })
        .Distinct(); // Define query.
    distinct.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.ProductCategoryID}: {subcategory.Name}&quot;)); // Execute query.
}

internal static void DistinctWithGroupByMultipleKeys()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    var distinct = source.GroupBy(
        subcategory =&amp;gt; new { ProductCategoryID = subcategory.ProductCategoryID, Name = subcategory.Name },
        (key, group) =&amp;gt; key); // Define query.
    distinct.ForEach(subcategory =&amp;gt; Trace.WriteLine(
        $&quot;{subcategory.ProductCategoryID}: {subcategory.Name}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The anonymous type’s properties are translated into the SELECT DISTINCT clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Distinct1].[C1] AS [C1], 
    [Distinct1].[ProductCategoryID] AS [ProductCategoryID], 
    [Distinct1].[Name] AS [Name]
    FROM ( SELECT DISTINCT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        1 AS [C1]
        FROM [Production].[ProductSubcategory] AS [Extent1]
    )  AS [Distinct1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GroupBy can also be used for more complex scenarios, for example, query the complete entities with certain distinct properties. Please see above APPLY examples.&lt;/p&gt;
&lt;p&gt;The following example queries subcategories’ Names, where they have distinct ProductCategoryIDs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DistinctWithGroupByAndFirstOrDefault()
{
    IQueryable&amp;lt;ProductSubcategory&amp;gt; source = AdventureWorks.ProductSubcategories;
    IQueryable&amp;lt;string&amp;gt; distinct = source.GroupBy(
        subcategory =&amp;gt; subcategory.ProductCategoryID,
        (key, group) =&amp;gt; group.Select(subcategory =&amp;gt; subcategory.Name).FirstOrDefault()); // Define query.
    distinct.ForEach(subcategory =&amp;gt; Trace.WriteLine(subcategory)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    (SELECT TOP (1) 
        [Extent2].[Name] AS [Name]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID]) AS [C1]
    FROM ( SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1]
    )  AS [Distinct1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other set query methods, Intersect and Except:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Intersect()
{
    var first = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var second = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;lt; 2000)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var intersect = first.Intersect(second); // Define query.
    intersect.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}

internal static void Except()
{
    var first = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 100)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var second = AdventureWorks.Products
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 2000)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice });
    var except = first.Except(second); // Define query.
    except.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;are translated to INTERSECT and EXCEPT:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Intersect1].[C1] AS [C1], 
    [Intersect1].[Name] AS [C2], 
    [Intersect1].[ListPrice] AS [C3]
    FROM  (SELECT 
        1 AS [C1], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    INTERSECT
        SELECT 
        1 AS [C1], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ListPrice] AS [ListPrice]
        FROM [Production].[Product] AS [Extent2]
        WHERE [Extent2].[ListPrice] &amp;lt; cast(2000 as decimal(18))) AS [Intersect1]
    
SELECT 
    [Except1].[C1] AS [C1], 
    [Except1].[Name] AS [C2], 
    [Except1].[ListPrice] AS [C3]
    FROM  (SELECT 
        1 AS [C1], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;gt; cast(100 as decimal(18))
    EXCEPT
        SELECT 
        1 AS [C1], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ListPrice] AS [ListPrice]
        FROM [Production].[Product] AS [Extent2]
        WHERE [Extent2].[ListPrice] &amp;gt; cast(2000 as decimal(18))) AS [Except1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;Take cannot be used independently. OrderBy must be called before calling Skip. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndSkip()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .OrderBy(product =&amp;gt; product.Name)
        .Skip(10)
        .Select(product =&amp;gt; product.Name); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without OrderBy, Entity Framework throws NotSupportedException. The reason is, Skip is translated to OFFSET clause, and OFFSET requires ORDER BY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[Name] AS [Name]
    FROM [Production].[Product] AS [Extent1]
    ORDER BY [Extent1].[Name] ASC
    OFFSET 10 ROWS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Take is called without calling Skip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Take()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .Take(10)
        .Select(product =&amp;gt; product.Name); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it is translated to TOP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (10) 
    [c].[Name] AS [Name]
    FROM [Production].[Product] AS [c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Take is called with Skip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndSkipAndTake()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .OrderBy(product =&amp;gt; product.Name)
        .Skip(20)
        .Take(10)
        .Select(product =&amp;gt; product.Name); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the translation becomes OFFSET-FETCH clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[Name] AS [Name]
    FROM [Production].[Product] AS [Extent1]
    ORDER BY [Extent1].[Name] ASC
    OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is extremely helpful for pagination.&lt;/p&gt;
&lt;h3&gt;Ordering&lt;/h3&gt;
&lt;p&gt;OrderBy/OrderByDescding are translated to ORDER BY clause with ASC/DESC. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderBy()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;)); // Execute query.
}

internal static void OrderByDescending()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source
        .OrderByDescending(product =&amp;gt; product.ListPrice)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translations are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice]
    FROM ( SELECT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [Project1]
    ORDER BY [Project1].[ListPrice] ASC

SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice]
    FROM ( SELECT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [Project1]
    ORDER BY [Project1].[ListPrice] DESC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To sort with multiple keys, call OrderBy/OrderByDescending and ThenBy/ThenByDescending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndThenBy()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .ThenBy(product =&amp;gt; product.Name)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to GroupBy/Join/GroupJoin, the ordering query methods’ keySelector can return anonymous type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAnonymousType()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; new { ListPrice = product.ListPrice, Name = product.Name })
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 2 queries are semantically equivalent. They are translated to identical ORDER BY query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice]
    FROM ( SELECT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [Project1]
    ORDER BY [Project1].[ListPrice] ASC, [Project1].[Name] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If OrderBy/OrderByDescending are called multiple times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void OrderByAndOrderBy()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var products = source
        .OrderBy(product =&amp;gt; product.ListPrice)
        .OrderBy(product =&amp;gt; product.Name)
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;only the last call is translated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[ListPrice] AS [ListPrice]
    FROM ( SELECT 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [Project1]
    ORDER BY [Project1].[Name] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conversion&lt;/h3&gt;
&lt;p&gt;Cast can convert primitive types, for example, decimal (money) to string (nvarchar):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Cast()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; listPrices = source
        .Select(product =&amp;gt; product.ListPrice)
        .Cast&amp;lt;string&amp;gt;(); // Define query.
    listPrices.ForEach(listPrice =&amp;gt; Trace.WriteLine(listPrice)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cast is translated to CAST:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
     CAST( [Extent1].[ListPrice] AS nvarchar(max)) AS [C1]
    FROM [Production].[Product] AS [Extent1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SQL function CAST only works for primitive types, so Cast query method cannot convert arbitrary data. The following example attempts to convert Product to UniversalProduct:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CastEntity()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;UniversalProduct&amp;gt; universalProducts = source
        .Where(product =&amp;gt; product.Name.StartsWith(&quot;Road-750&quot;))
        .Cast&amp;lt;UniversalProduct&amp;gt;(); // Define query.
    universalProducts.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.GetType().Name}&quot;)); // Execute query.
    // NotSupportedException: Unable to cast the type &apos;Dixin.Linq.EntityFramework.Product&apos; to type &apos;Dixin.Linq.EntityFramework.UniversalProduct&apos;. LINQ to Entities only supports casting EDM primitive or enumeration types.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, above conversion cannot be translated to a CAST expression, so Entity Framework throws a NotSupportedException.&lt;/p&gt;
&lt;p&gt;The other conversion query method is AsQueryable. It has 2 overloads, a generic overload to convert IEnumerable&amp;lt;T&amp;gt; source to IQueryable&amp;lt;T&amp;gt;, and a non-generic overload to convert IEnumerable source to IQueryable. Also, remember Enumerable.AsEnumerable can convert more derived source (e.g., a IQueryable&amp;lt;T&amp;gt; source) to IEnumerable&amp;lt;T&amp;gt;. These AsQueryable/AsEnumerable methods look like the AsParallel/AsSequential methods, which convert between LINQ to Objects parallel/sequential queries. However, AsQueryable/AsEnumerable usually do not convert between remote LINQ to Entities query and local LINQ to Objects query. Here is the implementation of Enumerable.AsEnumerable, and Queryable.AsQueryable (the generic overload):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    using System.Collections.Generic;

    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source) =&amp;gt; source;
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TElement&amp;gt; AsQueryable&amp;lt;TElement&amp;gt;(this IEnumerable&amp;lt;TElement&amp;gt; source) =&amp;gt;
            source is IQueryable&amp;lt;TElement&amp;gt; ? (IQueryable&amp;lt;TElement&amp;gt;)source : new EnumerableQuery&amp;lt;TElement&amp;gt;(source);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsQueryable accepts an IEnumerable&amp;lt;T&amp;gt; source. If the input source is indeed an IQueryable&amp;lt;T&amp;gt; source, then return the input source; if not, wrap the input source into an EnumerablleQuery&amp;lt;T&amp;gt; object, and return it. EnumerablleQuery&amp;lt;T&amp;gt; is a special implementation of IQueryable&amp;lt;T&amp;gt;. When pulling values from EnumerableQuery&amp;lt;T&amp;gt; source, System.Linq.EnumerableRewriter.Visit is called to translate the query to local LINQ to Objects query, then execute the query locally. As a result, AsEnumerable can convert a remote LINQ to Entities query to local LINQ to Objects query, but AsQueryable cannot convert a local LINQ to Objects query to a remote LINQ to Entities query (and logically, a local .NET data source cannot be converted to a remote SQL data source). For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsEnumerableAsQueryable()
{
    IQueryable&amp;lt;Product&amp;gt; source1 = AdventureWorks.Products;
    var query1 = source1 // DbSet&amp;lt;T&amp;gt; object, derives from DbQuery&amp;lt;T&amp;gt;.
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return DbQuery&amp;lt;T&amp;gt; object.
        .AsEnumerable() // Do nothing, directly return the input DbQuery&amp;lt;T&amp;gt; object.
        .AsQueryable() // Do nothing, directly return the input DbQuery&amp;lt;T&amp;gt; object.
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 0); // Continue LINQ to Entities query.
    query1.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;));

    IQueryable&amp;lt;Product&amp;gt; source2 = AdventureWorks.Products;
    var query2 = source2 // DbSet&amp;lt;T&amp;gt; object, derives from DbQuery&amp;lt;T&amp;gt;.
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice }) // Return DbQuery&amp;lt;T&amp;gt; object.
        .AsEnumerable() // Do nothing, directly return the input DbQuery&amp;lt;T&amp;gt; object.
        .Select(product =&amp;gt; product) // Enumerable.Select, returns a generator wrapping the input DbQuery&amp;lt;T&amp;gt; object.
        .AsQueryable() // Return an EnumerableQuery&amp;lt;T&amp;gt; object wrapping the input generator.
        .Where(product =&amp;gt; product.ListPrice &amp;gt; 0); // No longer LINQ to Entities query on DbSet&amp;lt;T&amp;gt; or DbQuery&amp;lt;T&amp;gt;.
    query2.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.Name}: {product.ListPrice}&quot;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the first query:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select is called on DbSet&amp;lt;T&amp;gt; source, it returns a DbQuery&amp;lt;T&amp;gt;, and it will be translated to SQL query.&lt;/li&gt;
&lt;li&gt;AsEnumerable returns the input source directly, which is actually an DbQuery&amp;lt;T&amp;gt; source.&lt;/li&gt;
&lt;li&gt;Then, AsQueryable is called. since the input DbQuery&amp;lt;T&amp;gt; source is IQueryable&amp;lt;T&amp;gt;, it directly returns the input source again.&lt;/li&gt;
&lt;li&gt;So after calling AsEnumerable and AsQueryable, nothing happens. Where is still LINQ to Entities query on DbQuery&amp;lt;T&amp;gt;, it will be translated to WHERE clause.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So it is translated as if AsEnumerable call and AsQueryable call do not exist:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ListPrice] AS [ListPrice]
    FROM [Production].[Product] AS [Extent1]
    WHERE [Extent1].[ListPrice] &amp;gt; cast(0 as decimal(18))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the second query:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first Select will be translated to SQL query.&lt;/li&gt;
&lt;li&gt;The second Select is called after AsEnumerable, so it is Enumerable.Select instead of Queryable.Select. As discussed in the LINQ to Objects chapter, Enumerable.Select returns a generator, which wraps the input source.&lt;/li&gt;
&lt;li&gt;Then AsQueryable is called. Since the input generator is not IQueryable&amp;lt;T&amp;gt;, it returns an EnumerableQuery&amp;lt;T&amp;gt;, which wraps he generator.&lt;/li&gt;
&lt;li&gt;Where is called on EnumerbaleQuery&amp;lt;T&amp;gt; source, it will be translated to LINQ to Objects query.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The translated SQL does not have the WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    1 AS [C1], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ListPrice] AS [ListPrice]
    FROM [Production].[Product] AS [Extent1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AsEnumerable can be useful for LINQ to Entities for some special cases. For example, LINQ to Entities’ Select query method does not support mapping to existing entity type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectEntities()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;Product&amp;gt; products = source
        .Where(product =&amp;gt; product is UniversalProduct)
        .Select(product =&amp;gt; new UniversalProduct()
        {
            ProductID = product.ProductID,
            Name = product.Name,
            ListPrice = product.ListPrice,
            ProductSubcategoryID = product.ProductSubcategoryID
        }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine($&quot;{product.ProductID}: {product.Name}&quot;)); // Execute query.
    // NotSupportedException: The entity or complex type &apos;Dixin.Linq.EntityFramework.UniversalProduct&apos; cannot be constructed in a LINQ to Entities query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing above query throws a NotSupportedException. This is by design, because this kind of mapping causes difficulties for Entity Framework. For example, by default DbContext maintains the mapping between remote rows and query result entities, and constructing entities on the fly prevents doing so. Here, one solution is to construct the UniversalProduct entities with local LINQ to Objects query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectEntityObjects()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IEnumerable&amp;lt;Product&amp;gt; products = source
        .Where(product =&amp;gt; product is UniversalProduct) // Return IQueryable&amp;lt;Product&amp;gt;. LINQ to Entities.
        .AsEnumerable() // Return IEnumerable&amp;lt;(int, string)&amp;gt;. LINQ to Objects from here.
        .Select(product =&amp;gt; new UniversalProduct()
        {
            ProductID = product.ProductID,
            Name = product.Name,
            ListPrice = product.ListPrice,
            ProductSubcategoryID = product.ProductSubcategoryID
        }); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product.Name)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Return a single value&lt;/h2&gt;
&lt;p&gt;Query methods in this category takes an IQueryable&amp;lt;T&amp;gt; input source and returns a single value. As demonstrated above, they can be used with the other query methods to flatten hierarchical data, like aggregation query method with GroupBy are translated to SQL aggregation function with GROUP BY, etc. When they are called at the end of a LINQ to Entities query, they returns some value with immediate execution, which is similar behavior to LINQ to Objects.&lt;/p&gt;
&lt;h3&gt;Element&lt;/h3&gt;
&lt;p&gt;First/FirstOrDefault execute the LINQ to Entities queries immediately for the first value/first or default value. The following example queries the first product’s Name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void First()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    string first = source
        .Select(product =&amp;gt; product.Name)
        .First(); // Execute query.
    Trace.WriteLine(first);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to TOP (1):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) 
    [c].[Name] AS [Name]
    FROM [Production].[Product] AS [c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First/FirstOrDefault can also accept a predicate expression tree. The following example queries the first or default product with ListPrice greater than 5000:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void FirstOrDefault()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var firstOrDefault = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .FirstOrDefault(product =&amp;gt; product.ListPrice &amp;gt; 5000); // Execute query.
    Trace.WriteLine($&quot;{firstOrDefault?.Name}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The predicate is translated to WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[C1] AS [C1], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ListPrice] AS [ListPrice]
    FROM ( SELECT TOP (1) 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;gt; cast(5000 as decimal(18))
    )  AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in LINQ to Objects, Single/SingleOrDefault look similar to, but the semantics is more strict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Single()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var single = source
        .Select(product =&amp;gt; new { Name = product.Name, ListPrice = product.ListPrice })
        .Single(product =&amp;gt; product.ListPrice &amp;lt; 50); // Execute query.
    Trace.WriteLine($&quot;{single.Name}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To ensure the query result does not have more than 1 row, Single/SingleOrDefault are translated to TOP (2):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[C1] AS [C1], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ListPrice] AS [ListPrice]
    FROM ( SELECT TOP (2) 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ListPrice] AS [ListPrice], 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;lt; cast(50 as decimal(18))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single/SingleOrDefault can also accept predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SingleOrDefault()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    var singleOrDefault = source
        .GroupBy(
            subcategory =&amp;gt; subcategory.ListPrice,
            (key, groups) =&amp;gt; new { ListPrice = key, Count = groups.Count() })
        .SingleOrDefault(group =&amp;gt; group.Count &amp;gt; 10); // Define query.
    Trace.WriteLine($&quot;{singleOrDefault?.ListPrice}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to WHERE as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[C2] AS [C1], 
    [Limit1].[ListPrice] AS [ListPrice], 
    [Limit1].[C1] AS [C2]
    FROM ( SELECT TOP (2) 
        [GroupBy1].[A1] AS [C1], 
        [GroupBy1].[K1] AS [ListPrice], 
        1 AS [C2]
        FROM ( SELECT 
            [Extent1].[ListPrice] AS [K1], 
            COUNT(1) AS [A1]
            FROM [Production].[Product] AS [Extent1]
            GROUP BY [Extent1].[ListPrice]
        )  AS [GroupBy1]
        WHERE [GroupBy1].[A1] &amp;gt; 10
    )  AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregation&lt;/h3&gt;
&lt;p&gt;Count/LongCount are translated to SQL aggregate functions COUNT/COUNT_BIG, and the provided predicate is translated to WHERE clause. The following examples query the System.Int32 count of categories, and the System.Int64 count of the products with ListPrice greater than 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Count()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    int count = source.Count(); // Execute query.
    Trace.WriteLine(count);
}

internal static void LongCount()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    long longCount = source.LongCount(product =&amp;gt; product.ListPrice &amp;gt; 0); // Execute query.
    Trace.WriteLine(longCount);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [Production].[ProductCategory] AS [Extent1]
    )  AS [GroupBy1]

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT_BIG(1) AS [A1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ListPrice] &amp;gt; cast(0 as decimal(18))
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Max/Min are translated to MAX/MIN functions. If a selector is provided, the selector is translated to argument of MAX/MIN. The following examples query the latest ModifiedDate of photos, and the lowest ListPrice of products:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Max()
{
    IQueryable&amp;lt;ProductPhoto&amp;gt; source = AdventureWorks.ProductPhotos;
    DateTime max = source.Select(photo =&amp;gt; photo.ModifiedDate).Max(); // Execute query.
    Trace.WriteLine(max); 
}

internal static void Min()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    decimal min = source.Min(product =&amp;gt; product.ListPrice); // Execute query.
    Trace.WriteLine(min);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their translations are in the same pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MAX([Extent1].[ModifiedDate]) AS [A1]
        FROM [Production].[ProductPhoto] AS [Extent1]
    )  AS [GroupBy1]

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MIN([Extent1].[ListPrice]) AS [A1]
        FROM [Production].[Product] AS [Extent1]
    )  AS [GroupBy1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Min/Max cannot evaluate for any type, because SQL MAX/MIN functions only accept numeric, character string, uniqueidentifier, and datetime arguments.&lt;/p&gt;
&lt;p&gt;For other scenarios, like query some properties&lt;/p&gt;
&lt;h3&gt;Quantifier&lt;/h3&gt;
&lt;p&gt;Any is translated to EXISTS operator, and the LINQ to Entities query before Any is translated to subquery of EXISTS. The following example simply query whether any product exists:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Any()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    bool anyUniversal = source.Any(); // Execute query.
    Trace.WriteLine(anyUniversal);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
    )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Contains can be implemented by Any equivalently, so Contains is translated to EXISTS too. The following example queries whether any product’s ListPrice is 100:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Contains()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    // Only primitive types or enumeration types are supported.
    bool contains = source.Select(product =&amp;gt; product.ListPrice).Contains(100); // Execute query.
    Trace.WriteLine(contains);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is equivalent to the following Any query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AnyWithPredicate()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    bool anyUniversal = source.Any(product =&amp;gt; product.ListPrice == 100); // Execute query.
    Trace.WriteLine(anyUniversal);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are translated to identical EXISTS query, and the predicate for Any is translated to WHERE clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE cast(100 as decimal(18)) = [Extent1].[ListPrice]
    )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All can be implemented by Any equivalently too. The following example queries whether all products’ ListPrices are not 100:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AllNot()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    bool allNot = source.All(product =&amp;gt; product.ProductSubcategoryID != null); // Execute query.
    Trace.WriteLine(allNot);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is equivalent to query whether not any product’s ListPrice is 100:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NotAny()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    bool notAny = !source.Any(product =&amp;gt; !(product.ProductSubcategoryID != null)); // Execute query.
    Trace.WriteLine(notAny);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So above All query is translated to NOT EXISTS, and in the subquery’s WHERE clause, != null is translated to opposite condition IS NULL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    CASE WHEN ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE ([Extent1].[ProductSubcategoryID] IS NULL) 
            OR (CASE -- OR and the succeeding condition is redundant.
                    WHEN ([Extent1].[ProductSubcategoryID] IS NOT NULL) THEN cast(1 as bit) 
                    ELSE cast(0 as bit) 
                END IS NULL)
    )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]

SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ProductSubcategoryID] IS NULL
    )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their translation are not identical, but in the same pattern. In the ALL translation, the WHERE clause’s OR operator and the succeeding condition is redundant. Also the Any translation is EXISTS, the “not” any is done by the .NET ! operator outside the LINQ to Entities query, so it is not translated.&lt;/p&gt;
</content:encoded></item><item><title>Debugging Classic ASP with Modern Visual Studio</title><link>https://dixin.github.io/posts/debugging-classic-asp-with-visual-studio/</link><guid isPermaLink="true">https://dixin.github.io/posts/debugging-classic-asp-with-visual-studio/</guid><description>Recently I tried to show my Mom some websites I built when I was a kid. Those , some in  wh</description><pubDate>Mon, 23 May 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I tried to show my Mom some websites I built when I was a kid. Those &lt;a href=&quot;http://en.wikipedia.org/wiki/Active_Server_Pages&quot;&gt;ASP code&lt;/a&gt;, some in &lt;a href=&quot;http://en.wikipedia.org/wiki/VBScript&quot;&gt;VBScript&lt;/a&gt; while some in &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;, are more than 10 years old. They were running fine in &lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Personal_Web_Server&quot;&gt;PWS&lt;/a&gt;, but now they didn’t run in &lt;a href=&quot;http://en.wikipedia.org/wiki/Internet_Information_Services&quot;&gt;IIS 8.5&lt;/a&gt;. I have no idea what’s the problem. It seems a little debugging has to be done.&lt;/p&gt;
&lt;h2&gt;Debugging with Visual Studio 2013/2015/2017 and IIS Express&lt;/h2&gt;
&lt;p&gt;I have &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_8.1&quot;&gt;Windows 8.1&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Visual_Studio#Visual_Studio_2013&quot;&gt;Visual Studio 2013&lt;/a&gt; (Later I have &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_10&quot;&gt;Windows 10&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#Visual_Studio_2015&quot;&gt;Visual Studio 2015&lt;/a&gt;/&lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#2017&quot;&gt;Visual Studio 2017&lt;/a&gt;). Surprisingly, I found that &lt;a href=&quot;https://weblogs.asp.net/scottgu/introducing-iis-express&quot;&gt;IIS Express supports ASP&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In addition to supporting ASP.NET, IIS Express also supports Classic ASP and other file-types and extensions supported by IIS – which also makes it ideal for sites that combine a variety of different technologies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After searching and trying things around, using Visual Studio and &lt;a href=&quot;http://en.wikipedia.org/wiki/Internet_Information_Services#IIS_Express&quot;&gt;IIS Express&lt;/a&gt; seems to be the easiest way to run and debug ASP websites:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Modify IIS Express configuration. Open %USERPROFILE%\Documents\IISExpress\config\applicationhost.config. Under &lt;a href=&quot;http://www.iis.net/configreference/system.webserver&quot;&gt;&amp;lt;system.webServer&amp;gt;&lt;/a&gt;, find &lt;a href=&quot;http://www.iis.net/configreference/system.webserver/asp&quot;&gt;&amp;lt;asp&amp;gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;asp scriptErrorSentToBrowser=&quot;true&quot;&amp;gt;
    &amp;lt;cache diskTemplateCacheDirectory=&quot;%TEMP%\iisexpress\ASP Compiled Templates&quot; /&amp;gt;
    &amp;lt;limits /&amp;gt;
&amp;lt;/asp&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and change it to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;asp scriptErrorSentToBrowser=&quot;true&quot; enableParentPaths=&quot;true&quot; bufferingOn=&quot;true&quot; errorsToNTLog=&quot;true&quot; appAllowDebugging=&quot;true&quot; appAllowClientDebug=&quot;true&quot;&amp;gt;
    &amp;lt;cache diskTemplateCacheDirectory=&quot;%TEMP%\iisexpress\ASP Compiled Templates&quot; /&amp;gt;
    &amp;lt;session allowSessionState=&quot;true&quot; /&amp;gt;
    &amp;lt;limits /&amp;gt;
&amp;lt;/asp&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Visual Studio, add existing website to the solution (or open a website), point to the ASP website folder.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start the website without debugging (Ctrl+F5).I will explain why.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Visual Studio, open the “Attach to Process” dialog (Ctrl+Alt+P). Notice the “Attach to” has the default option “Automatic: Native code” &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb9_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb9_thumb.png&quot; alt=&quot;image_thumb9&quot; title=&quot;image_thumb9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click the “Select…” button, change it to “Script”: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb10_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb10_thumb.png&quot; alt=&quot;image_thumb10&quot; title=&quot;image_thumb10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now attach to IIS Express: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb11_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb11_thumb.png&quot; alt=&quot;image_thumb11&quot; title=&quot;image_thumb11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If IIS Express is running multiple websites, there will be multiple iisexpress.exe processes in the “Available Processes”. The current website’s process ID can be found from the IIS Express site list: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb13_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb13_thumb.png&quot; alt=&quot;image_thumb13&quot; title=&quot;image_thumb13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now the website can be debugged in Visual Studio:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And Solution Explorer shows the triggered .asp files, and how each .asp file includes other files.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb15_5.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb15_thumb_1.png&quot; alt=&quot;image_thumb15&quot; title=&quot;image_thumb15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, if the website is directly started with debugging (F5), Visual Studio will attach to native code or managed code. We have to start the website then manually attach to script code, as &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/vstudio/ms241740(v=vs.110).aspx&quot;&gt;MSDN mentions&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you debug script, Managed code must not be selected. You cannot debug script and managed code at the same time in Visual Studio 2005.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is why in Step 4 we do not start website with debugging (F5).&lt;/p&gt;
&lt;p&gt;As the second last picture shows, the index.asp has a [dynamic] tag. Visual Studio does not automatically map it to index.asp from the file system. This means, if a breakpoint is set in a *.asp file, it won’t trigger when running the website. You may have to go back and forth between dynamic file and static file. To have the mapping automatically, IIS is needed.&lt;/p&gt;
&lt;h2&gt;Debugging with Visual Studio 2013/2015 and IIS&lt;/h2&gt;
&lt;p&gt;Here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open IIS manager, change ASP configurations to enable debugging: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb_9.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb_thumb.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Run Visual Studio as administrator.&lt;/li&gt;
&lt;li&gt;Create an empty web application. In Visual Studio 2015, click File –&amp;gt; New –&amp;gt; Project…, then in the new project dialog, search “ASP.NET Web Application”. A WebApplication.csproj file and Web.config file will be created in the web application directory. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Merge website folder to Visual Studio web application folder. In Visual Studio, include all website files into the created empty web application.&lt;/li&gt;
&lt;li&gt;In web application project’s properties, go to Web tab, choose “Local IIS”, create virtual directory in local IIS for this web application.&lt;/li&gt;
&lt;li&gt;In the “Attach to Process” dialog, attach Visual Studio to “Script Code” of IIS process (w3wp.exe). &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb1_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Debugging_13D39/image_thumb1_thumb.png&quot; alt=&quot;image_thumb1&quot; title=&quot;image_thumb1&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Manually start a browser, input the URI of the created virtual directory. Now the breakpoint set in the static .asp file triggers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With this approach, the created WebApplication.csproj file and Web.config file pollute the website folder. Instead of web application, If creating/opening website in Visual Studio, it works the same as IIS Express. Web application has to be created so that Visual Studio can map to the static .asp files in file system during debugging.&lt;/p&gt;
</content:encoded></item><item><title>Shrink Virtual Hard Disk Image (VHD and VHDX) Files</title><link>https://dixin.github.io/posts/shrink-virtual-hard-disk-image-vhd-and-vhdx-files/</link><guid isPermaLink="true">https://dixin.github.io/posts/shrink-virtual-hard-disk-image-vhd-and-vhdx-files/</guid><description>Virtual hard disk image files () grow bigger during the usage. For instance, this is a 20G virtual disk file for a Window</description><pubDate>Fri, 06 May 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Virtual hard disk image files (&lt;a href=&quot;https://technet.microsoft.com/en-us/library/hh831446.aspx&quot;&gt;VHD and VHDX files&lt;/a&gt;) grow bigger during the usage. For instance, this is a 20G virtual disk file for a Windows XP virtual machine:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But the actual storage usage is only 5.3GB (19.9GB total space – 14.6GB free space):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hyper-v Manager provides a button to compact the virtual hard drive:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_29.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_13.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, it never worked directly. After spending time to try around, the following are the steps truly workable.&lt;/p&gt;
&lt;h2&gt;Delete files in VHD/VHDX&lt;/h2&gt;
&lt;p&gt;First of all, delete whatever not needed in the virtual machine. For example, in this Windows XP virtual machine, these entries can be cleared:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C:\Documents and Settings\Administrator\Local Settings\Temp\*&lt;/li&gt;
&lt;li&gt;C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files\*&lt;/li&gt;
&lt;li&gt;C:\WINDOWS\$*&lt;/li&gt;
&lt;li&gt;C:\WINDOWS\SoftwareDistribution\Download\*&lt;/li&gt;
&lt;li&gt;C:\WINDOWS\System32\dllcache\*&lt;/li&gt;
&lt;li&gt;C:\WINDOWS\Temp\*&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, &lt;a href=&quot;https://windirstat.info/index.html&quot;&gt;WinDirStat&lt;/a&gt; is very helpful to identify the sizes of directories/files:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Defrag the partitions&lt;/h2&gt;
&lt;p&gt;After cleaning up inside the VHD/VHDX, the next step is defragment. The built in defragment tool in Windows is not powerful enough for the purpose of shrinking. &lt;a href=&quot;http://www.raxco.com/business/products/perfectdisk-professional&quot;&gt;PerfectDisk&lt;/a&gt; (30 days free trail) could be a nice option:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Start defragment by clicking “Prep for Shrink”. When it is done, click “Boot Time Defrag”:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then virtual machine will be restarted, system files and page files will be defragged:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Shrink the partitions&lt;/h2&gt;
&lt;p&gt;In Windows XP virtual machine, the built in Disk Management Tool cannot shrink the partition. &lt;a href=&quot;http://www.paragon-software.com/home/pm-personal/eshop.html&quot;&gt;Paragon Partition Manager&lt;/a&gt; (free edition) can do that:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_31.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_14.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Reboot is required again:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_33.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_15.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After reboot, it will be done:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_16.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Other tools, like &lt;a href=&quot;http://www.partitionwizard.com/&quot;&gt;MiniTool Partition Manager&lt;/a&gt;, &lt;a href=&quot;http://www.diskgenius.cn&quot;&gt;Disk Genius&lt;/a&gt; (Chinese language), etc., should also work.&lt;/p&gt;
&lt;h2&gt;Shrink the VHD/VHDX files&lt;/h2&gt;
&lt;p&gt;This is the most tricky part. There are several options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use built-in Hyper-v Manager to shrink VHD/VHDX files of a virtual machine. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_35.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_16.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;http://www.bursky.net/wp-content/uploads/2012/07/VhdResizerSetup.zip&quot;&gt;VHD Resizer&lt;/a&gt; to change the size. It only works for VHD, not VHDX.&lt;/li&gt;
&lt;li&gt;Use PowerShell command to shrink VHD/VHDX files:&lt;pre&gt;&lt;code&gt;Resize-VHD –Path .\dixinyan-vmxp.vhdx –ToMinimumSize
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Unfortunately, none of these can work for above virtual hard disk of this Windows XP virtual machine. After trying things around, the following approach works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When shrinking a VHDX, Convert it to VHD then convert it back to VHDX.&lt;/li&gt;
&lt;li&gt;When shrinking a VHD, convert it to VHDX then convert it back to VHD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In PowerShell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Convert-VHD -Path .\dixinyan-vmxp.vhdx -DestinationPath .\dixinyan-vmxp.vhd
Convert-VHD -Path .\dixinyan-vmxp.vhd -DestinationPath .\dixinyan-vmxp.min.vhdx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, The VHDX is shrunk from 20GB to 6GB:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Shrink-a_D28C/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Paste code from Visual Studio 2015 to Windows Live Writer</title><link>https://dixin.github.io/posts/paste-code-from-visual-studio-2015-to-windows-live-writer/</link><guid isPermaLink="true">https://dixin.github.io/posts/paste-code-from-visual-studio-2015-to-windows-live-writer/</guid><description>Now it is close to the end of 2015, but  is still the best Windows blogging tool. For years I use a Windows Live W</description><pubDate>Fri, 22 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Now it is close to the end of 2015, but &lt;a href=&quot;http://windows.microsoft.com/en-us/windows-live/essentials&quot;&gt;Windows Live Writer 2012&lt;/a&gt; is still the best Windows blogging tool. For years I use a Windows Live Writer plugin called &lt;a href=&quot;http://www.11011.net/software/vs2html&quot;&gt;VSPaste&lt;/a&gt; for code snippets. With VSPaste, any code in any language can be copied from Visual Studio, and paste into Windows Live Writer with 100% accurate syntax highlighting.&lt;/p&gt;
&lt;p&gt;However, VSPaste has a problem with Visual Studio 2015 RTM (not with RC) – the pasted HTML code always has a white background: &amp;lt;span style=”background: white;”&amp;gt;code&amp;lt;/span&amp;gt;. To quickly fix this, the easiest way is to decompile the source code of VSPaste.&lt;/p&gt;
&lt;p&gt;VSPaste is a small dll located in Windows Live Writer’s plugin directory: C:\Program Files (x86)\Windows Live\Writer\Plugins\VSPaste.dll. It can be decompiled to a project with source code, by &lt;a href=&quot;https://www.red-gate.com/products/dotnet-development/reflector/&quot;&gt;.NET reflector free trial version&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Reflector will ask for reference assembly, just point it to C:\Program Files (x86)\Windows Live\Writer\WindowsLive.Writer.Api.dll. Then it decompiles VSPaste.dll to a complete C# project.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Paste_DDB8/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now open the VSPaste.csproj, and search for string “background”. Here it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void SyncColors(bool bgOnly)
{
    int? nullable;
    int? nullable2;
    if ((this.background != this.nextBackground) || ((((nullable = this.color).GetValueOrDefault() != (nullable2 = this.nextColor).GetValueOrDefault()) || (nullable.HasValue != nullable2.HasValue)) &amp;amp;&amp;amp; !bgOnly))
    {
        if (this.color.HasValue || this.background.HasValue)
        {
            this.writer.Write(&quot;&amp;lt;/span&amp;gt;&quot;);
        }
        this.color = this.nextColor;
        this.background = this.nextBackground;
        if (this.color.HasValue || this.background.HasValue)
        {
            this.writer.Write(&quot;&amp;lt;span style=\&quot;&quot;);
            if (this.color.HasValue)
            {
                this.writer.Write(&quot;color:&quot;);
                this.writer.Write(this.colors.CssColor(this.color.Value));
            }
            if (this.background.HasValue)
            {
                if (this.color.HasValue)
                {
                    this.writer.Write(&apos;;&apos;);
                }
                this.writer.Write(&quot;background:&quot;);
                this.writer.Write(this.colors.CssColor(this.background.Value));
            }
            this.writer.Write(&quot;\&quot;&amp;gt;&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just comment out the 2 highlighted statement and compile, then copy the new VSPaste.dll to C:\Program Files (x86)\Windows Live\Writer\Plugins. It is done. Please notice only debug build works here. Release build will crash. Now VSPaste works with Visual Studio 2015 again.&lt;/p&gt;
</content:encoded></item><item><title>Download Liked Posts from Tumblr.com</title><link>https://dixin.github.io/posts/download-liked-posts-from-tumblr-com/</link><guid isPermaLink="true">https://dixin.github.io/posts/download-liked-posts-from-tumblr-com/</guid><description>After using tumblr.com for years, a lot of posts have been liked. It would be easier to look up if the contents of these posts are stored to local. Fortunately, tumblr has provided [a set of APIs](htt</description><pubDate>Tue, 12 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After using tumblr.com for years, a lot of posts have been liked. It would be easier to look up if the contents of these posts are stored to local. Fortunately, tumblr has provided &lt;a href=&quot;https://www.tumblr.com/docs/en/api/v2&quot;&gt;a set of APIs&lt;/a&gt; to make this easy, and even an &lt;a href=&quot;https://api.tumblr.com/console&quot;&gt;API console&lt;/a&gt; to play with these APIs. The API client is also provided in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/tumblr.js&quot;&gt;JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/tumblr_client&quot;&gt;Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/tumblr.php&quot;&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/jumblr&quot;&gt;Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/pytumblr&quot;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/tumblr/TMTumblrSDK&quot;&gt;Objective-C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which are all open source.&lt;/p&gt;
&lt;h2&gt;Create application and install dependent modules&lt;/h2&gt;
&lt;p&gt;Here JavaScript would a nice option, since Microsoft has released a &lt;a href=&quot;https://www.visualstudio.com/en-us/features/node-js-vs.aspx&quot;&gt;Node.js Tools&lt;/a&gt; for Visual Studio 2015. So, first, create a Node.js application:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then, install npm modules. Instead of installing the tumblr module directly, here &lt;a href=&quot;https://www.npmjs.com/package/tumblr-auto-auth&quot;&gt;tumblr-auto-auth&lt;/a&gt; is installed. Because tumblr APIs uses OAuth 1.0a, and this tumblr-auto-auth module handles the authentication/authorization. It also installs the tumblr module as its dependency.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also, &lt;a href=&quot;https://github.com/kriskowal/q&quot;&gt;Q&lt;/a&gt; can be installed for promise-based asynchronous programming.&lt;/p&gt;
&lt;h2&gt;Create utility functions&lt;/h2&gt;
&lt;p&gt;The plan is to download the pictures/video in each post, so a download utility function is needed. Node.js does not have such a built-in API, but it is easy to create one in a common module (common.js):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var http = require(&quot;http&quot;),
    fs = require(&quot;fs&quot;),
    Q = require(&quot;q&quot;),

    download = function (url, path) {
        var deferred = Q.defer(),
            file = fs.createWriteStream(path);
        console.log(&quot;Downloading &quot; + url + &quot;to &quot; + path);
        http.get(url, function (response) {
            response.pipe(file);
            file.on(&quot;finish&quot;, function () {
                file.close(deferred.resolve);
            });
        }).on(&quot;error&quot;, function (error) {
            fs.unlink(path);
            deferred.reject(error);
        });
        return deferred.promise;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It simply downloads the specified URL to the specified file system path. And Q is used to convert the callback style asynchronous programming model into promise style. This is very useful to stay away from &lt;a href=&quot;https://strongloop.com/strongblog/node-js-callback-hell-promises-generators/&quot;&gt;callback hell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To save the downloaded file to local, a file name is needed. The easiest way is to directly use the file name from the URL. But it would be nice if the file name can have more semantics, which will be very helpful for search. So the post id and the post summary text can be used as the local file name. Notice not all the characters in the text can be used in file names. So another utility function is needed to remove those &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#file_and_directory_names&quot;&gt;reversed and disallowed characters&lt;/a&gt; from text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;removeReservedCharactersFromFileName = function (fileName) {
        // https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#file_and_directory_names
        return fileName.replace(/[&amp;lt;&amp;gt;:&quot;/\\|?*\x00-\x1F\r\n\t]/g, &quot;&quot;);
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then export these 2 functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = {
    download: download,
    removeReservedCharactersFromFileName: removeReservedCharactersFromFileName,
    exists: exists
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Download post’s pictures/video files then unlike post&lt;/h2&gt;
&lt;p&gt;Now a tumblr module (tumblr.js) can be created. The first step is to create a tumblr client, with tumblr-auto-auth, this is extremely simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var path = require(&quot;path&quot;),
    util = require(&quot;util&quot;),
    Q = require(&quot;q&quot;),
    tumblr = require(&quot;tumblr-auto-auth&quot;),
    common = require(&quot;./common&quot;),

    getClient = function (options) {
        var deferred = Q.defer();
        tumblr.getAuthorizedClient({
            userEmail: options.userEmail,
            userPassword: options.userPassword,
            appConsumerKey: options.appConsumerKey,
            appSecretKey: options.appSecretKey,
            debug: options.debug
        }, function (error, client) {
            if (error) {
                deferred.reject(error);
            } else {
                options.client = client;
                deferred.resolve(options);
            }
        });
        return deferred.promise;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Q is consistently used for asynchrony.&lt;/p&gt;
&lt;p&gt;Then the created client can be used to pull the liked posts of the specified user from tumblr. Just call client.likes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getLikes = function (options) {
        var deferred = Q.defer();
        options.client.likes(options, function (error, data) {
            if (error) {
                deferred.reject(error);
            } else {
                console.log(&quot;Likes: &quot; + data.liked_count);
                options.posts = data.liked_posts;
                options.likesCount = data.liked_count;
                deferred.resolve(options);
            }
        });
        return deferred.promise;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will send a GET request to tumblr. The response will be a JSON data. data.liked_posts is an array of post objects, and data.liked_count is the total count of liked posts all time.&lt;/p&gt;
&lt;p&gt;Now it is time to download the contents of each post. A post can have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one or more pictures&lt;/li&gt;
&lt;li&gt;one video file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All files will be downloaded by calling common.download, which was defined a moment ago:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;downloadPost = function (post, directory, getFileName) {
        var downloads = [];
        console.log(&quot;Processing &quot; + post.post_url);
        if (post.photos) { // Post has pictures.
            post.photos.forEach(function (photo, index) {
                var url = photo.original_size.url;
                var file = path.join(directory, getFileName(post, url, index));
                downloads.push(common.download(url, file).thenResolve({
                    post: post, 
                    url: url, 
                    file: file,
                    type: &quot;photo&quot;
                }));
            });
        }
        if (post.video_url) { // Post has videos.
            var url = post.video_url;
            var file = path.join(directory, getFileName(post, url));
            downloads.push(common.download(url, file).thenResolve({
                post: post, 
                url: url, 
                file: file,
                type: &quot;video&quot;
            }));
        }
        return Q.all(downloads);
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since common.download returns a promise object, all these promise objects can be pushed to a promise array, then Q.all can be called to composite them to a single promise object. Q.all is similar to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd270695.aspx&quot;&gt;Task.WaitAll&lt;/a&gt; in .NET.&lt;/p&gt;
&lt;p&gt;Also a getFileName function is used to generate file name with post id and file URL (either URL of a picture, or URL of a video):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getFileName = function (post, url, index) {
        var summary = post.summary ? common.removeReservedCharactersFromFileName(post.summary).trim() : &quot;&quot;,
            extension = url.split(&quot;.&quot;).pop();
        summary = summary ? &quot; &quot; + summary.substring(0, 30) : &quot;&quot;;
        index = index ? index : 0;
        // return `${post.id} ${index}${summary}.${extension}`;
        return post.id + &quot; &quot; + index + summary + &quot;.&quot; + extension;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, Node.js Tools for Visual Studio does not support &lt;a href=&quot;http://www.ecma-international.org/ecma-262/6.0/&quot;&gt;ECMAScript 2015/ES 6&lt;/a&gt;, even though &lt;a href=&quot;https://nodejs.org/en/docs/es6/&quot;&gt;Node.js already support it&lt;/a&gt;. So here the old string concatenation syntax is applied instead of the new &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings&quot;&gt;template string&lt;/a&gt; syntax.&lt;/p&gt;
&lt;p&gt;After finishing downloading all files in a post, this post can be removed from liked posts list. Tumblr client has a unlike API for this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unlikePost = function (options) {
        var deferred = Q.defer();
        console.log(&quot;Unliking post &quot; + options.post.post_url);
        options.client.unlike(options.post.id, options.post.reblog_key, function (error, data) {
            if (error) {
                deferred.reject(error);
            } else {
                deferred.resolve(options);
            }
        });
        return deferred.promise;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is time to composite these steps together. They all return a promise, so it is quite easy and straightforword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;downloadAllAndUnlike = function (options) {
        getClient(options) // Get tumblr client.
            .then(getLikes) // Get tumblr liked post.
            .then(function (options) {
                if (options.likesCount &amp;gt; 0 &amp;amp;&amp;amp; options.posts &amp;amp;&amp;amp; options.posts.length &amp;gt; 0) {
                    // If there is any liked post.  
                    Q.all(options.posts.map(function (post) { // Download each liked post.
                        return downloadPost(post, options.directory, getFileName).then(function (download) {
                            return unlikePost({ // After downloading all files of the tumblr post, unlike it
                                client: options.client,
                                post: post
                            }).thenResolve(download);
                        });
                    })).then(function (posts) { // After downloading and unliking all tumblr post, log them.
                        if (util.isArray(posts)) {
                            posts.forEach(console.log);
                        } else {
                            console.log(posts);
                        }
                    }, function (errors) { // If there is error, log it.
                        if (util.isArray(errors)) {
                            errors.forEach(console.error);
                        } else {
                            console.error(errors);
                        }
                    }).then(function() {
                        downloadAllAndUnlike(options); // Download gain, recursively.
                    });
                }
                // If there is not any liked post, stop. Recursion terminates.
            });
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling tumblr API to get liked posts, the API returns 50 posts even when there is more. So, above downloadAllAndUnlike is a recursive function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When there is any liked post to download, it calls itself recursively to try to download again.&lt;/li&gt;
&lt;li&gt;When there is nothing to download, the recursion terminates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And finally, export downloadAllAndUnlike function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = {
    downloadAllAndUnlike: downloadAllAndUnlike
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Start working&lt;/h2&gt;
&lt;p&gt;To start downloading, specify a startup file for this Node.js application:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Download_12B7F/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the startup file (main.js), just call downloadAllAndUnlike function of the tumblr module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var tumblr = require(&quot;./tumblr&quot;);

tumblr.downloadAllAndUnlike({
    userEmail: &quot;dixinyan@live.com&quot;,
    userPassword: &quot;...&quot;,
    appConsumerKey: &quot;...&quot;,
    appSecretKey: &quot;...&quot;,
    offset: 5,
    limit: 51,
    directory: &quot;D:\\Downloads\\Tumblr&quot;,
    after: 1
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The user email, user password, application consumer key, and application secrete key are required. To get the application consumer/secrete key, just &lt;a href=&quot;https://www.tumblr.com/oauth/apps&quot;&gt;register an application in tumblr&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Query Operating System Processes in C#</title><link>https://dixin.github.io/posts/query-operating-system-processes-in-c/</link><guid isPermaLink="true">https://dixin.github.io/posts/query-operating-system-processes-in-c/</guid><description>.NET framework provides some process APIs in  class. Only some basic information of process can be</description><pubDate>Sat, 02 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;.NET framework provides some process APIs in &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx&quot;&gt;System.Diagnostics.Process&lt;/a&gt; class. Only some basic information of process can be queried with these APIs. .NET does not have APIS for other information, for example, a process’s parent process/child processes. There are some options to query process informations, like performance counter, P/Invoke, etc. Querying [Win32_Process](// https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372.aspx) class of &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_Management_Instrumentation&quot;&gt;WMI&lt;/a&gt; could be an easier way.&lt;/p&gt;
&lt;p&gt;The definition of Win32_Process class can be translated to C# class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Win32Process
{
    public const string WmiClassName = &quot;Win32_Process&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And these are all the properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerDisplay(&quot;Name = {Name}; Id = {ProcessId}&quot;)]
public partial class Win32Process
{
    public string Caption { get; }

    public string CommandLine { get; }

    public string CreationClassName { get; }

    public DateTime? CreationDate { get; }

    public string CSCreationClassName { get; }

    public string CSName { get; }

    public string Description { get; }

    public string ExecutablePath { get; }

    public ushort? ExecutionState { get; }

    public string Handle { get; }

    public uint? HandleCount { get; }

    public DateTime? InstallDate { get; }

    public ulong? KernelModeTime { get; }

    public uint? MaximumWorkingSetSize { get; }

    public uint? MinimumWorkingSetSize { get; }

    public string Name { get; }

    public string OSCreationClassName { get; }

    public string OSName { get; }

    public ulong? OtherOperationCount { get; }

    public ulong? OtherTransferCount { get; }

    public uint? PageFaults { get; }

    public uint? PageFileUsage { get; }

    public uint? ParentProcessId { get; }

    public uint? PeakPageFileUsage { get; }

    public ulong? PeakVirtualSize { get; }

    public uint? PeakWorkingSetSize { get; }

    public uint? Priority { get; }

    public ulong? PrivatePageCount { get; }

    public uint? ProcessId { get; }

    public uint? QuotaNonPagedPoolUsage { get; }

    public uint? QuotaPagedPoolUsage { get; }

    public uint? QuotaPeakNonPagedPoolUsage { get; }

    public uint? QuotaPeakPagedPoolUsage { get; }

    public ulong? ReadOperationCount { get; }

    public ulong? ReadTransferCount { get; }

    public uint? SessionId { get; }

    public string Status { get; }

    public DateTime? TerminationDate { get; }

    public uint? ThreadCount { get; }

    public ulong? UserModeTime { get; }

    public ulong? VirtualSize { get; }

    public string WindowsVersion { get; }

    public ulong? WorkingSetSize { get; }

    public ulong? WriteOperationCount { get; }

    public ulong? WriteTransferCount { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is much more information then .NET built-in Process class. It is tagged with [&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms228992.aspx&quot;&gt;DebuggerDisplay&lt;/a&gt;] attribute to be friendly at debugging time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Query-Operating-System-Processes-in-C_9DCE/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Query-Operating-System-Processes-in-C_9DCE/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To query Win32_Process class from WMI, the following Wmi.Query method can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Wmi
{
    public static ManagementObject[] Query(ObjectQuery objectQuery, ManagementScope managementScope = null)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(objectQuery != null);

        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(
            managementScope ?? new ManagementScope(), // Default ManagementPath: \\.\root\cimv2.
            objectQuery)) // Default QueryLangauge: WQL.
        using (ManagementObjectCollection processes = searcher.Get())
        {
            return processes.OfType&amp;lt;ManagementObject&amp;gt;().ToArray();
        }
    }

    public static ManagementObject[] Query
        (string query, ManagementScope managementScope = null) =&amp;gt; Query(new ObjectQuery(query), managementScope);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2 overloads are provided for Query method, one general version accepts a WMI ObjectQuery, the other accepts a string query. The string version will be used in the example in this post. The ManagementScope parameter will be useful, for example, when querying another computer. By default it is null, and the query will work in local machine.&lt;/p&gt;
&lt;p&gt;The Query method returns general ManagementObject, which can be converted to a Win32Process object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Win32Process
{
    public Win32Process(ManagementObject process)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(process != null);

        this.Caption = process[nameof(this.Caption)] as string;
        this.CommandLine = process[nameof(this.CommandLine)] as string;
        this.CreationClassName = process[nameof(this.CreationClassName)] as string;
        this.CreationDate =
            (process[nameof(this.CreationDate)] as string)?.Forward(ManagementDateTimeConverter.ToDateTime);
        this.CSCreationClassName = process[nameof(this.CSCreationClassName)] as string;
        this.CSName = process[nameof(this.CSName)] as string;
        this.Description = process[nameof(this.Description)] as string;
        this.ExecutablePath = process[nameof(this.ExecutablePath)] as string;
        this.ExecutionState = (ushort?)process[nameof(this.ExecutionState)];
        this.Handle = process[nameof(this.Handle)] as string;
        this.HandleCount = (uint?)process[nameof(this.HandleCount)];
        this.InstallDate =
            (process[nameof(this.InstallDate)] as string)?.Forward(ManagementDateTimeConverter.ToDateTime);
        this.KernelModeTime = (ulong?)process[nameof(this.KernelModeTime)];
        this.MaximumWorkingSetSize = (uint?)process[nameof(this.MaximumWorkingSetSize)];
        this.MinimumWorkingSetSize = (uint?)process[nameof(this.MinimumWorkingSetSize)];
        this.Name = process[nameof(this.Name)] as string;
        this.OSCreationClassName = process[nameof(this.OSCreationClassName)] as string;
        this.OSName = process[nameof(this.OSName)] as string;
        this.OtherOperationCount = (ulong?)process[nameof(this.OtherOperationCount)];
        this.OtherTransferCount = (ulong?)process[nameof(this.OtherTransferCount)];
        this.PageFaults = (uint?)process[nameof(this.PageFaults)];
        this.PageFileUsage = (uint?)process[nameof(this.PageFileUsage)];
        this.ParentProcessId = (uint?)process[nameof(this.ParentProcessId)];
        this.PeakPageFileUsage = (uint?)process[nameof(this.PeakPageFileUsage)];
        this.PeakVirtualSize = (ulong?)process[nameof(this.PeakVirtualSize)];
        this.PeakWorkingSetSize = (uint?)process[nameof(this.PeakWorkingSetSize)];
        this.Priority = (uint?)process[nameof(this.Priority)];
        this.PrivatePageCount = (ulong?)process[nameof(this.PrivatePageCount)];
        this.ProcessId = (uint?)process[nameof(this.ProcessId)];
        this.QuotaNonPagedPoolUsage = (uint?)process[nameof(this.QuotaNonPagedPoolUsage)];
        this.QuotaPagedPoolUsage = (uint?)process[nameof(this.QuotaPagedPoolUsage)];
        this.QuotaPeakNonPagedPoolUsage = (uint?)process[nameof(this.QuotaPeakNonPagedPoolUsage)];
        this.QuotaPeakPagedPoolUsage = (uint?)process[nameof(this.QuotaPeakPagedPoolUsage)];
        this.ReadOperationCount = (ulong?)process[nameof(this.ReadOperationCount)];
        this.ReadTransferCount = (ulong?)process[nameof(this.ReadTransferCount)];
        this.SessionId = (uint?)process[nameof(this.SessionId)];
        this.Status = process[nameof(this.Status)] as string;
        this.TerminationDate =
            (process[nameof(this.TerminationDate)] as string)?.Forward(ManagementDateTimeConverter.ToDateTime);
        this.ThreadCount = (uint?)process[nameof(this.ThreadCount)];
        this.UserModeTime = (ulong?)process[nameof(this.UserModeTime)];
        this.VirtualSize = (ulong?)process[nameof(this.VirtualSize)];
        this.WindowsVersion = process[nameof(this.WindowsVersion)] as string;
        this.WorkingSetSize = (ulong?)process[nameof(this.WorkingSetSize)];
        this.WriteOperationCount = (ulong?)process[nameof(this.WriteOperationCount)];
        this.WriteTransferCount = (ulong?)process[nameof(this.WriteTransferCount)];
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is to define methods to query process information from MWI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ProcessHelper
{
    public static IEnumerable&amp;lt;Win32Process&amp;gt; All
        (ManagementScope managementScope = null) =&amp;gt; Wmi
            .Query($&quot;SELECT * FROM {Win32Process.WmiClassName}&quot;, managementScope)
            .Select(process =&amp;gt; new Win32Process(process));

    public static Win32Process ById
        (uint processId, ManagementScope managementScope = null) =&amp;gt; Wmi
            .Query(
                $&quot;SELECT * FROM {Win32Process.WmiClassName} WHERE {nameof(Win32Process.ProcessId)} = {processId}&quot;,
                managementScope)
            .Select(process =&amp;gt; new Win32Process(process)).FirstOrDefault();

    public static IEnumerable&amp;lt;Win32Process&amp;gt; ByName
        (string name, ManagementScope managementScope = null) =&amp;gt; Wmi
            .Query(
                $&quot;SELECT * FROM {Win32Process.WmiClassName} WHERE {nameof(Win32Process.Name)} = &apos;{name}&apos;&quot;,
                managementScope)
            .Select(process =&amp;gt; new Win32Process(process));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The All method queries all processes in the specified ManagementScope. ById/ByName queries by process id/name.&lt;/p&gt;
&lt;p&gt;Besides querying rich information of processes, with these methods it is easy to traverse the process tree. The following ParentProcess method queries the direct parent process, if there is one. And the AllParentProcesses method queries all the parent processes in the tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ProcessHelper
{
    public static Win32Process ParentProcess(uint childProcessId, ManagementScope managementScope = null)
        =&amp;gt; ById(childProcessId)?.ParentProcessId?.Forward(parentProcessId =&amp;gt; ById(parentProcessId));

    public static IEnumerable&amp;lt;Win32Process&amp;gt; AllParentProcess(
        uint childProcessId,
        ManagementScope managementScope = null)
    {
        Win32Process parentProcess =
            ById(childProcessId)?.ParentProcessId?.Forward(parentProcessId =&amp;gt; ById(parentProcessId));
        return parentProcess == null
            ? Enumerable.Empty&amp;lt;Win32Process&amp;gt;()
            : Enumerable.Repeat(parentProcess, 1).Concat(parentProcess.ProcessId.HasValue
                ? AllParentProcess(parentProcess.ProcessId.Value)
                : Enumerable.Empty&amp;lt;Win32Process&amp;gt;());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following ChildProcesses method queries the direct child processes. And the AllChildProcesses method queries all child processes in the tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ProcessHelper
{
    public static IEnumerable&amp;lt;Win32Process&amp;gt; ChildProcesses
        (uint parentProcessId, ManagementScope managementScope = null) =&amp;gt; Wmi
            .Query(
                $&quot;SELECT * FROM {Win32Process.WmiClassName} WHERE {nameof(Win32Process.ParentProcessId)} = {parentProcessId}&quot;,
                managementScope)
            .Select(process =&amp;gt; new Win32Process(process));

    public static IEnumerable&amp;lt;Win32Process&amp;gt; AllChildProcesses
        (uint parentProcessId, ManagementScope managementScope = null)
    {
        IEnumerable&amp;lt;Win32Process&amp;gt; childProcesses = Wmi
            .Query(
                $&quot;SELECT * FROM {Win32Process.WmiClassName} WHERE {nameof(Win32Process.ParentProcessId)} = {parentProcessId}&quot;,
                managementScope).Select(process =&amp;gt; new Win32Process(process));
        return childProcesses.Concat(childProcesses.SelectMany(process =&amp;gt; process.ProcessId.HasValue
            ? AllChildProcesses(process.ProcessId.Value, managementScope)
            : Enumerable.Empty&amp;lt;Win32Process&amp;gt;()));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Management&quot;&gt;Wmi and Win32Process&lt;/a&gt; classes are uploaded to &lt;a href=&quot;https://github.com/Dixin/CodeSnippets&quot;&gt;GitHub&lt;/a&gt;, so is the &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin/Diagnostics&quot;&gt;ProcessHelper&lt;/a&gt; class. The &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/tree/master/Dixin.Tests/Diagnostics&quot;&gt;unit tests&lt;/a&gt; can be also found here.&lt;/p&gt;
</content:encoded></item><item><title>C# 6.0 Exception Filter and when Keyword</title><link>https://dixin.github.io/posts/c-6-0-exception-filter-and-when-keyword/</link><guid isPermaLink="true">https://dixin.github.io/posts/c-6-0-exception-filter-and-when-keyword/</guid><description>C# 6.0 introduces a new feature exception filter and a new keyword when. , but exception filter/when keyword is not.</description><pubDate>Mon, 07 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# 6.0 introduces a new feature exception filter and a new keyword when. &lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;Many C# features/keywords are syntactic sugars&lt;/a&gt;, but exception filter/when keyword is not.&lt;/p&gt;
&lt;p&gt;To examine this feature, a few helper methods can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExceptionFilter
{
    private static void A() =&amp;gt; B();

    private static void B() =&amp;gt; C();

    private static void C() =&amp;gt; D();

    private static void D()
    {
        int localVariable1 = 1;
        int localVariable2 = 2;
        int localVariable3 = 3;
        int localVariable4 = 4;
        int localVariable5 = 5;
        throw new OperationCanceledException(nameof(ExceptionFilter));
    }

    private static bool Log(this object message, bool result = false)
    {
        Trace.WriteLine(message);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods can make up a call stack, with some local variables. The Log method can log a Exception object and return a specified bool value.&lt;/p&gt;
&lt;h2&gt;Syntax&lt;/h2&gt;
&lt;p&gt;The when keyword works like if. A when condition is a predicate expression, which can be appended to a catch block. If the predicate expression is evaluated to be true, the associated catch block is executed; otherwise, the catch block is ignored.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Filter()
{
    try
    {
        A();
    }
    catch (OperationCanceledException exception) when (string.Equals(nameof(ExceptionFilter), exception.Message, StringComparison.Ordinal))
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the earlier preview of C# 6.0, the if keyword was used. In the final release, if is replaced by when, because some improper format can make catch-if confusing, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Filter()
{
    try
    {
        A();
    }
    catch (OperationCanceledException exception) 
 // {
        if (string.Equals(nameof(ExceptionFilter), exception.Message, StringComparison.Ordinal))
        {
        }
 // }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code format looks just like a if statement inside the catch block.&lt;/p&gt;
&lt;p&gt;Now it is already March 2016, the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/0yd65esw.aspx&quot;&gt;MSDN document for C# exception filter&lt;/a&gt; still uses the if keyword in the examples:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;Before C# 6.0, it is very common to catch an exception, then log or filter it, and re-throw:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Catch()
{
    try
    {
        A();
    }
    catch (Exception exception)
    {
        exception.Log();
        throw;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 6.0 provides a way to log or filter an exception before catching it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void When()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log())
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the Log method will log the exception, and return false. So the catch block will not be executed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/icsharpcode/ILSpy&quot;&gt;ILSpy&lt;/a&gt; and ildasm (located in C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\) can be used to view the &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_CIL_instructions&quot;&gt;compiled IL&lt;/a&gt;. In the Catch method, the catch-log-throw pattern will be compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.method private hidebysig static void  Catch() cil managed
{
    .maxstack  2
    .locals init ([0] class [mscorlib]System.Exception exception)
    IL_0000:  nop
    .try
    {
        IL_0001:  nop
        IL_0002:  call       void Dixin.Console.Program::A()
        IL_0007:  nop
        IL_0008:  nop
        IL_0009:  leave.s    IL_0017
    }  // end .try
    catch [mscorlib]System.Exception 
    {
        IL_000b:  stloc.0
        IL_000c:  nop
        IL_000d:  ldloc.0
        IL_000e:  ldc.i4.0
        IL_000f:  call       bool Dixin.Console.Program::Log(object,
                                                            bool)
        IL_0014:  pop
        IL_0015:  rethrow
    }  // end handler
    IL_0017:  ret
} // end of method Program::Catch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is nothing new or surprising. And When method is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.method private hidebysig static void  When() cil managed
{
    .maxstack  2
    .locals init ([0] class [mscorlib]System.Exception exception,
                [1] bool V_1)
    IL_0000:  nop
    .try
    {
        IL_0001:  nop
        IL_0002:  call       void Dixin.Console.Program::A()
        IL_0007:  nop
        IL_0008:  nop
        IL_0009:  leave.s    IL_002a

    }  // end .try
    filter
    {
        IL_000b:  isinst     [mscorlib]System.Exception
        IL_0010:  dup
        IL_0011:  brtrue.s   IL_0017

        IL_0013:  pop
        IL_0014:  ldc.i4.0
        IL_0015:  br.s       IL_0024

        IL_0017:  stloc.0
        IL_0018:  ldloc.0
        IL_0019:  ldc.i4.0
        IL_001a:  call       bool Dixin.Console.Program::Log(object,
                                                            bool)
        IL_001f:  stloc.1
        IL_0020:  ldloc.1
        IL_0021:  ldc.i4.0
        IL_0022:  cgt.un
        IL_0024:  endfilter
    }  // end filter
    {  // handler
        IL_0026:  pop
        IL_0027:  nop
        IL_0028:  rethrow
    }  // end handler
    IL_002a:  ret
} // end of method Program::When
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The catch keyword is gone, and C# when condition is compiled to a IL filter block. In the filter block, it checks if the exception is of Exception type. If so, it calls the Log method. Apparently, exception filter is not syntactic sugar. It is a CLR feature.&lt;/p&gt;
&lt;h2&gt;Runtime: stack unwinding&lt;/h2&gt;
&lt;p&gt;The catch block and when predicate refers to the same exception object. In the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Log()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log(true))
    {
        exception.Log();
        throw;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the when predicate, the Log method returns true, so in the catch block, Log will be called again. These 2 Log calls print out exactly the same information:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;System.OperationCanceledException: ExceptionFilter at Dixin.Common.ExceptionFilter.D() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 21 at Dixin.Common.ExceptionFilter.C() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 12 at Dixin.Common.ExceptionFilter.B() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 10 at Dixin.Common.ExceptionFilter.A() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 8 at Dixin.Common.ExceptionFilter.Log() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 91&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apparently, in both cases, the exception object’s StackTrace property has the call stack of A/B/C/D methods, as expected.&lt;/p&gt;
&lt;p&gt;The real difference is the CLR stack (not the exception object’s StackTrace string property). To demonstrate this, set 2 breakpoints at 2 Log calls:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When the exception filter is executed:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current stack (again, not the exception object’s StackTrace property) is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 93 [Native to Managed Transition] ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.D() Line 21 ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.C() Line 12 ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.B() Line 10 ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.A() Line 8 ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 91 ConsoleApplication2.exe!Dixin.Console.Program.Main() Line 110&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Next, when the catch block is executed:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current stack becomes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 95 ConsoleApplication2.exe!Dixin.Console.Program.Main() Line 110&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This magic here is called stack unwinding: exception filter does not unwind the stack, and catch block does unwind. When executing catch block, this catch block’s method becomes the top frame of the stack. As a result, all the methods called by current method are removed from the stack. In contrast, exception filter can be helpful for runtime debugging. For example, if above Catch method is executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Catch()
{
    try
    {
        A();
    }
    catch (Exception exception)
    {
        exception.Log();
        throw;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;at runtime the debugger breaks at the throw statement in the catch block:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The stack is unwound. As a result the debugger cannot see the exception is actually thrown by D.&lt;/p&gt;
&lt;p&gt;When executing the other When method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void When()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log())
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Log method always returns false, so that the stack will not be unwound by catch block. This time the debugger breaks in method D, where the exception is actually thrown:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/C-6.0-Exception-Filter_11DE8/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice in the Locals windows and Call Stack window, all information are available for debugger.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;C# 6.0 exception filter and when keyword is not a syntactic sugar. It is a CLR feature. Unlike catch block, exception filter does not unwind the call stack, which is helpful at runtime.&lt;/p&gt;
</content:encoded></item><item><title>Configure Git for Visual Studio 2015</title><link>https://dixin.github.io/posts/configure-git-for-visual-studio-2015/</link><guid isPermaLink="true">https://dixin.github.io/posts/configure-git-for-visual-studio-2015/</guid><description>After installing , the initial Git configurations can be viewed with git config –list:</description><pubDate>Thu, 03 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After installing &lt;a href=&quot;https://git-scm.com/download/win&quot;&gt;Git&lt;/a&gt;, the initial Git configurations can be viewed with git config –list:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;core.symlinks=false core.autocrlf=true color.diff=auto color.status=auto color.branch=auto color.interactive=true pack.packsizelimit=2g help.format=html http.sslcainfo=/bin/curl-ca-bundle.crt sendemail.smtpserver=/bin/msmtp.exe diff.astextplain.textconv=astextplain rebase.autosquash=true core.repositoryformatversion=0 core.filemode=false core.bare=false core.logallrefupdates=true core.symlinks=false core.ignorecase=true core.hidedotfiles=dotGitOnly remote.origin.url=&lt;a href=&quot;https://github.com/Dixin/CodeSnippets.git&quot;&gt;https://github.com/Dixin/CodeSnippets.git&lt;/a&gt; remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* branch.master.remote=origin branch.master.merge=refs/heads/master&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is nothing for Visual Studio.&lt;/p&gt;
&lt;p&gt;After installing &lt;a href=&quot;https://desktop.github.com/&quot;&gt;GitHub for Windows Desktop&lt;/a&gt;, it provides 2 configurations for Visual Studio 2012 and 2013, but nothing for 2015:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;difftool.vs2012.cmd=&quot;c:/program files (x86)/microsoft visual studio 11.0/common7 /ide/devenv.exe&quot; &apos;//diff&apos; &quot;$LOCAL&quot; &quot;$REMOTE&quot; difftool.vs2013.cmd=&quot;c:/program files (x86)/microsoft visual studio 12.0/common7 /ide/devenv.exe&quot; &apos;//diff&apos; &quot;$LOCAL&quot; &quot;$REMOTE&quot;&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The configurations for Visual Studio 2015 can be added to local repository/all repositories/all users with git config --edit –local/global/system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[diff]
    tool = vs2015
[difftool]
    prompt = true
[difftool &quot;vs2015&quot;]
    cmd = \&quot;C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\vsdiffmerge.exe\&quot; \&quot;$LOCAL\&quot; \&quot;$REMOTE\&quot; //t
    keepbackup = false
    trustexistcode = true
[merge]
    tool = vs2015
[mergetool]
    prompt = true
[mergetool &quot;vs2015&quot;]
    cmd = \&quot;C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\vsdiffmerge.exe\&quot; \&quot;$REMOTE\&quot; \&quot;$LOCAL\&quot; \&quot;$BASE\&quot; \&quot;$MERGED\&quot; //m
    keepbackup = false
    trustexistcode = true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this, Git works correctly in Visual Studio 2015. The following is a screenshot of merging conflicts in Visual Studio 2015. The left panel is remote file, right panel is local file, and lower panel is merge result:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/29e98b02b219_F192/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/29e98b02b219_F192/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Batch Processing Compression Archives with Different Formats (RAR, ISO, 7z, Zip, …) in C#</title><link>https://dixin.github.io/posts/batch-processing-compression-archive-with-different-formats-in-c-sharp/</link><guid isPermaLink="true">https://dixin.github.io/posts/batch-processing-compression-archive-with-different-formats-in-c-sharp/</guid><description>](http://techheavy.s3.a</description><pubDate>Wed, 02 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://techheavy.s3.amazonaws.com/wp-content/uploads/2014/02/compress.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Batch-processing-RAR-and-Zip_13247/compress_89982e7a-0617-49d7-af84-f4364e62426c.jpg&quot; alt=&quot;compress&quot; title=&quot;compress&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Recently I need to batch process some compressed files in several hard disk drives - Some &lt;a href=&quot;http://en.wikipedia.org/wiki/RAR&quot;&gt;RAR&lt;/a&gt;/&lt;a href=&quot;http://en.wikipedia.org/wiki/ISO_image&quot;&gt;ISO&lt;/a&gt;/&lt;a href=&quot;http://en.wikipedia.org/wiki/7z&quot;&gt;7z&lt;/a&gt; files need to unified to &lt;a href=&quot;http://en.wikipedia.org/wiki/Zip_(file_format)&quot;&gt;zip&lt;/a&gt; format; And some compression archives has to be extracted; etc..&lt;/p&gt;
&lt;h2&gt;C# options for compression archive (RAR, ISO, 7z, zip, …) processing&lt;/h2&gt;
&lt;p&gt;For compression archive processing, there are some nice .NET libraries, like &lt;a href=&quot;https://github.com/adamhathcock/sharpcompress&quot;&gt;SharpCompress&lt;/a&gt;. For example, it provides an easy way to programmatically extract an archive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ArchiveFactory.WriteToDirectory(rarFile, destinationDirectory);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So there creates an possibility to convert RAR to zip, by extracting RAR then re-compressing to zip.&lt;/p&gt;
&lt;p&gt;To create or extract zip files, now it seems much easier, since .NET has a built-in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.compression.zipfile(v=vs.110).aspx&quot;&gt;ZipFile class&lt;/a&gt; since &lt;a href=&quot;http://en.wikipedia.org/wiki/.NET_Framework_version_history#.NET_Framework_4.5&quot;&gt;4.5&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ZipFile.CreateFromDirectory(destinationDirectory, zipFile, CompressionLevel.Optimal, false);
ZipFile.ExtractToDirectory(zipFile, destinationDirectory);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the third free solution is &lt;a href=&quot;http://en.wikipedia.org/wiki/7-Zip&quot;&gt;7-Zip&lt;/a&gt;. I used it for years and I am satisfied with its compression ratio.&lt;/p&gt;
&lt;h3&gt;The entry name encoding/decoding problem&lt;/h3&gt;
&lt;p&gt;When examining these options, my biggest concern is the entry name encoding. When I use Windows File Explorer to process zip archives, the entry name encoding/decoding has been a nightmare for years. I got non-English file/directory names like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;╞╗╣√╕╔╧╕░√╡─│╔╣ª╙ª╙├.pdf&lt;/li&gt;
&lt;li&gt;╞╗╣√╕╔╧╕░√╬¬└╧╗»║═╩▄╦≡╡─╞ñ╖⌠╠ß╣⌐┴╦╨┬╡─╔·╗·.pdf&lt;/li&gt;
&lt;li&gt;┤╠╝ñ╞ñ╖⌠╕╔╧╕░√┤┘╜°╞ñ╖⌠╖╡└╧╗╣═».pdf&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc..&lt;/p&gt;
&lt;p&gt;So I looked into the source code of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.compression(v=vs.110).aspx&quot;&gt;System.IO.Compression.dll&lt;/a&gt;. This is how it handles file/directory names in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry%28v=vs.110%29.aspx&quot;&gt;ZipArchiveEntry class&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private string DecodeEntryName(byte[] entryNameBytes)
{
    Encoding encoding;
    if ((ushort)(this._generalPurposeBitFlag &amp;amp; ZipArchiveEntry.BitFlagValues.UnicodeFileName) == 0)
    {
        encoding = ((this._archive == null) ? Encoding.GetEncoding(0) : (this._archive.EntryNameEncoding ?? Encoding.GetEncoding(0)));
    }
    else
    {
        encoding = Encoding.UTF8;
    }
    return new string(encoding.GetChars(entryNameBytes));
}

private byte[] EncodeEntryName(string entryName, out bool isUTF8)
{
    Encoding encoding;
    if (this._archive != null &amp;amp;&amp;amp; this._archive.EntryNameEncoding != null)
    {
        encoding = this._archive.EntryNameEncoding;
    }
    else
    {
        encoding = (ZipHelper.RequiresUnicode(entryName) ? Encoding.UTF8 : Encoding.GetEncoding(0));
    }
    isUTF8 = (encoding is UTF8Encoding &amp;amp;&amp;amp; encoding.Equals(Encoding.UTF8));
    return encoding.GetBytes(entryName);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The underlined Encoding.GetEncoding(0) &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/wzsz3bk3%28v=vs.110%29.aspx&quot;&gt;is the flaky part&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ANSI code pages can be different on different computers, or can be changed for a single computer, leading to data corruption. For this reason, encoding and decoding data using the default code page returned by Encoding.GetEncoding(0) is not recommended.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In SharpCompress, entry name is handled in &lt;a href=&quot;https://github.com/adamhathcock/sharpcompress/blob/master/SharpCompress/Common/Zip/Headers/ZipFileEntry..cs&quot;&gt;ZipFileEntry class&lt;/a&gt; and &lt;a href=&quot;https://github.com/adamhathcock/sharpcompress/blob/master/SharpCompress/Common/ArchiveEncoding.cs&quot;&gt;ArchiveEncoding class&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal abstract class ZipFileEntry : ZipHeader
{
    protected string DecodeString(byte[] str)
    {
        if (FlagUtility.HasFlag(Flags, HeaderFlags.UTF8))
        {
            return Encoding.UTF8.GetString(str, 0, str.Length);
        }
        return ArchiveEncoding.Default.GetString(str, 0, str.Length);
    }
}

public class ArchiveEncoding
{
    static ArchiveEncoding()
    {
#if PORTABLE || NETFX_CORE
        Default = Encoding.UTF8;
        Password = Encoding.UTF8;
#else
        Default = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
        Password = Encoding.Default;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The underlined CultureInfo.CurrentCulture is not the preference either.&lt;/p&gt;
&lt;p&gt;So finally, 7-Zip seems to be the choice, regarding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I haven’t got a chance to look into its &lt;a href=&quot;http://sourceforge.net/projects/sevenzip/files/7-Zip/9.34/7z934-src.7z/download&quot;&gt;source code&lt;/a&gt; yet. But I have used 7-Zip for years, never encounter entry name issues.&lt;/li&gt;
&lt;li&gt;It can extract &lt;a href=&quot;http://en.wikipedia.org/wiki/7-Zip#Others&quot;&gt;a wide range of formats&lt;/a&gt;, which helps unifying archives to zip.&lt;/li&gt;
&lt;li&gt;It creates zip archive, and the compression ratio is satisfying.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://zip-7.com/wp-content/uploads/2014/11/Quality-and-Efficient-File-Compression-to-Suit-Your-Needs.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Batch-processing-RAR-and-Zip_13247/Quality-and-Efficient-File-Compression-to-Suit-Your-Needs_5.png&quot; alt=&quot;Quality-and-Efficient-File-Compression-to-Suit-Your-Needs&quot; title=&quot;Quality-and-Efficient-File-Compression-to-Suit-Your-Needs&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Prepare to use 7z.exe command line tool&lt;/h2&gt;
&lt;p&gt;On 7-Zip’s website, &lt;a href=&quot;http://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/lzma922.tar.bz2/download&quot;&gt;the latest SDK&lt;/a&gt; is released in 2011, and &lt;a href=&quot;http://sourceforge.net/projects/sevenzip/files/7-Zip/9.34/7z934-x64.msi/download&quot;&gt;the latest binary&lt;/a&gt; is released in Nov 2014. So the plan is to go with the binary.&lt;/p&gt;
&lt;p&gt;To invoke the 7z.exe command line tool, a helper function is needed to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;invoke 7z.exe command line tool.&lt;/li&gt;
&lt;li&gt;Wait for 7z.exe to finish executing.&lt;/li&gt;
&lt;li&gt;Grab all messages and errors from 7z.exe.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public static class ProcessHelper
{
    public static int StartAndWait(string fileName, string arguments, Action&amp;lt;string&amp;gt; outputReceived = null, Action&amp;lt;string&amp;gt; errorReceived = null)
    {
        using (Process process = new Process()
        {
            StartInfo = new ProcessStartInfo()
            {
                FileName = fileName,
                Arguments = arguments,
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            }
        })
        {
            if (outputReceived != null)
            {
                process.OutputDataReceived += (sender, args) =&amp;gt; outputReceived(args.Data);
            }

            if (errorReceived != null)
            {
                process.ErrorDataReceived += (sender, args) =&amp;gt; errorReceived(args.Data);
            }
                
            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
            return process.ExitCode;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When there is output message/error message from the created process, the outputReceived/errorReceived callback functions will be invoked.&lt;/p&gt;
&lt;p&gt;Also the implementation starts with an empty 7Z.exe wrapper:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SevenZip
{
    // http://sevenzip.sourceforge.jp/chm/cmdline/switches/method.htm#Zip 
    private const int DefaultCompressionLevel = 9;

    private static readonly int processorCount = Environment.ProcessorCount;

    private readonly string sevenZ;

    public SevenZip(string sevenZ)
    {
        this.sevenZ = sevenZ;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of developing a direct conversion algorithm between RAR/ISO/… and zip format, I would &lt;a href=&quot;http://en.wikipedia.org/wiki/KISS_principle&quot;&gt;keep it simple stupid&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extract RAR archive entries to a temp folder (x command)&lt;/li&gt;
&lt;li&gt;Compress temp folder entries to zip archive (a command).&lt;/li&gt;
&lt;li&gt;Delete the temp folder.&lt;/li&gt;
&lt;li&gt;Delete the RAR archive.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now some basic functions can be added to SevenZip class.&lt;/p&gt;
&lt;h2&gt;Extract entries from RAR/ISO/7z/… archive&lt;/h2&gt;
&lt;p&gt;To extract an archive, &lt;a href=&quot;http://sevenzip.sourceforge.jp/chm/cmdline/commands/extract_full.htm&quot;&gt;the command format&lt;/a&gt; is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;7z.exe x {archiveFileName} -y -r -o{destinationDirectoryName}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the code is straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void Extract(
    string archive, 
    string destination = null, 
    bool deleteArchive = false, 
    Action&amp;lt;string&amp;gt; logger = null)
{
    destination = !string.IsNullOrWhiteSpace(destination)
        ? destination
        : Path.Combine(Path.GetDirectoryName(archive), Path.GetFileNameWithoutExtension(archive));
    &quot;Start extracting {0} to {1}&quot;.FormatWith(archive, destination).LogWith(logger);
    ProcessHelper.StartAndWait(
        this.sevenZ,
        @&quot;x &quot;&quot;{0}&quot;&quot; -y -r -o&quot;&quot;{1}&quot;&quot;&quot;.FormatWith(archive, destination),
        message =&amp;gt; message.LogWith(logger),
        error =&amp;gt; error.LogWith(logger));
    &quot;End extracting {0} to {1}&quot;.FormatWith(archive, destination).LogWith(logger);

    if (deleteArchive)
    {
        DeleteFile(archive, logger);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When destination directory is missing, entries will be extracted to a directory with the same name as the archive.&lt;/p&gt;
&lt;p&gt;The invocation is extremely simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SevenZip sevenZip = new SevenZip(@&quot;D:\Software\7zip\7z.exe&quot;);
sevenZip.Extract(@&quot;D:\Temp\a.rar&quot;); // D:\Temp\a.rar -&amp;gt; D:\Temp\a\.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Create zip archive&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://upload.wikimedia.org/wikipedia/commons/f/fa/Simple_Comic_zip.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Batch-processing-RAR-and-Zip_13247/Simple_Comic_zip_3.png&quot; alt=&quot;Simple_Comic_zip&quot; title=&quot;Simple_Comic_zip&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To create zip archive from a file/directory, &lt;a href=&quot;http://sevenzip.sourceforge.jp/chm/cmdline/commands/add.htm&quot;&gt;the command format&lt;/a&gt; is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;7z.exe a {zipFileName} {sourceFile} -tzip -r -mx={compressionLevel} -mmt={threadCount} -p{password}&lt;/p&gt;
&lt;p&gt;7z.exe a {zipFileName} {sourceDirectory}\* -tzip -r -mx={compressionLevel} -mmt={threadCount} -p{password}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So a general function will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void Zip(
    string source,
    string zip = null,
    Action&amp;lt;string&amp;gt; logger = null,
    string password = null,
    int level = DefaultCompressionLevel)
{
    level = FormatCompressionLevel(level);
    zip = !string.IsNullOrWhiteSpace(zip) ? zip : &quot;{0}.zip&quot;.FormatWith(source);
    string passwordArgument = string.IsNullOrEmpty(password) ? null : &quot;-p{0}&quot;.FormatWith(password);

    &quot;Start creating {0} from {1}&quot;.FormatWith(zip, source).LogWith(logger);
    ProcessHelper.StartAndWait(
        this.sevenZ,
        @&quot;a &quot;&quot;{0}&quot;&quot; &quot;&quot;{1}&quot;&quot;  -tzip -r -mx={2} -mmt={3} {4}&quot;.FormatWith(zip, source, level, processorCount, passwordArgument),
        message =&amp;gt; message.LogWith(logger),
        error =&amp;gt; error.LogWith(logger));
    &quot;End creating {0} from {1}&quot;.FormatWith(zip, source).LogWith(logger);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where FormatComptression() is a tiny function to ensure &lt;a href=&quot;http://sevenzip.sourceforge.jp/chm/cmdline/switches/method.htm#Zip&quot;&gt;the compression level of zip is in the range of 0-9&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static int FormatCompressionLevel(int level)
{
    // http://sevenzip.sourceforge.jp/chm/cmdline/switches/method.htm#Zip
    if (level &amp;lt; 0)
    {
        return 0;
    }

    if (level &amp;gt; 9)
    {
        return 9;
    }

    return level;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this demonstrates how to zip a single file/all entries inside a directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sevenZip.Zip(@&quot;D:\Temp\SingleFile&quot;, @&quot;D:\Temp\SingleFile.zip&quot;);
sevenZip.Zip(@&quot;D:\Temp\Directory\*&quot;, @&quot;D:\Temp\Directory.zip&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Delete a file/directory&lt;/h2&gt;
&lt;p&gt;In the above Extract() function, a DeleteFile() function is used. Yes, here a little trick is needed to delete file/directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class FileHelper
{
    public static void Delete(string file)
    {
        File.SetAttributes(file, FileAttributes.Normal); // In case file is readonly.
        File.Delete(file);
    }
}

public static class DirectoryHelper
{
    public static void Delete(string directory)
    {
        Directory.EnumerateFiles(directory).ForEach(FileHelper.Delete);
        Directory.EnumerateDirectories(directory).ForEach(Delete);
        Directory.Delete(directory, false);
    }
}

public class SevenZip
{
    private static void DeleteFile(string file, Action&amp;lt;string&amp;gt; logger = null)
    {
        &quot;Start deleting file {0}&quot;.FormatWith(file).LogWith(logger);
        FileHelper.Delete(file);
        &quot;End deleting file {0}&quot;.FormatWith(file).LogWith(logger);
    }

    private static void DeleteDirectory(string directory, Action&amp;lt;string&amp;gt; logger = null)
    {
        &quot;Start deleting directory {0}&quot;.FormatWith(directory).LogWith(logger);
        DirectoryHelper.Delete(directory);
        &quot;End deleting directory {0}&quot;.FormatWith(directory).LogWith(logger);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The built-in Directory.Delete() and File.Delete() functions are not directly used, because they will fail when some file/directory is read only, which can be a common scenario for entries extracted from ISO archives.&lt;/p&gt;
&lt;h2&gt;Convert RAR, ISO, 7z, … archives to zip&lt;/h2&gt;
&lt;p&gt;Now “converting” an archive becomes very easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void ToZip(
    string archive,
    string zip = null,
    bool deleteArchive = false,
    Action&amp;lt;string&amp;gt; logger = null,
    int level = DefaultCompressionLevel)
{
    // Create temp directory.
    string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    Directory.CreateDirectory(tempDirectory);

    try
    {
        // Extract archive entries to temp directory.
        this.Extract(archive, tempDirectory, false, logger);

        // Compress temp directory entries (tempDirectory\*) to zip.
        string zipFullName = string.IsNullOrWhiteSpace(zip) ? Path.ChangeExtension(archive, &quot;zip&quot;) : zip;
        this.Zip(Path.Combine(tempDirectory, &quot;*&quot;), zipFullName, logger, null, level);

        if (deleteArchive)
        {
            // Delete archive.
            DeleteFile(archive, logger);
        }
    }
    finally
    {
        // Delete temp directory.
        DeleteDirectory(tempDirectory, logger);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The invocation is easy too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sevenZip.ToZip(@&quot;D:\Temp\b.rar&quot;, null /* By default D:\Temp\b.zip */, true, Console.Write);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Batch process&lt;/h2&gt;
&lt;p&gt;To batch convert all archives within a certain directory, just need a little recursion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void AllToZips(
    string directory,
    string[] archiveExtensions,
    Func&amp;lt;string, string&amp;gt; zipFile = null,
    bool deleteArchive = false,
    bool isRecursive = false,
    Action&amp;lt;string&amp;gt; logger = null,
    int level = DefaultCompressionLevel)
{
    Directory
        .EnumerateFiles(directory)
        .Where(file =&amp;gt; archiveExtensions.Contains(Path.GetExtension(file), StringComparer.InvariantCultureIgnoreCase))
        .ForEach(archive =&amp;gt; this.ToZip(archive, zipFile != null ? zipFile(archive) : null, deleteArchive, logger, level));

    if (isRecursive)
    {
        Directory
            .EnumerateDirectories(directory)
            .ForEach(subDirectory =&amp;gt;
            this.AllToZips(subDirectory, archiveExtensions, zipFile, deleteArchive, true, logger, level));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The invocation will be like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sevenZip.AllToZips(
    @&quot;\\dixinyan-disk\sda1\Files\&quot;,
    new string[] { &quot;.rar&quot;, &quot;.iso&quot;, &quot;.7z&quot; },
    null, // By default, take original archive&apos;s name as zip file&apos;s name (abc.rar -&amp;gt; abc.zip).
    true, // Delete original archive.
    true, // Process sub directories recursively.
    Console.Write);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also need to batch “convert” bunch of archives to files/directories for direct access:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void ExtractAll(
    string directory,
    string[] archiveExtensions,
    Func&amp;lt;string, string&amp;gt; destinationDirectory = null,
    bool deleteArchive = false,
    bool isRecursive = false,
    Action&amp;lt;string&amp;gt; logger = null)
{
    Directory
        .EnumerateFiles(directory)
        .Where(file =&amp;gt; archiveExtensions.Contains(Path.GetExtension(file), StringComparer.InvariantCultureIgnoreCase))
        .ForEach(archive =&amp;gt; this.Extract(
            archive, destinationDirectory != null ? destinationDirectory(archive) : null, deleteArchive, logger));

    if (isRecursive)
    {
        Directory
            .EnumerateDirectories(directory)
            .ForEach(subDirectory =&amp;gt; this.ExtractAll(
                subDirectory, archiveExtensions, destinationDirectory, deleteArchive, true, logger));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Encrypt/hide file names in zip&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://zip-7.com/wp-content/uploads/2014/10/Top-3-Best-Compression-Tools.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Batch-processing-RAR-and-Zip_13247/Top-3-Best-Compression-Tools_5960e63c-2b80-4a0b-a4b2-28e7a023a6e7.png&quot; alt=&quot;Top-3-Best-Compression-Tools&quot; title=&quot;Top-3-Best-Compression-Tools&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After converting RAR to zip, there is a big disadvantage. RAR can encrypt/hide entry names in the archive, but zip cannot. Again, a &lt;a href=&quot;http://en.wikipedia.org/wiki/KISS_principle&quot;&gt;simple stupid&lt;/a&gt; way is to &lt;a href=&quot;http://kb.winzip.com/kb/entry/147/&quot;&gt;double zip&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First pass: zip entries into an archive without encryption&lt;/li&gt;
&lt;li&gt;Second pass: zip that archive with encryption&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;public void DoubleZip(
    string source,
    string password,
    Func&amp;lt;string, string&amp;gt; intermediateFile = null,
    Action&amp;lt;string&amp;gt; logger = null,
    int level = DefaultCompressionLevel)
{
    intermediateFile = intermediateFile ?? (name =&amp;gt; &quot;{0}..zip&quot;.FormatWith(source));

    string firstPassZip = intermediateFile(source);
    this.Zip(source, firstPassZip, logger, null, level);

    string secondPassZip = &quot;{0}.zip&quot;.FormatWith(source);
    this.Zip(firstPassZip, secondPassZip, logger, password, level);

    DeleteFile(firstPassZip, logger);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With the help of 7z.exe, I have programmatically extracted many archives, and also batch “converted” tons of fancy archives (mostly in RAR, ISO, and 7z format) to zip archives.&lt;/p&gt;
&lt;p&gt;The complete code can be downloaded &lt;a href=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Batch-processing-RAR-and-Zip_13247/SevenZip.cs&quot;&gt;here&lt;/a&gt; - including the SevenZip class and all extension methods/helper classes used above.&lt;/p&gt;
&lt;p&gt;If you have a better approach to encrypt/hide entry names in zip archives, please share :)&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (6) Deferred Execution, Laziness Loading and Eager Loading</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-6-deferred-execution-laziness-loading-and-eager-loading/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-6-deferred-execution-laziness-loading-and-eager-loading/</guid><description>In LINQ to Objects, query methods returning IEnumerable&lt;T&gt; implements deferred execution. Similarly, in LINQ to Entities, query methods returning IQueryable&lt;T&gt; implements deferred execution too.</description><pubDate>Fri, 26 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-6-query-data-loading&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-6-query-data-loading&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In LINQ to Objects, query methods returning IEnumerable&amp;lt;T&amp;gt; implements deferred execution. Similarly, in LINQ to Entities, query methods returning IQueryable&amp;lt;T&amp;gt; implements deferred execution too.&lt;/p&gt;
&lt;h2&gt;Deferred execution&lt;/h2&gt;
&lt;p&gt;As previous part discussed, when creating a LINQ to Entities query, if Queryable methods returning IQueryable&amp;lt;T&amp;gt; are called, these methods just keep building the expression tree, there is no query execution. The execution is deferred.&lt;/p&gt;
&lt;h3&gt;Iterator pattern&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;. So values can be pulled from IQueryable&amp;lt;T&amp;gt; with the standard iterator pattern. When trying to pull the first value, Entity Framework translates LINQ to Entities query to SQL, and execute SQL in the database. This process can be demonstrated by the following GetIterator method, implemented with the Iterator&amp;lt;T&amp;gt; class from the LINQ to Objects chapter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class QueryableExtensions
{
    public static IEnumerator&amp;lt;TSource&amp;gt; GetIterator&amp;lt;TSource&amp;gt;(
        this IQueryable&amp;lt;TSource&amp;gt; query, DbContext dbContext)
    {
        query.NotNull(nameof(query));
        dbContext.NotNull(nameof(dbContext));

        IEnumerator&amp;lt;TSource&amp;gt; sqlReader = null;
        bool isSqlExecuted = false;
        return new Iterator&amp;lt;TSource&amp;gt;(
            start: () =&amp;gt;
                {
                    Trace.WriteLine(&quot;|_Convert expression tree to database command tree.&quot;);
                    DbQueryCommandTree commandTree = dbContext.Convert(query.Expression);
                    Trace.WriteLine(&quot;|_Generate SQL from database command tree.&quot;);
                    DbCommand sql = dbContext.Generate(commandTree);
                    Trace.WriteLine(&quot;|_Build SQL query.&quot;);
                    IEnumerable&amp;lt;TSource&amp;gt; sqlQuery = dbContext.Database.SqlQuery&amp;lt;TSource&amp;gt;(
                        sql.CommandText,
                        sql.Parameters.OfType&amp;lt;DbParameter&amp;gt;().Select(parameter =&amp;gt; parameter.Value).ToArray());
                    sqlReader = sqlQuery.GetEnumerator();
                },
            hasNext: () =&amp;gt;
                {
                    if (!isSqlExecuted)
                    {
                        Trace.WriteLine(&quot;|_Execute SQL query.&quot;);
                        isSqlExecuted = true;
                    }
                    Trace.WriteLine($&quot;|_Try reading a row and materializing to {typeof(TSource).Name} object.&quot;);
                    return sqlReader.MoveNext();
                },
            next: () =&amp;gt; sqlReader.Current,
            dispose: () =&amp;gt; sqlReader.Dispose()).StartState();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take the previous simple Where and Select query as example, this is how the values are pulled from IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Laziness
{
    internal static void WhereAndSelect()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;Product&amp;gt; products = adventureWorks.Products
                .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;));
            // products.ForEach(product =&amp;gt; Trace.WriteLine(product));
            Trace.WriteLine(&quot;Get iterator from LINQ to Entities query.&quot;);
            using (IEnumerator&amp;lt;Product&amp;gt; iterator = products
                .GetIterator(adventureWorks)) // products.GetEnumerator()
            {
                while (new Func&amp;lt;bool&amp;gt;(() =&amp;gt;
                    {
                        Trace.WriteLine(&quot;Try moving iterator to next.&quot;);
                        return iterator.MoveNext(); // Translate and execute query.
                    })())
                {
                    Product product = iterator.Current;
                    Trace.WriteLine($&quot;Get iterator current product: {product.Name}.&quot;);
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In iterator pattern, IQueryable&amp;lt;T&amp;gt;.GetEnumerator should be called to get an iterator. Here for demonstration purpose, the GetEnumerator method is replaced by above GetIterator. Later, when the iterator’s MoveNext method is called for the first iteration, Entity Framework starts to work. It:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;converts LINQ to Entities query’s expression tree to database command tree,&lt;/li&gt;
&lt;li&gt;generates SQL query,&lt;/li&gt;
&lt;li&gt;executes SQL query,&lt;/li&gt;
&lt;li&gt;reads the first row&lt;/li&gt;
&lt;li&gt;materializes the row data to the specified Product object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then each following iteration reads a row and materializes it to a Product object. The above query execution outputs the following trace:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Get iterator from LINQ to Entities query. Try moving iterator to next. |_Convert expression tree to database command tree. |_Generate SQL from database command tree. |_Build SQL query. |_Execute SQL query. |_Try reading a row and materializing to Product object. Get iterator current product: ML Bottom Bracket. Try moving iterator to next. |_Try reading a row and materializing to Product object. Get iterator current product: ML Crankset. Try moving iterator to next. |_Try reading a row and materializing to Product object. Get iterator current product: Mountain-400-W Silver, 38. ...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lazy/eager evaluation&lt;/h3&gt;
&lt;p&gt;Deferred execution can be either lazy evaluation or eager evaluation. As the previous part discussed, when Entity Framework translates LINQ to Entities query to a DbCommand object, representing the database query and parameters. Then it calls DbCommand.ExecuteReader method to build a DbDataReader, then calls DbDataReader.Read method to read each row. DbCommand and DbDataReader are abstract classes. For SQL database, actually SqlCommand and SqlDataReader are used. Calling SqlCommand.ExecuteReader executes the SQL query, and &lt;a href=&quot;http://blogs.msdn.com/b/adonet/archive/2012/04/20/using-sqldatareader-s-new-async-methods-in-net-4-5-beta.aspx&quot;&gt;streams&lt;/a&gt; a number of rows to local buffer through &lt;a href=&quot;https://en.wikipedia.org/wiki/Tabular_Data_Stream&quot;&gt;TDS (tabular data stream) protocol&lt;/a&gt;. Then, calling SqlDataReader.Read reads each row from local buffer. So LINQ to Entities. So LINQ to Entities’ evaluation is neither completely lazy (steaming 1 row for each iteration), nor completely eager (streaming all rows at the first iteration). It is somewhere between, implemented by batch streaming into a local buffer.&lt;/p&gt;
&lt;h2&gt;Lazy loading and eager loading&lt;/h2&gt;
&lt;p&gt;An entity can have navigation properties, referencing associated entities. By default, these associated entities are not queried, until they are pulled. This feature of Entity Framework is called lazy loading.&lt;/p&gt;
&lt;h3&gt;Implicit and explicit lazy loading&lt;/h3&gt;
&lt;p&gt;In the entity definition, the navigation properties are defined as virtual. By default, the derived proxy classes override these properties and implement lazy loading:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ImplicitLazyLoading()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Database query.
        Trace.WriteLine(subcategory.Name);
        ProductCategory associatedCategory = subcategory.ProductCategory; // Database query.
        Trace.WriteLine(associatedCategory.Name);
        ICollection&amp;lt;Product&amp;gt; associatedProducts = subcategory.Products; // Database query.
        Trace.WriteLine(associatedProducts.Count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example executes 3 database queries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The first subcategory entity is queried by First&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) 
    [c].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [c].[Name] AS [Name], 
    [c].[ProductCategoryID] AS [ProductCategoryID]
    FROM [Production].[ProductSubcategory] AS [c]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The associated single category entity is queried when it is pulled from navigation property ProductSubcategory.ProductCategory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The associated product entities is queried when they are pulled from navigation property ProductSubcategory.Products&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    CASE 
        WHEN (
            ((CASE 
                WHEN ([Extent1].[Style] = N&apos;&apos;M&apos;&apos;) THEN cast(1 as bit) 
                ELSE cast(0 as bit) 
            END) &amp;lt;&amp;gt; 1) AND 
            ((CASE 
                WHEN ([Extent1].[Style] = N&apos;&apos;U&apos;&apos;) THEN cast(1 as bit)
                ELSE cast(0 as bit)
            END) &amp;lt;&amp;gt; 1) AND 
            ((CASE
                WHEN ([Extent1].[Style] = N&apos;&apos;W&apos;&apos;) THEN cast(1 as bit) 
                ELSE cast(0 as bit) 
            END) &amp;lt;&amp;gt; 1)) THEN &apos;&apos;0X&apos;&apos;
        WHEN ([Extent1].[Style] = N&apos;&apos;M&apos;&apos;) THEN &apos;&apos;0X0X&apos;&apos;
        WHEN ([Extent1].[Style] = N&apos;&apos;U&apos;&apos;) THEN &apos;&apos;0X1X&apos;&apos;
        ELSE &apos;&apos;0X2X&apos;&apos; 
    END AS [C1], 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[RowVersion] AS [RowVersion], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ListPrice] AS [ListPrice], 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID]
    FROM [Production].[Product] AS [Extent1]
    WHERE [Extent1].[ProductSubcategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Style column is queried by a CASE expression because it is discriminator column for the table per hierarchy inheritance.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entity Framework also provides APIs for explicit lazy loading:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    using System.Data.Entity.Infrastructure;

    public class DbContext
    {
        public DbEntityEntry&amp;lt;TEntity&amp;gt; Entry&amp;lt;TEntity&amp;gt;(TEntity entity) where TEntity : class;

        // Other members.
    }
}

namespace System.Data.Entity.Infrastructure
{
    using System.Collections.Generic;
    using System.Linq.Expressions;

    public class DbEntityEntry&amp;lt;TEntity&amp;gt; where TEntity : class
    {
        public DbReferenceEntry&amp;lt;TEntity, TProperty&amp;gt; Reference&amp;lt;TProperty&amp;gt;(
            Expression&amp;lt;Func&amp;lt;TEntity, TProperty&amp;gt;&amp;gt; navigationProperty) where TProperty : class;

        public DbCollectionEntry&amp;lt;TEntity, TElement&amp;gt; Collection&amp;lt;TElement&amp;gt;(
            Expression&amp;lt;Func&amp;lt;TEntity, ICollection&amp;lt;TElement&amp;gt;&amp;gt;&amp;gt; navigationProperty) where TElement : class;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbContext.Entry method accepts an entity and returns a DbEntityEntry&amp;lt;TEntity&amp;gt; object, which represents the entity’s information tracked by the source DbContext. DbEntityEntry&amp;lt;TEntity&amp;gt; provides a Reference method to get a DbReferenceEntry&amp;lt;TEntity, TProperty&amp;gt; object, which represents a navigation property to another associated single entity. DbEntityEntry&amp;lt;TEntity&amp;gt; also provides a Collection method to get a DbCollectionEntry&amp;lt;TEntity, TElement&amp;gt; object, which represents a navigation property to a collection of other associated entities. So the associated entities can be manually loaded by calling DbReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Load and DbCollectionEntry&amp;lt;TEntity, TElement&amp;gt;.Load:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExplicitLazyLoading()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Database query.
        Trace.WriteLine(subcategory.Name);
        adventureWorks
            .Entry(subcategory) // Return DbEntityEntry&amp;lt;ProductSubcategory&amp;gt;.
            .Reference(entity =&amp;gt; entity.ProductCategory) // Return DbReferenceEntry&amp;lt;ProductSubcategory, ProductCategory&amp;gt;.
            .Load(); // Database query.
        Trace.WriteLine(subcategory.ProductCategory.Name);
        adventureWorks
            .Entry(subcategory) // Return DbEntityEntry&amp;lt;ProductSubcategory&amp;gt;.
            .Collection(entity =&amp;gt; entity.Products) // Return DbCollectionEntry&amp;lt;ProductSubcategory, Product&amp;gt;.
            .Load(); // Database query.
        Trace.WriteLine(subcategory.Products.Count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the Load method is called, the associated entities are queried, and the navigation properties becomes ready. Here the SQL queries are the same as above implicit lazy loading. Explicit lazy loading can be useful, because the associated data to load can be specified by a query. For example, if only the associated category’s Name and the associated products’ Count is needed, then call DbReferenceEntry&amp;lt;TEntity, TProperty&amp;gt;.Query and DbCollectionEntry&amp;lt;TEntity, TElement&amp;gt;.Query to start a query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ExplicitLazyLoadingWithQuery()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Database query.
        Trace.WriteLine(subcategory.Name);
        string associatedCategoryName = adventureWorks
            .Entry(subcategory).Reference(entity =&amp;gt; entity.ProductCategory)
            .Query() // Return IQueryable&amp;lt;ProductCategory&amp;gt;.
            .Select(category =&amp;gt; category.Name).Single(); // Database query.
        Trace.WriteLine(associatedCategoryName);
        int associatedProductsCount = adventureWorks
            .Entry(subcategory).Collection(entity =&amp;gt; entity.Products)
            .Query() // Return IQueryable&amp;lt;Product&amp;gt;.
            .Count(); // Database query.
        Trace.WriteLine(associatedProductsCount);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, for the associated category, only its Name is queried:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    [Limit1].[Name] AS [Name]
    FROM ( SELECT TOP (2) 
        [Extent1].[Name] AS [Name]
        FROM [Production].[ProductCategory] AS [Extent1]
        WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1
    )  AS [Limit1]&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the associated products, only their count is queried:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [Production].[Product] AS [Extent1]
        WHERE [Extent1].[ProductSubcategoryID] = @EntityKeyValue1
    )  AS [GroupBy1]&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lazy loading can be a little tricky when used with deferred execution. The following example throws EntityCommandExecutionException:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LazyLoadingAndDeferredExecution()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategories = adventureWorks.ProductSubcategories;
        subcategories
            .ForEach(subcategory =&amp;gt; Trace.WriteLine( // Reading subcategories is in progress.
                $&quot;{subcategory.ProductCategory.Name}/{subcategory.Name}: {subcategory.Products.Count}&quot;));
        // EntityCommandExecutionException: There is already an open DataReader associated with this Command which must be closed first.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the ForEach’s action starts executing for the first ForEach iteration, it pulls 1 subcategory entity from the database query. Entity Framework translates and executes the query, and eventually builds a System.Data.Common.DbDataReader object to read 1 row from the query result. This reader is not closed during the action execution, so that it can be called again in the next iteration to read another row. DbDataReader uses the DbContext’s database connection &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/haa3afyz.aspx&quot;&gt;exclusively&lt;/a&gt;. As a result, when the action pulls associated product entity from the navigation property, Entity Framework tries to build another reader, and it fails with an exception. The above exception can be fixed by finishing reading subcategories before reading from lazy loading, so that the the readers’ lifecycle do not overlap:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LazyLoadingAndImmediateExecution()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategories = adventureWorks.ProductSubcategories;
        subcategories
            .ToArray() // Finish reading subcategories.
            .ForEach(subcategory =&amp;gt; Trace.WriteLine(
                $@&quot;{subcategory.ProductCategory/* Finish reading category. */.Name}/{subcategory.Name}: {subcategory.Products/* Finish reading products. */.Count}&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here ToArray() is translated to database query; For each iteration, pulling category and pulling products are translated to 2 separate database queries. So, if there are N subcategories, the above code executes 1 + 2 * N database queries. The performance can be better if all data are retrieved by 1 queried.&lt;/p&gt;
&lt;h3&gt;Eager loading&lt;/h3&gt;
&lt;p&gt;Entity Framework provides an Include extension method for IQueryable&amp;lt;T&amp;gt;, to query entities and their associated entities eagerly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingWithInclude()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductSubcategory&amp;gt; subcategories = adventureWorks.ProductSubcategories
            .Include(subcategory =&amp;gt; subcategory.ProductCategory)
            .Include(subcategory =&amp;gt; subcategory.Products);
        subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
            $&quot;{subcategory.ProductCategory.Name}/{subcategory.Name}: {subcategory.Products.Count}&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Include methods are translated to JOINs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Project1].[Name] AS [Name], 
    [Project1].[ProductCategoryID] AS [ProductCategoryID], 
    [Project1].[ProductCategoryID1] AS [ProductCategoryID1], 
    [Project1].[Name1] AS [Name1], 
    [Project1].[C2] AS [C1], 
    [Project1].[C1] AS [C2], 
    [Project1].[ProductID] AS [ProductID], 
    [Project1].[RowVersion] AS [RowVersion], 
    [Project1].[Name2] AS [Name2], 
    [Project1].[ListPrice] AS [ListPrice], 
    [Project1].[ProductSubcategoryID1] AS [ProductSubcategoryID1]
    FROM ( SELECT 
        [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID1], 
        [Extent2].[Name] AS [Name1], 
        [Extent3].[ProductID] AS [ProductID], 
        [Extent3].[RowVersion] AS [RowVersion], 
        [Extent3].[Name] AS [Name2], 
        [Extent3].[ListPrice] AS [ListPrice], 
        [Extent3].[ProductSubcategoryID] AS [ProductSubcategoryID1], 
        CASE 
            WHEN ([Extent3].[ProductID] IS NULL) THEN CAST(NULL AS varchar(1)) 
            WHEN (
                ((CASE 
                    WHEN ([Extent3].[Style] = N&apos;M&apos;) THEN cast(1 as bit) 
                    ELSE cast(0 as bit) 
                END) &amp;lt;&amp;gt; 1) AND 
                ((CASE 
                    WHEN ([Extent3].[Style] = N&apos;U&apos;) THEN cast(1 as bit) 
                    ELSE cast(0 as bit) 
                END) &amp;lt;&amp;gt; 1) AND 
                ((CASE 
                    WHEN ([Extent3].[Style] = N&apos;W&apos;) THEN cast(1 as bit) 
                    ELSE cast(0 as bit) 
                END) &amp;lt;&amp;gt; 1)) THEN &apos;4X&apos; 
            WHEN ([Extent3].[Style] = N&apos;M&apos;) THEN &apos;4X0X&apos; 
            WHEN ([Extent3].[Style] = N&apos;U&apos;) THEN &apos;4X1X&apos; 
            ELSE &apos;4X2X&apos; 
        END AS [C1], 
        CASE 
            WHEN ([Extent3].[ProductID] IS NULL) THEN CAST(NULL AS int) 
            ELSE 1 
        END AS [C2]
        FROM   [Production].[ProductSubcategory] AS [Extent1]
        INNER JOIN [Production].[ProductCategory] AS [Extent2] ON [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
        LEFT OUTER JOIN [Production].[Product] AS [Extent3] ON [Extent1].[ProductSubcategoryID] = [Extent3].[ProductSubcategoryID]
    )  AS [Project1]
    ORDER BY [Project1].[ProductSubcategoryID] ASC, [Project1].[ProductCategoryID1] ASC, [Project1].[C2] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Include can be used with Select to load multiple levels of associated entities. The following example queries all categories, and eagerly load all associated subcategories and products:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingWithIncludeAndSelect()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories
            .Include(category =&amp;gt; category.ProductSubcategories.Select(subcategory =&amp;gt; subcategory.Products));
        categories.ForEach(category =&amp;gt; Trace.WriteLine(
            $@&quot;{category.Name}: {string.Join(&quot;, &quot;, category.ProductSubcategories
                .Select(subcategory =&amp;gt; $&quot;{subcategory.Name}-{subcategory.Products.Count}&quot;))}&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translated SQL query is also JOINs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Project1].[ProductCategoryID] AS [ProductCategoryID], 
    [Project1].[Name] AS [Name], 
    [Project1].[C3] AS [C1], 
    [Project1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Project1].[Name1] AS [Name1], 
    [Project1].[ProductCategoryID1] AS [ProductCategoryID1], 
    [Project1].[C2] AS [C2], 
    [Project1].[C1] AS [C3], 
    [Project1].[ProductID] AS [ProductID], 
    [Project1].[RowVersion] AS [RowVersion], 
    [Project1].[Name2] AS [Name2], 
    [Project1].[ListPrice] AS [ListPrice], 
    [Project1].[ProductSubcategoryID1] AS [ProductSubcategoryID1]
    FROM ( SELECT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent1].[Name] AS [Name], 
        [Join1].[ProductSubcategoryID1] AS [ProductSubcategoryID], 
        [Join1].[Name1] AS [Name1], 
        [Join1].[ProductCategoryID] AS [ProductCategoryID1], 
        [Join1].[ProductID] AS [ProductID], 
        [Join1].[RowVersion] AS [RowVersion], 
        [Join1].[Name2] AS [Name2], 
        [Join1].[ListPrice] AS [ListPrice], 
        [Join1].[ProductSubcategoryID2] AS [ProductSubcategoryID1], 
        CASE
            WHEN ([Join1].[ProductSubcategoryID1] IS NULL) THEN CAST(NULL AS varchar(1))
            WHEN ([Join1].[ProductID] IS NULL) THEN CAST(NULL AS varchar(1))
            WHEN (
                ((CASE
                    WHEN ([Join1].[Style] = N&apos;M&apos;) THEN CAST(1 AS bit)
                    ELSE CAST(0 AS bit)
                END) &amp;lt;&amp;gt; 1) AND
                ((CASE
                    WHEN ([Join1].[Style] = N&apos;U&apos;) THEN CAST(1 AS bit)
                    ELSE CAST(0 AS bit)
                END) &amp;lt;&amp;gt; 1) AND
                ((CASE
                    WHEN ([Join1].[Style] = N&apos;W&apos;) THEN CAST(1 AS bit)
                    ELSE CAST(0 AS bit)
                END) &amp;lt;&amp;gt; 1)) THEN &apos;4X&apos;
            WHEN ([Join1].[Style] = N&apos;M&apos;) THEN &apos;4X0X&apos;
            WHEN ([Join1].[Style] = N&apos;U&apos;) THEN &apos;4X1X&apos;
            ELSE &apos;4X2X&apos;
        END AS [C1],
        CASE
            WHEN ([Join1].[ProductSubcategoryID1] IS NULL) THEN CAST(NULL AS int)
            WHEN ([Join1].[ProductID] IS NULL) THEN CAST(NULL AS int)
            ELSE 1
        END AS [C2],
        CASE
            WHEN ([Join1].[ProductSubcategoryID1] IS NULL) THEN CAST(NULL AS int)
            ELSE 1
        END AS [C3]
        FROM  [Production].[ProductCategory] AS [Extent1]
        LEFT OUTER JOIN  (SELECT 
            [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID1], 
            [Extent2].[Name] AS [Name1], 
            [Extent2].[ProductCategoryID] AS [ProductCategoryID], 
            [Extent3].[ProductID] AS [ProductID], 
            [Extent3].[RowVersion] AS [RowVersion], 
            [Extent3].[Name] AS [Name2], 
            [Extent3].[ListPrice] AS [ListPrice], 
            [Extent3].[ProductSubcategoryID] AS [ProductSubcategoryID2], 
            [Extent3].[Style] AS [Style]
            FROM  [Production].[ProductSubcategory] AS [Extent2]
            LEFT OUTER JOIN [Production].[Product] AS [Extent3] 
            ON [Extent2].[ProductSubcategoryID] = [Extent3].[ProductSubcategoryID] ) AS [Join1] 
        ON [Extent1].[ProductCategoryID] = [Join1].[ProductCategoryID]
    )  AS [Project1]
    ORDER BY [Project1].[ProductCategoryID] ASC, [Project1].[C3] ASC, [Project1].[ProductSubcategoryID] ASC, [Project1].[C2] ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the query methods part, eager loading can also be easily with Select:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EagerLoadingWithSelect()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        var subcategories = adventureWorks.ProductSubcategories.Select(subcategory =&amp;gt; new
        {
            Name = subcategory.Name,
            CategoryName = subcategory.ProductCategory.Name,
            ProductCount = subcategory.Products.Count
        });
        subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
            $&quot;{subcategory.CategoryName}/{subcategory.Name}: {subcategory.ProductCount}&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Include eagerly loads the full associated entities. Select can be flexible when not all associated data are needed. Here the translated query is smaller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1], 
    (SELECT 
        COUNT(1) AS [A1]
        FROM [Production].[Product] AS [Extent3]
        WHERE [Extent1].[ProductSubcategoryID] = [Extent3].[ProductSubcategoryID]) AS [C1]
    FROM  [Production].[ProductSubcategory] AS [Extent1]
    INNER JOIN [Production].[ProductCategory] AS [Extent2] ON [Extent1].[ProductCategoryID] = [Extent2].[ProductCategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The N + 1 problem&lt;/h3&gt;
&lt;p&gt;Sometimes lazy loading can cause the “N + 1 queries” problem. The following example queries some subcategories, and print each subcategory’s information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PrintSubcategoriesWithLazyLoading()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory[] subcategories = adventureWorks.ProductSubcategories
            .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID, (key, group) =&amp;gt; group.FirstOrDefault())
            .ToArray(); // 1 query for N subcategories.
        subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
            $&quot;{subcategory.Name} ({subcategory.ProductCategory.Name})&quot;)); // N queries.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When ToArray is called, 1 database query is executed, and it returns 4 subcategories:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name] AS [Name], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID]
    FROM   (SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent2]
        WHERE [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this query. each subcategory’s associated category is not queried because of lazy loading. Later, when the subcategories are printed in the loop, each iteration pulls one associated category. So there are 4 more database queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=1

exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=2

exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=3

exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This “N + 1 queries” problem can be resolved by eager loading:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void PrintSubcategoriesWithEagerLoading()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory[] subcategories = adventureWorks.ProductSubcategories
            .GroupBy(subcategory =&amp;gt; subcategory.ProductCategoryID, (key, group) =&amp;gt; group.FirstOrDefault())
            .Include(subcategory =&amp;gt; subcategory.ProductCategory)
            .ToArray(); // 1 query for N subcategories.
        subcategories.ForEach(subcategory =&amp;gt; Trace.WriteLine(
            $&quot;{subcategory.Name} ({subcategory.ProductCategory.Name})&quot;)); // N queries.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time there is only 1 database query for all subcategories and their associated categories:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Limit1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Limit1].[Name1] AS [Name], 
    [Limit1].[ProductCategoryID1] AS [ProductCategoryID], 
    [Limit1].[ProductCategoryID] AS [ProductCategoryID1], 
    [Limit1].[Name] AS [Name1]
    FROM   (SELECT DISTINCT 
        [Extent1].[ProductCategoryID] AS [ProductCategoryID]
        FROM [Production].[ProductSubcategory] AS [Extent1] ) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) 
        [Extent3].[ProductCategoryID] AS [ProductCategoryID], 
        [Extent3].[Name] AS [Name], 
        [Extent2].[ProductSubcategoryID] AS [ProductSubcategoryID], 
        [Extent2].[Name] AS [Name1], 
        [Extent2].[ProductCategoryID] AS [ProductCategoryID1]
        FROM  [Production].[ProductSubcategory] AS [Extent2]
        INNER JOIN [Production].[ProductCategory] AS [Extent3] ON [Extent2].[ProductCategoryID] = [Extent3].[ProductCategoryID]
        WHERE [Distinct1].[ProductCategoryID] = [Extent2].[ProductCategoryID] ) AS [Limit1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Disable lazy loading&lt;/h3&gt;
&lt;p&gt;There are some scenarios lazy loading needs to be disabled, like entity serialization. There are several ways to disable lazy loading for different scopes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To disable lazy loading for specific navigation properties, just do not mark it as virtual, so that the derived proxy class cannot override it with the lazy load implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To disable lazy loading for specific DbContext, set DbContextConfiguration object’s LazyLoadingEnabled property to false:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DisableLazyLoading()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.Configuration.LazyLoadingEnabled = false;
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First(); // Database query.
        Trace.WriteLine(subcategory.Name);
        ProductCategory associatedCategory = subcategory.ProductCategory; // No database query.
        Trace.WriteLine(associatedCategory == null); // True
        ICollection&amp;lt;Product&amp;gt; associatedProducts = subcategory.Products; // No database query.
        Trace.WriteLine(associatedProducts.Count); // 0
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To disable lazy loading by default, set LazyLoadingEnabled when constructing DbContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public AdventureWorks()
        : base(ConnectionStrings.AdventureWorks)
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Convert HTML to Well-Formatted Microsoft Word Document</title><link>https://dixin.github.io/posts/convert-html-to-well-formatted-microsoft-word-document/</link><guid isPermaLink="true">https://dixin.github.io/posts/convert-html-to-well-formatted-microsoft-word-document/</guid><description>Recently I wanted to convert my  into a Word document (.doc). The tasks are:</description><pubDate>Tue, 23 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I wanted to convert my &lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# tutorial&lt;/a&gt; into a Word document (.doc). The tasks are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the content of index page of the entire tutorial.&lt;/li&gt;
&lt;li&gt;Interpret the index page and get the title/URI of each chapter and its sections.&lt;/li&gt;
&lt;li&gt;Download the content of each chapter/section.&lt;/li&gt;
&lt;li&gt;Merge all contents as one well formatted document, with:
&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;table of contents&lt;/li&gt;
&lt;li&gt;header&lt;/li&gt;
&lt;li&gt;footer (page number)&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There might be several possible solutions, e.g.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt;: It is easy to use &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt; to process downloaded HTML DOM.&lt;/li&gt;
&lt;li&gt;C#: it is easier to use C# to implement the conversion to Word document.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/OfficeDev/Open-XML-SDK&quot;&gt;Open XML SDK&lt;/a&gt;: Open XML is a lower level API to build the Word document&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Visual_Studio_Tools_for_Office&quot;&gt;VSTO (Visual Studio Tools for Office)&lt;/a&gt;: Microsoft.Office.Interop.Word.dll from VSTO provides APIs to directly automate Word application itself to build a document.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After searching around, I found &lt;a href=&quot;https://www.nuget.org/packages/CsQuery/&quot;&gt;CsQuery library&lt;/a&gt;, which is available from &lt;a href=&quot;https://www.nuget.org/packages/CsQuery/&quot;&gt;Nuget&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-Package CsQuery
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;-like library for DOM process via C#. So The decision is to go with C#.&lt;/p&gt;
&lt;h2&gt;Download index page HTML and all contents via CsQuery&lt;/h2&gt;
&lt;p&gt;The first steps are to download everything from this blog:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download HTML string from index page: &lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;http://weblogs.asp.net/dixin/linq-via-csharp&lt;/a&gt;, which is easy by just calling WebClient.DownloadString.&lt;/li&gt;
&lt;li&gt;In the downloaded HTML string, get the title of the tutorial from the &amp;lt;title&amp;gt; tag of the downloaded HTML string: indexPage[&quot;title&quot;].Text()&lt;/li&gt;
&lt;li&gt;Get the article content of the index page (get rid of HTML page header, footer, sidebar, article comments …): indexPage[&quot;article.blog-post&quot;]&lt;/li&gt;
&lt;li&gt;In the page content, the title of each chapter, which is so easy with jQuery-style API: indexPage[&quot;article.blog-post&quot;].Children(&quot;ol&quot;).Children(&quot;li&quot;)
&lt;ol&gt;
&lt;li&gt;Get the title of each section.&lt;/li&gt;
&lt;li&gt;Get the URI of each section from the HTML hyperlink.
&lt;ol&gt;
&lt;li&gt;Download HTML string from each section.&lt;/li&gt;
&lt;li&gt;Get the article content of the section page (get rid of HTML page header, footer, sidebar, article comments …)&lt;/li&gt;
&lt;li&gt;In the contents, downgrade the &amp;lt;h1&amp;gt;, &amp;lt;h2&amp;gt;, &amp;lt;h3&amp;gt;, … tags: replace &amp;lt;h7&amp;gt; to &amp;lt;h9&amp;gt;, &amp;lt;h6&amp;gt; to &amp;lt;h8&amp;gt;, … &amp;lt;h2&amp;gt; to &amp;lt;h4&amp;gt;, &amp;lt;h1&amp;gt; to &amp;lt;h3&amp;gt;. This is a must, because later when merge all contents, chapter title will be &amp;lt;h1&amp;gt; and section title will be &amp;lt;h2&amp;gt;. The headings inside each section must downgrade 2 levels. Again, fortunately, this is very easy with jQuery-style API.&lt;/li&gt;
&lt;li&gt;Remove unnecessary hyperlinks.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Merge all section’s HTML.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Merge all chapters’ HTML.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the crawler code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Html DownloadHtml(string indexUrl = @&quot;http://weblogs.asp.net/dixin/linq-via-csharp&quot;)
{
    using (WebClient webClient = new WebClient() { Encoding = Encoding.UTF8 })
    {
        Console.WriteLine($&quot;Downloading {indexUrl}.&quot;);
        CQ indexPage = webClient.DownloadString(indexUrl);

        CQ article = indexPage[&quot;article.blog-post&quot;];
        IEnumerable&amp;lt;IGrouping&amp;lt;string, Tuple&amp;lt;string, string&amp;gt;&amp;gt;&amp;gt; chapters = article
            .Children(&quot;ol&quot;)
            .Children(&quot;li&quot;)
            .Select(chapter =&amp;gt; chapter.Cq())
            .Select(chapter =&amp;gt;
            {
                Tuple&amp;lt;string, string&amp;gt;[] sections = chapter.Find(&quot;h2&quot;)
                    .Select(section =&amp;gt; section.Cq().Find(&quot;a:last&quot;))
                    .Select(section =&amp;gt;
                    {
                        string sectionUrl = section.Attr&amp;lt;string&amp;gt;(&quot;href&quot;);
                        Console.WriteLine($&quot;Downloading {sectionUrl}.&quot;);
                        CQ sectionPage = webClient.DownloadString(sectionUrl);
                                
                        CQ sectionArticle = sectionPage[&quot;article.blog-post&quot;];
                        sectionArticle.Children(&quot;header&quot;).Remove();
                        Enumerable
                            .Range(1, 7)
                            .Reverse()
                            .ForEach(i =&amp;gt; sectionArticle
                                .Find($&quot;h{i}&quot;).Contents().Unwrap()
                                .Wrap($&quot;&amp;lt;h{i + 2}/&amp;gt;&quot;)
                                .Parent()
                                .Find(&quot;a&quot;).Contents().Unwrap());
                        sectionArticle.Find(&quot;pre span&quot;).Css(&quot;background&quot;, string.Empty);
                        sectionArticle.Find(&quot;p&quot;)
                            .Select(paragraph =&amp;gt; paragraph.Cq())
                            .ForEach(paragraph =&amp;gt;
                            {
                                string paragrapgText = paragraph.Text().Trim();
                                if ((paragraph.Children().Length == 0 &amp;amp;&amp;amp; string.IsNullOrWhiteSpace(paragrapgText))
                                    || paragrapgText.StartsWith(&quot;[LinQ via C#&quot;, StringComparison.OrdinalIgnoreCase))
                                {
                                    paragraph.Remove();
                                }
                            });
                        return Tuple.Create(section.Text().Trim(), sectionArticle.Html());
                    })
                    .ToArray();
                return new Grouping&amp;lt;string, Tuple&amp;lt;string, string&amp;gt;&amp;gt;(
                    chapter.Find(&quot;h1&quot;).Text().Trim(),
                    sections);
            })
            .ToArray();

        return new Html(
            indexPage[&quot;title&quot;].Text().Replace(&quot;Dixin&apos;s Blog -&quot;, string.Empty).Trim(),
            chapters);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WebClient.ncoding has to be specified as UTF8, otherwise the downloaded HTML will be messy. Also above Grouping class is under Microsoft.FSharp.Linq.RuntimeHelpers namespace. This is the only IGrouping&amp;lt;TKey, TElement&amp;gt; implementation that can be found in .NET libraries.&lt;/p&gt;
&lt;h2&gt;Represent entire tutorial as one single piece of HTML via T4 template&lt;/h2&gt;
&lt;p&gt;Above code constructs and returns a Html object, representing all chapters and all sections of the tutorial. The Html type is actually a &lt;a href=&quot;https://en.wikipedia.org/wiki/Text_Template_Transformation_Toolkit&quot;&gt;T4 template (Text Template Transformation Toolkit)&lt;/a&gt; for the entire tutorial:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;#@ template language=&quot;C#&quot; debug=&quot;true&quot; visibility=&quot;internal&quot; linePragmas=&quot;false&quot; #&amp;gt;
&amp;lt;#@ import namespace=&quot;System.Linq&quot; #&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;&amp;lt;#= this.Title #&amp;gt;&amp;lt;/title&amp;gt;
        &amp;lt;style type=&quot;text/css&quot;&amp;gt;
            table {
                border-collapse: collapse;
            }

            table, th, td {
                border: 1px solid black;
            }
        &amp;lt;/style&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
&amp;lt;# 
foreach (IGrouping&amp;lt;string, Tuple&amp;lt;string, string&amp;gt;&amp;gt; chapter in this.Chapters)
{
#&amp;gt;
        &amp;lt;h1&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;#= chapter.Key #&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;#
    foreach (Tuple&amp;lt;string, string&amp;gt; section in chapter)
    {
#&amp;gt;
        &amp;lt;h2&amp;gt;&amp;lt;#= section.Item1 #&amp;gt;&amp;lt;/h2&amp;gt;
        &amp;lt;#= section.Item2 #&amp;gt;
&amp;lt;#
    }
}
#&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned. &amp;lt;h1&amp;gt; represents each chapter title, and &amp;lt;h2&amp;gt; represents each section title. A little CSS is used to unify all tables with 1 pixel solid border. This Html.tt file will automatically generate a Html.cs file, containing above Html type.&lt;/p&gt;
&lt;p&gt;The generated Html class is a partial class, so that some custom code can be appended to make is more intuitive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class Html
{
    internal Html(string title, IEnumerable&amp;lt;IGrouping&amp;lt;string, Tuple&amp;lt;string, string&amp;gt;&amp;gt;&amp;gt; chapters)
    {
        this.Title = title;
        this.Chapters = chapters;
    }

    internal string Title { get; }

    internal IEnumerable&amp;lt;IGrouping&amp;lt;string, Tuple&amp;lt;string, string&amp;gt;&amp;gt;&amp;gt; Chapters { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Straightforward. To get the HTML string, just need to call Html.TransformText method, which is defined in the generated Html.cs.&lt;/p&gt;
&lt;h2&gt;Convert HTML to Word document via VSTO&lt;/h2&gt;
&lt;p&gt;As fore mentioned, one possible way is to using Microsoft’s Open XML SDK. It is extremely easy with a third party helper &lt;a href=&quot;https://html2openxml.codeplex.com/&quot;&gt;HtmlToOpenXml&lt;/a&gt;, which is also available from &lt;a href=&quot;https://www.nuget.org/packages/HtmlToOpenXml.dll&quot;&gt;Nuget&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-Package HtmlToOpenXml.dll
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static byte[] HtmlToWord(string html, string fileName)
{
    using (MemoryStream memoryStream = new MemoryStream())
    using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(
        memoryStream, WordprocessingDocumentType.Document))
    {
        MainDocumentPart mainPart = wordDocument.MainDocumentPart;
        if (mainPart == null)
        {
            mainPart = wordDocument.AddMainDocumentPart();
            new Document(new Body()).Save(mainPart);
        }

        HtmlConverter converter = new HtmlConverter(mainPart);
        converter.ImageProcessing = ImageProcessing.AutomaticDownload;
        Body body = mainPart.Document.Body;

        IList&amp;lt;OpenXmlCompositeElement&amp;gt; paragraphs = converter.Parse(html);
        body.Append(paragraphs);

        mainPart.Document.Save();
        return memoryStream.ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, the result document’s format is totally messed up. There is no other mature library for this (Microsoft’s &lt;a href=&quot;https://github.com/OfficeDev/Open-Xml-PowerTools&quot;&gt;Power Tools for Open XML&lt;/a&gt; provides APIs to convert Word document’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Office_Open_XML&quot;&gt;Open XML&lt;/a&gt; into HTML, but there is no API to convert HTML to Open XML), so the other way, VSTO, will be the solution.&lt;/p&gt;
&lt;p&gt;Microsoft word is a powerful application. It can directly open HTML document, and save it as Word document. So the task becomes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Save above Html object as a HTML document.&lt;/li&gt;
&lt;li&gt;Use Word application to open the saved HTML document.&lt;/li&gt;
&lt;li&gt;Format the document.&lt;/li&gt;
&lt;li&gt;Save the document as word document.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;private static void ConvertDocument(
    string inputFile, WdOpenFormat inputFormat,
    string outputFile, WdSaveFormat outputFormat,
    Action&amp;lt;Document&amp;gt; format = null,
    bool isWordVisible = false)
{
    Application word = null;
    try
    {
        word = new Application { Visible = isWordVisible };

        Console.WriteLine($&quot;Opening {inputFile} as {inputFormat}.&quot;);
        word.Documents.Open(inputFile, Format: inputFormat);
        Document document = word.Documents[inputFile];

        format?.Invoke(document);

        Console.WriteLine($&quot;Saving {outputFile} as {outputFormat}&quot;);
        document.SaveAs2(outputFile, outputFormat);
    }
    finally
    {
        word?.Documents?.Close();
        word?.Quit();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Format word document via VSTO&lt;/h2&gt;
&lt;p&gt;The task has the following steps (in order):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download all referenced pictures (&amp;lt;img&amp;gt; tags in HTML), and save them along with the Word document, so that the document can be viewed offline.&lt;/li&gt;
&lt;li&gt;Apply a specified template (.dot) to the Word document. This is the easiest way to format document’s
&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;table of contents&lt;/li&gt;
&lt;li&gt;header&lt;/li&gt;
&lt;li&gt;footer (page number)&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Insert a detailed table of contents to the Word document, which shows all headings of the tutorial.&lt;/li&gt;
&lt;li&gt;Insert a abstract table of contents to the Word document, which only shows chapter titles (“Heading 1” fields in Word, or &amp;lt;h1&amp;gt; tags in HTM).&lt;/li&gt;
&lt;li&gt;Insert a title to the Word document (“Title” field in word, or &amp;lt;title&amp;gt; tag in HTML)&lt;/li&gt;
&lt;li&gt;Insert author next to the title.&lt;/li&gt;
&lt;li&gt;Insert page numbers to the Word document footer.&lt;/li&gt;
&lt;li&gt;Insert chapter (fields with “Heading 1”) to Word document header via FieldStyleRef.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And the code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void FormatDocument(Document document, Html html, string template, string author = &quot;Dixin Yan&quot;)
{
    document.InlineShapes
            .OfType&amp;lt;InlineShape&amp;gt;()
            .Where(shape =&amp;gt; shape.Type == WdInlineShapeType.wdInlineShapeLinkedPicture)
            .ForEach(picture =&amp;gt;
            {
                Console.WriteLine($&quot;Downloading {picture.LinkFormat.SourceFullName}&quot;);
                picture.LinkFormat.SavePictureWithDocument = true;
            });

    Console.WriteLine($&quot;Applying template {template}&quot;);
    document.set_AttachedTemplate(template);
    document.UpdateStyles();

    Range range = document.Range(document.Content.Start, document.Content.Start);

    document.TablesOfContents.Add(range);

    TableOfContents table = document.TablesOfContents.Add(range, LowerHeadingLevel: 1);

    Console.WriteLine($&quot;Adding title {html.Title}&quot;);
    Paragraph titleParagraph = document.Paragraphs.Add(range);
    titleParagraph.Range.Text = $&quot;{html.Title}{Environment.NewLine}&quot;;
    range.set_Style(&quot;Title&quot;);

    Console.WriteLine($&quot;Adding author {author}&quot;);
    range = document.Range(table.Range.Start, table.Range.Start);
    Paragraph authorParagraph = document.Paragraphs.Add(range);
    authorParagraph.Range.Text = $&quot;{author}{Environment.NewLine}&quot;;
    range.set_Style(&quot;Author&quot;);

    range = document.Range(table.Range.End, table.Range.End);
    range.InsertBreak(WdBreakType.wdPageBreak);

    document.Sections.OfType&amp;lt;Section&amp;gt;().ForEach(section =&amp;gt;
    {
        range = section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
        range.Fields.Add(range, WdFieldType.wdFieldStyleRef, @&quot;&quot;&quot;Heading 1&quot;&quot;&quot;, true);

        section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].PageNumbers.Add(
            WdPageNumberAlignment.wdAlignPageNumberCenter);
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The VSTO programming is not intuitive, and APIs are lack of examples. It was quite time consuming to insert the FieldStyleRef - the style name is not “Heading 1”, but “&quot;Heading 1&quot;”, the double quote around the style ref name is required.&lt;/p&gt;
&lt;h2&gt;Save as Word document via VSTO&lt;/h2&gt;
&lt;p&gt;The is the method to save as Word document (.doc)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void SaveDocument(Html html, string outputDocument)
{
    string tempHtmlFile = Path.ChangeExtension(Path.GetTempFileName(), &quot;htm&quot;);
    string htmlContent = html.TransformText();
    Console.WriteLine($&quot;Saving HTML as {tempHtmlFile}, {htmlContent.Length}.&quot;);
    File.WriteAllText(tempHtmlFile, htmlContent);

    string template = Path.Combine(PathHelper.ExecutingDirectory(), &quot;Book.dot&quot;);
    ConvertDocument(
        tempHtmlFile, WdOpenFormat.wdOpenFormatWebPages,
        outputDocument, WdSaveFormat.wdFormatDocument,
        document =&amp;gt; FormatDocument(document, html, template));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how to call it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Main(string[] arguments)
{
    string outputDirectory = arguments.Any() &amp;amp;&amp;amp; !string.IsNullOrWhiteSpace(arguments.First())
        ? arguments.First()
        : (PathHelper.TryGetOneDrive(out outputDirectory)
            ? Path.Combine(outputDirectory, @&quot;Share\Book&quot;)
            : Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));

    Html html = DownloadHtml();
    SaveDocument(html, Path.Combine(outputDirectory, $&quot;{html.Title}.doc&quot;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default the document is saved to my local OneDrive directory, so that readers and always get the latest version of tutorial from there. If OneDrive does not exist, it is saved to local desktop.&lt;/p&gt;
&lt;h2&gt;Share document via OneDrive&lt;/h2&gt;
&lt;p&gt;To get the OneDrive local path:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First lookup the registry: HKEY_CURRENT_USER\Software\Microsoft\OneDrive&lt;/li&gt;
&lt;li&gt;If not found, then lookup a .ini file in %LocalApplicationData%\Microsoft\OneDrive\Settings\Personal&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The last line of the .ini file contains the local OneDrive path, e.g.:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;library = 1 4 A3BD24426A36B9EE!129 1388966861 &quot;SkyDrive&quot; Me personal &quot;D:\SkyDrive&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And here is the implementation of above TryGetOneDriveRoot method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool TryGetOneDriveRoot(out string oneDrive)
{
    oneDrive = Registry.GetValue(
        @&quot;HKEY_CURRENT_USER\Software\Microsoft\OneDrive&quot;, &quot;UserFolder&quot;, null) as string;
    if (!string.IsNullOrWhiteSpace(oneDrive))
    {
        return true;
    }

    string settingsDirectory = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        @&quot;Microsoft\OneDrive\Settings\Personal&quot;);
    if (!Directory.Exists(settingsDirectory))
    {
        return false;
    }

    try
    {
        string datFile = Directory.EnumerateFiles(settingsDirectory, &quot;*.dat&quot;).FirstOrDefault();
        string iniFile = Path.ChangeExtension(datFile, &quot;ini&quot;);
        oneDrive = File.ReadLines(iniFile)
            .Last(line =&amp;gt; !string.IsNullOrWhiteSpace(line))
            .Split(new char[] { &apos; &apos; }, StringSplitOptions.RemoveEmptyEntries)
            .Last()
            .Trim(&apos;&quot;&apos;);
        return !string.IsNullOrWhiteSpace(oneDrive);
    }
    catch (Exception exception) when (exception.IsNotCritical())
    {
        return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After saving the file to the right location, it is automatically uploaded to OneDrive:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_9.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It is not straightforward to perform the entire job. Many technologies have to be involved:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages/CsQuery/&quot;&gt;CsQuery&lt;/a&gt; is used for HTML DOM traversal and manipulation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Text_Template_Transformation_Toolkit&quot;&gt;T4 template&lt;/a&gt; is used for HTML merging and formatting.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Visual_Studio_Tools_for_Office&quot;&gt;VSTO&lt;/a&gt; is used to open, format, and save/convert HTML file to Microsoft Word document.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/OneDrive&quot;&gt;OneDrive&lt;/a&gt; is used to share the latest build of the document.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The is the final look of the project (Book.csproj):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_2.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And below is the converted Word document (no manual editing at all):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First page: title, author, abstract table of contents &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_7.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Detailed table of contents: &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_8.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Beginning of a chapter: &lt;a href=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_12.png&quot;&gt;&lt;img src=&quot;https://mscblogs.blob.core.windows.net/media/dixin/Windows-Live-Writer/Convert-HTML-to-Word-Document_DFBE/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently, the entire tutorial has 558 pages. Hope it helps.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (3) Logging</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-3-logging/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-3-logging/</guid><description>As fore mentioned, this tutorial will use SQL Profiler to trace the remote SQL queries, which are translated from the LINQ to Entities queries. This is most close the the truth, because the tracing un</description><pubDate>Mon, 22 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-3-logging-and-tracing-queries&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As fore mentioned, this tutorial will use SQL Profiler to trace the remote SQL queries, which are translated from the LINQ to Entities queries. This is most close the the truth, because the tracing uncovers the actual SQL query executed in SQL database. Entity Framework also provides several options to log the translated SQL database operations programmatically.&lt;/p&gt;
&lt;h2&gt;DbQuery&amp;lt;T&amp;gt;.ToString&lt;/h2&gt;
&lt;p&gt;For queries, the easiest way is to call ToString method on the IQueryable&amp;lt;T&amp;gt; object. In LINQ to Entities query, the IQueryable&amp;lt;T&amp;gt; is actually implemented with System.Data.Entity.Infrastructure.DbQuery&amp;lt;T&amp;gt;. DbQuery&amp;lt;T&amp;gt;.ToString returns its SQL translation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Log
{
    internal static void DbQueryToString()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
            string translatedSql = source.ToString();
            Trace.WriteLine(translatedSql);
            // SELECT 
            //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
            //    [Extent1].[Name] AS [Name]
            //    FROM [Production].[ProductCategory] AS [Extent1]
            source.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Database.Log&lt;/h2&gt;
&lt;p&gt;Besides LINQ to Entities queries, Entity Framework also supports other database operations, like updating the database. So a more general logging API is provides. The DbContext class has a Database property to expose a System.Data.Entity.Database object, where a Log action can be specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class DbContext : IDisposable, IObjectContextAdapter
    {
        public Database Database { get; }

        // Other members.
    }

    public class Database
    {
        public Action&amp;lt;string&amp;gt; Log { get; set; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Log action will be called for all database operations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DatabaseLog()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.Database.Log = log =&amp;gt; Trace.Write(log);
        IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
        source.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
        // Opened connection at 5/21/2016 12:33:34 AM -07:00
        // SELECT 
        //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        //    [Extent1].[Name] AS [Name]
        //    FROM [Production].[ProductCategory] AS [Extent1]
        // -- Executing at 5/21/2016 12:31:58 AM -07:00
        // -- Completed in 11 ms with result: SqlDataReader4
        // Closed connection at 5/21/2016 12:33:35 AM -07:00
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IDbCommandInterceptor&lt;/h2&gt;
&lt;p&gt;For low-level logging control, Entity Framework provides System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure.Interception
{
    public interface IDbCommandInterceptor : IDbInterceptor // IDbInterceptor is an empty interface.
    {
        void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext);

        void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext);

        void ReaderExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext);

        void ReaderExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext);

        void ScalarExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext);

        void ScalarExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a simple implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class DbCommandInterceptor : IDbCommandInterceptor
{
    private readonly Action&amp;lt;string&amp;gt; log;

    internal DbCommandInterceptor(Action&amp;lt;string&amp;gt; log)
    {
        this.log = log;
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.NonQueryExecuting), interceptionContext, command);

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;int&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.NonQueryExecuting), interceptionContext);

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.ReaderExecuting), interceptionContext, command);

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;DbDataReader&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.ReaderExecuted), interceptionContext);

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.ScalarExecuting), interceptionContext, command);

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext&amp;lt;object&amp;gt; interceptionContext) =&amp;gt;
        this.Log(nameof(this.ScalarExecuted), interceptionContext);

    private void Log&amp;lt;TResult&amp;gt;(
        string @event, DbCommandInterceptionContext&amp;lt;TResult&amp;gt; interceptionContext, DbCommand command = null)
    {
        Exception exception = interceptionContext.Exception;
        if (command == null)
        {
            this.log(exception == null ? @event : $&quot;{@event}: {exception}&quot;);
        }
        else
        {
            this.log($@&quot;{@event}: {command.CommandText}{string.Concat(command.Parameters
                .OfType&amp;lt;DbParameter&amp;gt;()
                .Select(parameter =&amp;gt; $&quot;, {parameter.ParameterName}={parameter.Value}&quot;))}&quot;);
            if (exception != null)
            {
                this.log($@&quot;{@event}: {exception}&quot;);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An interceptor has to be registered with System.Data.Entity.Infrastructure.Interception.DbInterception.Add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DbCommandInterceptor()
{
    DbCommandInterceptor dbCommandTrace = new DbCommandInterceptor(message =&amp;gt; Trace.WriteLine(message));
    DbInterception.Add(dbCommandTrace);
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductCategory&amp;gt; source = adventureWorks.ProductCategories; // Define query.
        source.ForEach(category =&amp;gt; Trace.WriteLine(category.Name)); // Execute query.
        // ReaderExecuting: SELECT 
        //    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
        //    [Extent1].[Name] AS [Name]
        //    FROM [Production].[ProductCategory] AS [Extent1]
        // ReaderExecuted
    }
    DbInterception.Remove(dbCommandTrace);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Use Fiddler with Node.js</title><link>https://dixin.github.io/posts/use-fiddler-with-node-js/</link><guid isPermaLink="true">https://dixin.github.io/posts/use-fiddler-with-node-js/</guid><description>) is an useful HTTP proxy debugger on Windows. It would be nice if it can work with  applica</description><pubDate>Mon, 22 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Fiddler_(software)&quot;&gt;Fiddler&lt;/a&gt; is an useful HTTP proxy debugger on Windows. It would be nice if it can work with &lt;a href=&quot;https://en.wikipedia.org/wiki/Node.js&quot;&gt;Node.js&lt;/a&gt; applications. To do this, just need to proxy Node.js requests through Fiddler. The default proxy is 127.0.0.1:8888. This can be viewed in Fiddler Tools –&amp;gt; WInINET Options –&amp;gt; LAN settings –&amp;gt; Advanced:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Request module&lt;/h2&gt;
&lt;p&gt;If the &lt;a href=&quot;https://www.npmjs.com/package/request&quot;&gt;request module&lt;/a&gt; is used to send requests, it is relatively easier. Environment variables can be used to turn on/off current node.js process’s fiddler proxy settings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set https_proxy=http://127.0.0.1:8888
set http_proxy=http://127.0.0.1:8888
set NODE_TLS_REJECT_UNAUTHORIZED=0
node Dixin.Nodejs\main.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s done. After setting the above 3 environment variables, when calling request module to send requests, they will be captured by Fiddler. If the proxy settings needs to be turned off, just set these environment variables to empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set https_proxy=
set http_proxy=
set NODE_TLS_REJECT_UNAUTHORIZED=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be done with JavaScript. Here is part of a simple fiddler.js module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;use strict&quot;;

var url = require(&quot;url&quot;),
    http = require(&quot;http&quot;),

    env = process.env,

    proxy = {
        protocol: &quot;http:&quot;,
        hostname: &quot;127.0.0.1&quot;,
        port: 8888,
    },

    proxyRequests = function () {
        var proxyUrl = url.format(proxy);
        env.http_proxy = proxyUrl;
        env.https_proxy = proxyUrl;
        env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
    },

    unproxyRequests = function () {
        env.http_proxy = &quot;&quot;;
        env.https_proxy = &quot;&quot;;
        env.NODE_TLS_REJECT_UNAUTHORIZED = &quot;&quot;;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The usage is straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var fiddler = require(&quot;./fiddler&quot;);
fiddler.proxyRequests();
// requests.
fiddler.unproxyRequests();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;HTTP/HTTPS module&lt;/h2&gt;
&lt;p&gt;If requests are sent with &lt;a href=&quot;https://nodejs.org/api/http.html&quot;&gt;HTTP&lt;/a&gt;/&lt;a href=&quot;https://nodejs.org/api/https.html&quot;&gt;HTTPS&lt;/a&gt; modules of Node.js, there is no global switch to turn on/off proxy settings for all requests. Some helper methods can be created to proxy an individual HTTP request to Fiddler. Below is the rest of the fiddler.js module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setProxy = function (options) {
        if (typeof options === &quot;string&quot;) { // options can be URL string.
            options = url.parse(options);
        }
        if (!options.host &amp;amp;&amp;amp; !options.hostname) {
            throw new Error(&quot;host or hostname must have value.&quot;);
        }
        options.path = url.format(options);
        options.headers = options.headers || {};
        options.headers.Host = options.host || url.format({
            hostname: options.hostname,
            port: options.port
        });
        options.protocol = proxy.protocol;
        options.hostname = proxy.hostname;
        options.port = proxy.port;
        options.href = null;
        options.host = null;
        return options;
    },

    request = function (options, callback) {
        options = setProxy(options);
        return http.request(options, callback);
    },
    
    get = function(options, callback) {
        options = setProxy(options);
        return http.get(options, callback);
    };

module.exports = {
    proxy: proxy,
    proxyRequests: proxyRequests,
    unproxyRequests: unproxyRequests,
    setProxy: setProxy,
    request: request,
    get: get
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling HTTP/HTTPS modules to send a request, call setProxy to proxy the request to Fiddler:&lt;/p&gt;
&lt;p&gt;setProxy is used for the url/options, before passing it to call HTTP module methods, like request, get, etc. The following example proxies the request to URL string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var http = require(&quot;http&quot;),
    https = require(&quot;https&quot;),
    fiddler = require(&quot;./fiddler&quot;);

var photoUrl = &quot;https://c1.staticflickr.com/3/2875/9215169916_f8fa57c3da_b.jpg&quot;;

https.request(photoUrl).end(); // Not through Fiddler.

http.request(fiddler.setProxy(photoUrl)).end(); // Through Fiddler.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second request can be viewed in Fiddler:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Similarly, setProxy can be used for URI options:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var blogUrl = {
    protocol: &quot;https:&quot;,
    hostname: &quot;weblogs.asp.net&quot;,
    pathname: &quot;dixin&quot;
};

https.get(blogUrl).end(); // Not through Fiddler.

http.get(fiddler.setProxy(blogUrl)); // Through Fiddler.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second request is in Fiddler:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Use-Fiddler-with-Nodejs_F458/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A get method and a request method are also provided. They are just shortcuts. The above calls are equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fiddler.request(photoUrl).end();
fiddler.get(blogUrl);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The complete fiddler.js module is available in GitHub: &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/blob/master/Dixin.Nodejs/fiddler.js&quot;&gt;https://github.com/Dixin/CodeSnippets/blob/master/Dixin.Nodejs/fiddler.js&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (2) Object-Relational Mapping</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-2-object-relational-mapping/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-2-object-relational-mapping/</guid><description>.NET and SQL database and have 2 different data type systems. For example:</description><pubDate>Sat, 20 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;EF Core version of this article: &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&quot;&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-2-modeling-database-object-relational-mapping&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;.NET and SQL database and have 2 different data type systems. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET has System.Int64 and System.String, while SQL database has bigint and nvarchar;&lt;/li&gt;
&lt;li&gt;.NET has collections and objects, while SQL database has tables and rows;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.. Object-relational mapping is a popular technology to map and convert between programming language data objects and database system relational data. In Entity Framework, the LINQ to Entities queries are all based on Object-relational mapping.&lt;/p&gt;
&lt;p&gt;Entity Framework provides &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms178359.aspx#dbfmfcf&quot;&gt;3 options&lt;/a&gt; to build the mapping between C#/.NET and SQL database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-in/data/ff830362.aspx&quot;&gt;Model first&lt;/a&gt;: The entity data models (a .edmx diagram consists of entities, entity properties, entity associations, etc.) are created in Entity Framework., typically with the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/cc716685.aspx&quot;&gt;ADO.NET Entity Data Model Designer&lt;/a&gt; tool in Visual Studio. Then, Entity Framework can use the models to generate database and the mapping .NET classes. In the following entity data models (a .edmx diagram) looks, the options to generate database/code are available from the right click menu. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj206878.aspx&quot;&gt;Database first&lt;/a&gt;: From an existing database, Entity Framework generates the entity data models (.edmx diagram) and the mapping .NET classes. In Visual Studio, the following Entity Data Model Wizard enables developer to select tables and other objects to generate entity data models (.edmx diagram) and code: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Code first: The mapping .NET classes can be coded first, then they can be immediately work with Entity Framework and LINQ to Entities queries. Entity Framework generates the entity data models at runtime, so that a static .edmx diagram is not visible at design time in code base. If the database exits, the .NET classes are just mapped to the existing database; if not, Entity Framework can generate the database. &lt;a href=&quot;http://blogs.msdn.com/b/adonet/archive/2014/10/21/ef7-what-does-code-first-only-really-mean.aspx&quot;&gt;“Code first” is a bad naming&lt;/a&gt;. It does not mean code comes first before the database exists. It is actually code-based modeling for &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj200620&quot;&gt;existing database&lt;/a&gt; or &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj193542&quot;&gt;new database&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Comparing to code generation, it is more intuitive to build some classes to work with database. It is also much easier if the entity data models (.edmx diagram) is not involved. So this tutorial follows the code first approach, with an existing AdventureWorks database – the sample database from Microsoft, which already has data for query.&lt;/p&gt;
&lt;h2&gt;Data types&lt;/h2&gt;
&lt;p&gt;Entity Framework can map most SQL data types to .NET types:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;629&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;SQL type category&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;SQL type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;.NET type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;C# primitive&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Exact numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;bit&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Boolean&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;bool&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;tinyint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Byte&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;byte&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;smallint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Int16&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;short&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;int&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Int32&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;int&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;bigint&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Int64&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;long&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;smallmoney, money, decimal, numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Decimal&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;decimal&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Approximate numeric&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;real&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Single&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;float&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;float&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Double&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;double&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Character string&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;char, varchar, text&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;nchar, nvarchar, ntext&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Binary string&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;binary, varbinary&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;image&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;rowversion (timestamp)&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Byte[]&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;byte[]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Date time&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;date&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.DateTime&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;time&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.TimeSpan&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;smalldatetime, datetime, datetime2&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.DateTime&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;datetimeoffset&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.DateTimeOffset&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Spatial type&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;geography&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Data.Entity.Spatial.DbGeography&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;geometry&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Data.Entity.Spatial.DbGeometry&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;Other&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;hierarchyid&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;No built-in mapping or support&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;xml&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.String&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;string&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;uniqueidentifier&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;System.Guid&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;150&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&quot;190&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;200&quot;&amp;gt;sql_variant&amp;lt;/td&amp;gt;&amp;lt;td width=&quot;300&quot;&amp;gt;No built-in mapping or support&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;107&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;h2&gt;Database&lt;/h2&gt;
&lt;p&gt;A SQL database is mapped to a class that derives from System.Data.Entity.DbContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks : DbContext
{
    public AdventureWorks()
        : base(ConnectionStrings.AdventureWorks)
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbContext is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class DbContext : IDisposable, IObjectContextAdapter
    {
        public DbContext(string nameOrConnectionString);

        public DbChangeTracker ChangeTracker { get; }

        public DbContextConfiguration Configuration { get; }

        public Database Database { get; }

        ObjectContext IObjectContextAdapter.ObjectContext { get; } // From IObjectContextAdapter.

        public void Dispose(); // From IDisposable.

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The database is specified in the connection string provided to DbContext’s constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ConnectionStrings
{
    internal const string AdventureWorks = @&quot;Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\AdventureWorks_Data.mdf;Integrated Security=True;Connect Timeout=30&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please replace the application domain property |DataDirectory| to the actual directory of the database file, or initialize it for current application domain before it is used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ConnectionStrings
{
    static ConnectionStrings()
    {
        AppDomain.CurrentDomain.SetData(&quot;DataDirectory&quot;, @&quot;D:\GitHub\CodeSnippets\Data&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generally, a database object should be constructed and disposed for each &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Query
{
    internal static void Dispose()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            // Unit of work.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Tables&lt;/h2&gt;
&lt;p&gt;There are tens of tables in the AdventureWorks database, but don’t worry, this tutorial only involves 5 tables, and a few columns of these tables. In Entity Framework, a table definition can be mapped to an entity class definition, where each column is mapped to a entity property. For example, the AdventureWorks database has a Production.ProductCategory table, which is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE SCHEMA [Production]
GO

CREATE TYPE [dbo].[Name] FROM nvarchar(50) NULL
GO

CREATE TABLE [Production].[ProductCategory](
    [ProductCategoryID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductCategory_ProductCategoryID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [rowguid] uniqueidentifier ROWGUIDCOL NOT NULL -- Ignored in mapping.
        CONSTRAINT [DF_ProductCategory_rowguid] DEFAULT (NEWID()),
    
    [ModifiedDate] datetime NOT NULL -- Ignored in mapping.
        CONSTRAINT [DF_ProductCategory_ModifiedDate] DEFAULT (GETDATE()))
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above Production.ProductCategory table definition can be mapped to a ProductCategory entity class definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public const string Production = nameof(Production); // Production schema.
}

[Table(nameof(ProductCategory), Schema = AdventureWorks.Production)]
public partial class ProductCategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductCategoryID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    // Other columns are ignored.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The [Table] attribute specifies the table name of schema. [Table] can be omitted when the table name is identical with the entity class name, and the table is under the default dbo schema.&lt;/p&gt;
&lt;p&gt;In the table-entity class mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The int column ProductCategoryID is mapped to a System.Int32 property with the same name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The [Key] attribute indicates it has a unique key&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[DatabaseGenerated] indicates it is an identity column&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Name column is of dbo.Name type. dbo.Name just nvarchar(50), so the Name property is of type System.String.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The [MaxLength] attribute indicates the max length is 50&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[Required] indicates it should not be null&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The other columns rowguid and ModifiedDate are not mapped. They are ignored in this tutorial, which is allowed by Entity Framework.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the Entity Framework code first approach for existing database, the mapping properties work without the [DatabaseGenerated] attribute. This tutorial keeps this attribute only for readability purpose.&lt;/p&gt;
&lt;p&gt;As a result, each row of Production.ProductCategory table is mapped to a ProductCategory object. However, at runtime, Entity Framework by default does not directly instantiate ProductCategory. It dynamically defines another proxy class to derive from ProductCategory class, with a name looks like System.Data.Entity.DynamicProxies.Product_F84B0F952ED22479EF48782695177D770E63BC4D8771C9DF78343B4D95926AE8. This proxy class is where Entity Framework injects more detailed logic, so that at design time, the mapping entity class can be clean and declarative.&lt;/p&gt;
&lt;p&gt;The rows of the entire table can be mapped to objects in an IQueryable&amp;lt;T&amp;gt; data source, exposed as a property of the database class. Entity Framework provides System.Data.Entity.DbSet&amp;lt;T&amp;gt; class to represent a table data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;ProductCategory&amp;gt; ProductCategories { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt;, and is derived from System.Data.Entity.Infrastructure.DbQuery&amp;lt;T&amp;gt; class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure
{
    public class DbQuery&amp;lt;TResult&amp;gt; : IOrderedQueryable&amp;lt;TResult&amp;gt;, IQueryable&amp;lt;TResult&amp;gt;,
        IOrderedQueryable, IQueryable, IEnumerable&amp;lt;TResult&amp;gt;, IEnumerable,
        IDbAsyncEnumerable&amp;lt;TResult&amp;gt;, IDbAsyncEnumerable, IListSource, IInternalQueryAdapter
    {
        Type IQueryable.ElementType { get; }

        Expression IQueryable.Expression { get; }

        IQueryProvider IQueryable.Provider { get; } // Return System.Data.Entity.Internal.Linq.DbQueryProvider object.

        // Other members.
    }
}

namespace System.Data.Entity
{
    public class DbSet&amp;lt;TEntity&amp;gt; : DbQuery&amp;lt;TEntity&amp;gt;, IDbSet&amp;lt;TEntity&amp;gt;, IQueryable&amp;lt;TEntity&amp;gt;, IQueryable,
        IEnumerable&amp;lt;TEntity&amp;gt;, IEnumerable, IInternalSetAdapter where TEntity : class
    {
        // Members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next example is the Production.ProductSubcategory table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductSubcategory](
    [ProductSubcategoryID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductSubcategory_ProductSubcategoryID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [ProductCategoryID] int NOT NULL
        CONSTRAINT [FK_ProductSubcategory_ProductCategory_ProductCategoryID] FOREIGN KEY
        REFERENCES [Production].[ProductCategory] ([ProductCategoryID]),

    /* Other ignored columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, it can be mapped to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductSubcategory), Schema = AdventureWorks.Production)]
public partial class ProductSubcategory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductSubcategoryID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    public int ProductCategoryID { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here ProductCategoryID is a foreign key. It will be further discussed soon.&lt;/p&gt;
&lt;p&gt;In this tutorial, a few more tables of AdventureWorks database will be involved. Here is the Production.Product table definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[Product](
    [ProductID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED,

    [Name] [dbo].[Name] NOT NULL, -- nvarchar(50).

    [ListPrice] money NOT NULL,

    [ProductSubcategoryID] int NULL
        CONSTRAINT [FK_Product_ProductSubcategory_ProductSubcategoryID] FOREIGN KEY
        REFERENCES [Production].[ProductSubcategory] ([ProductSubcategoryID]),

    [Style] nchar(2) NULL
        CONSTRAINT [CK_Product_Style] 
        CHECK (UPPER([Style]) = N&apos;U&apos; OR UPPER([Style]) = N&apos;M&apos; OR UPPER([Style]) = N&apos;W&apos; OR [Style] IS NULL),
    
    /* Other ignored columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be mapped to following Product entity class definition&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(Product), Schema = AdventureWorks.Production)]
public partial class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductID { get; set; }

    [MaxLength(50)]
    [Required]
    public string Name { get; set; }

    public decimal ListPrice { get; set; }

    public int? ProductSubcategoryID { get; set; }

    // public string Style { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ProductSubcategoryID column can be null, so it is mapped to a System.Nullable&amp;lt;int&amp;gt; property.&lt;/li&gt;
&lt;li&gt;The Style column can only have value U, M, W, or NULL. It does not have a property mapping, because it will be used to demonstrate conditional mapping in inheritance later in this part.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And this is the Production.ProductPhoto table definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductPhoto](
    [ProductPhotoID] int IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ProductPhoto_ProductPhotoID] PRIMARY KEY CLUSTERED,

    [LargePhotoFileName] nvarchar(50) NULL,
    
    [ModifiedDate] datetime NOT NULL 
        CONSTRAINT [DF_ProductPhoto_ModifiedDate] DEFAULT (GETDATE())

    /* Other ignored columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be mapped to the following ProductPhoto entity class definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductPhoto), Schema = AdventureWorks.Production)]
public partial class ProductPhoto
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductPhotoID { get; set; }

    [MaxLength(50)]
    public string LargePhotoFileName { get; set; }

    [ConcurrencyCheck]
    public DateTime ModifiedDate { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ModifiedDate has a [ConcurrencyCheck] attribute for concurrency conflict check, which will be discussed later.&lt;/p&gt;
&lt;p&gt;Again, the rows of each table can be expose as objects in IQueryable&amp;lt;T&amp;gt; data source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; }

    public DbSet&amp;lt;Product&amp;gt; Products { get; set; }

    public DbSet&amp;lt;ProductPhoto&amp;gt; ProductPhotos { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Relationships&lt;/h2&gt;
&lt;p&gt;In SQL database, tables can have &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms189049.aspx&quot;&gt;foreign key relationships&lt;/a&gt;. The following diagram visualizes the foreign key relationships of above 5 tables:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/a174a530a37c_12C6E/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;One-to-many&lt;/h3&gt;
&lt;p&gt;From top down, the Production.ProductCategory table and Production.ProductSubcategory has a one-to-many relationship. A row in Production.ProductCategory table can have many matching rows in Production.ProductSubcategory table. In Entity Framework, this relashionship is mapped to the associations between ProductCategory and ProductSubcategory entity classes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductCategory
{
    public virtual ICollection&amp;lt;ProductSubcategory&amp;gt; ProductSubcategories { get; set; } 
        = new HashSet&amp;lt;ProductSubcategory&amp;gt;();
}

public partial class ProductSubcategory
{
    // public int? ProductCategoryID { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One ProductCategory object can have many ProductSubcategory objects, and one ProductSubcategory object can have one ProductCategory object. These association properties are also called navigation properties. They are virtual properties, so that the association implementation details can be provided by the override of proxy class.&lt;/p&gt;
&lt;p&gt;Production.ProductSubcategory table and Production.Product table has the same one-to-many relationship. So the mapping associations are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductSubcategory
{
    public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; } = new HashSet&amp;lt;Product&amp;gt;();
}

public partial class Product
{
    // public int? ProductSubcategoryID { get; set; }
    public virtual ProductSubcategory ProductSubcategory { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Many-to-many&lt;/h3&gt;
&lt;p&gt;Production.Product table and Production.ProductPhoto table has many-to-many relationship. This is implemented by 2 one-to-many relationships with another Production.ProductProductPhoto junction table. In Entity Framework, there are 2 options to map this. The first option is to directly defined the to-many navigation properties for the entities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    public virtual ICollection&amp;lt;ProductPhoto&amp;gt; ProductPhotos { get; set; }
        = new HashSet&amp;lt;ProductPhoto&amp;gt;();
}

public partial class ProductPhoto
{
    public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; } = new HashSet&amp;lt;Product&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then specify the many-to-many association between them, and the junction table information for Entity Framework:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity&amp;lt;Product&amp;gt;()
            .HasMany(product =&amp;gt; product.ProductPhotos)
            .WithMany(photo =&amp;gt; photo.Products)
            .Map(mapping =&amp;gt; mapping
                .ToTable(&quot;ProductProductPhoto&quot;, Production)
                .MapLeftKey(&quot;ProductID&quot;)
                .MapRightKey(&quot;ProductPhotoID&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other options is to map whatever the database has. The junction table [Production].[ProductProductPhoto] is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [Production].[ProductProductPhoto](
    [ProductID] int NOT NULL
        CONSTRAINT [FK_ProductProductPhoto_Product_ProductID] FOREIGN KEY
        REFERENCES [Production].[Product] ([ProductID]),

    [ProductPhotoID] int NOT NULL
        CONSTRAINT [FK_ProductProductPhoto_ProductPhoto_ProductPhotoID] FOREIGN KEY
        REFERENCES [Production].[ProductPhoto] ([ProductPhotoID]),

    CONSTRAINT [PK_ProductProductPhoto_ProductID_ProductPhotoID] PRIMARY KEY NONCLUSTERED ([ProductID], [ProductPhotoID])
    
    /* Other ignored columns. */)
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is mapped to ProductProductPhoto entity class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(ProductProductPhoto), Schema = AdventureWorks.Production)]
public partial class ProductProductPhoto
{
    [Key]
    [Column(Order = 0)]
    public int ProductID { get; set; }

    [Key]
    [Column(Order = 1)]
    public int ProductPhotoID { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Production.ProductProductPhoto table’s primary key is defined on both 2 columns, so the ProductID and ProductPhotoID properties are both attributed as [Key]. And because of this, the [Column] attribute must be used to specify their orders.&lt;/p&gt;
&lt;p&gt;The many-to-many relationship is implemented by a one-to-many relationship between Production.Product and junction table, and another one-to-many relationship between Production.Product and junction table. These relationships are mapped to the following navigation properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } 
        = new HashSet&amp;lt;ProductProductPhoto&amp;gt;();
}

public partial class ProductPhoto
{
    public virtual ICollection&amp;lt;ProductProductPhoto&amp;gt; ProductProductPhotos { get; set; } 
        = new HashSet&amp;lt;ProductProductPhoto&amp;gt;();
}

public partial class ProductProductPhoto
{
    // public int ProductID { get; set; }
    public virtual Product Product { get; set; }

    // public int ProductPhotoID { get; set; }
    public virtual ProductPhoto ProductPhoto { get; set; }        
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following the KISS principle (keep it simple stupid), this tutorial uses the second mapping approach, so that the mapping is the same as database.&lt;/p&gt;
&lt;h2&gt;Inheritance&lt;/h2&gt;
&lt;p&gt;Above 5 tables’ mapping classes are independent from each other. In Entity Framework, the table’s mapping classes can also be in base/derived class of each other. Entity framework supports 3 types of inheritance for the mapping classes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.4&quot;&gt;Table per hierarchy (TPH)&lt;/a&gt;: one table is mapped with each base entity class and derived entity class in the class inheritance hierarchy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.5&quot;&gt;Table per type (TPT)&lt;/a&gt;: one table is mapped with one single entity class in the hierarchy&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/data/jj591617#2.6&quot;&gt;Table per concrete type (TPC)&lt;/a&gt;: one table is mapped with one non-abstract entity class in the hierarchy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial demonstrates the table per hierarchy inheritance, which is the default strategy of Entity Framework. In this case, one table is mapped to many entity classes in inheritance hierarchy, so a discriminator column is needed to specify each row’s mapping entity type. Above Production.Product table has a Style column to identify each row represents a women’s product (W), men’s product (M), or universal product (U). So the mapping hierarchy can be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class WomensProduct : Product
{
}

public class MensProduct : Product
{
}

public class UniversalProduct : Product
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, tell Entity Framework to map a row with W Style to a WomensProduct object, map a row with M Style to a MensProduct object, and map a row with U Style to a UniversalProduct object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum Style
{
    W,
    M,
    U
}

public partial class AdventureWorks
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity&amp;lt;Product&amp;gt;()
            .Map&amp;lt;WomensProduct&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(Style)).HasValue(nameof(Style.W)))
            .Map&amp;lt;MensProduct&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(Style)).HasValue(nameof(Style.M)))
            .Map&amp;lt;UniversalProduct&amp;gt;(mapping =&amp;gt; mapping.Requires(nameof(Style)).HasValue(nameof(Style.U)));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Style column is used for conditional class mapping, so it was not used for property mapping in above Product entity class definition. Style column can also be NULL. When a row has NULL Style, it is mapped to a Product object.&lt;/p&gt;
&lt;h2&gt;Views&lt;/h2&gt;
&lt;p&gt;A view definition are also be mapped to a entity class definition, as if it is a table. Take the Production.vProductAndDescription view as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE VIEW [Production].[vProductAndDescription2] 
WITH SCHEMABINDING 
AS 
SELECT 
    [product].[ProductID],
    [product].[Name],
    [model].[Name] AS [ProductModel],
    [culture].[CultureID],
    [description].[Description] 
FROM [Production].[Product] [product]
    INNER JOIN [Production].[ProductModel] [model]
    ON [product].[ProductModelID] = model.[ProductModelID] 
    INNER JOIN [Production].[ProductModelProductDescriptionCulture] [culture]
    ON [model].[ProductModelID] = [culture].[ProductModelID] 
    INNER JOIN [Production].[ProductDescription] [description]
    ON [culture].[ProductDescriptionID] = [description].[ProductDescriptionID];
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The mapping is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(nameof(vProductAndDescription), Schema = AdventureWorks.Production)]
public class vProductAndDescription
{
    [Key]
    public int ProductID { get; set; }

    public string Name { get; set; }

    public string ProductModel { get; set; }

    public string CultureID { get; set; }

    public string Description { get; set; }
}

public class vProductAndDescriptionMapping : EntityTypeConfiguration&amp;lt;vProductAndDescription&amp;gt;
{
    public vProductAndDescriptionMapping()
    {
        this.ToTable(nameof(vProductAndDescription));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[Table] is required for the view’s entity class. Also, in SQL database, views cannot have unique keys, but in the entity class, [Key] is still required just like tables. An additional mapping class and ToTable call are needed to make the view mapping work. And, finally, the rows in the view can be exposed as IQueryable&amp;lt;T&amp;gt; data source, still represented by DbSet&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public DbSet&amp;lt;vProductAndDescription&amp;gt; ProductAndDescriptions { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Stored procedures and functions&lt;/h2&gt;
&lt;p&gt;Entity Framework code first does not have built-in support to map stored procedures and functions in SQL database. But the .NET mapping can still be implemented for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stored procedures, with:
&lt;ul&gt;
&lt;li&gt;single result type&lt;/li&gt;
&lt;li&gt;multiple result types&lt;/li&gt;
&lt;li&gt;output parameter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Table-valued functions&lt;/li&gt;
&lt;li&gt;Scalar-valued functions
&lt;ul&gt;
&lt;li&gt;composable&lt;/li&gt;
&lt;li&gt;non-composable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregate functions&lt;/li&gt;
&lt;li&gt;Built-in functions&lt;/li&gt;
&lt;li&gt;Niladic functions&lt;/li&gt;
&lt;li&gt;Model defined functions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These contents are covered by a separate article: &lt;a href=&quot;https://weblogs.asp.net/Dixin/EntityFramework.Functions&quot;&gt;EntityFramework.Functions: Code First Functions for Entity Framework&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (5) Query Translation</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-5-query-translation/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-5-query-translation/</guid><description>The previous part discussed what SQL queries are the LINQ to Entities queries translated to. This part discusses how the LINQ to Entities queries are translated to SQL queries. As fore mentioned, IQue</description><pubDate>Sat, 20 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-5-query-translation-implementation&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous part discussed what SQL queries are the LINQ to Entities queries translated to. This part discusses how the LINQ to Entities queries are translated to SQL queries. As fore mentioned, IQueryable&amp;lt;T&amp;gt; query methods work with expression trees. Internally, these methods build expression trees too, then these expression trees are translated. In Entity Framework, .NET expression tree is not directly translated to SQL query. As mentioned at the beginning of this chapter, Entity Framework implements a provider model to work with different kinds of databases like Oracle, MySQL, PostgreSQL, etc., and different database system can have different query languages. So Entity Framework breaks the translation into 2 parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EntityFramework.dll translates .NET expression tree to generic, intermediate database command tree&lt;/li&gt;
&lt;li&gt;The specific database provider (like EntityFramework.SqlServer.dll here) is responsible to generate database query specific to that kind of database.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Code to expression tree&lt;/h2&gt;
&lt;p&gt;The first step of query translation is to build .NET expression tree. As fore mentioned, expression tree enables code as data. In C#, an expression tree shares the same syntax as functions, but C# code for expression tree is compiled to the building of an abstract syntactic tree, representing the abstract syntactic structure of the function’s source code. In LINQ, IQueryable&amp;lt;T&amp;gt; utilizes expression tree to represent the abstract syntactic structure of a remote query.&lt;/p&gt;
&lt;h3&gt;IQueryable&amp;lt;T&amp;gt; and IQueryProvider&lt;/h3&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; has been demonstrated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable
    {
        // Expression Expression { get; } from IQueryable.

        // Type ElementType { get; } from IQueryable.

        // IQueryProvider Provider { get; } from IQueryable.

        // IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); from IEnumerable&amp;lt;T&amp;gt;.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a wrapper of iterator getter, an expression tree representing the current query’s logic, and a query provider of IQueryProvider type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryProvider
    {
        IQueryable CreateQuery(Expression expression);

        IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression);

        object Execute(Expression expression);

        TResult Execute&amp;lt;TResult&amp;gt;(Expression expression);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has CreateQuery and Execute methods, all accepting a expression tree parameter. CreateQuery methods return an IQueryable&amp;lt;T&amp;gt; of values, and Execute methods return a single value. These methods are called inside the Queryable methods.&lt;/p&gt;
&lt;h3&gt;Queryable methods&lt;/h3&gt;
&lt;p&gt;As fore mentioned, Queryable also provides 2 kinds of query methods, which either return an IQueryable&amp;lt;T&amp;gt; of values, or return a single value. Take Where, Select, and First as example, here are their implementations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    using System.Linq.Expressions;

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;TSource&amp;gt;&amp;gt; currentMethod = 
                Where;
            MethodCallExpression whereCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(predicate));
            return source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(whereCallExpression);
        }

        public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt;, IQueryable&amp;lt;TResult&amp;gt;&amp;gt; currentMethod = 
                Select;
            MethodCallExpression selectCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(selector));
            return source.Provider.CreateQuery&amp;lt;TResult&amp;gt;(selectCallExpression);
        }

        public static TSource First&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt;, TSource&amp;gt; currentMethod = First;
            MethodCallExpression firstCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression,
                arg1: Expression.Quote(predicate));
            return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
        }

        public static TSource First&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source)
        {
            Func&amp;lt;IQueryable&amp;lt;TSource&amp;gt;, TSource&amp;gt; currentMethod = First;
            MethodCallExpression firstCallExpression = Expression.Call(
                method: currentMethod.Method,
                arg0: source.Expression);
            return source.Provider.Execute&amp;lt;TSource&amp;gt;(firstCallExpression);
        }

        // Other methods...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the query methods are in the same pattern. They just build a MethodCallExpression expression, representing the current query method is called. Then they obtain query provider from source’s Provider property. When the query method returns another IQueryable&amp;lt;T&amp;gt;, it calls query provider’s CreateQuery method. When the query method return a single value, it calls query provider’s Execute method.&lt;/p&gt;
&lt;h3&gt;Build LINQ to Entities queries and expressions&lt;/h3&gt;
&lt;p&gt;With above Where and Select query methods, a simple LINQ to Entities query can be implemented to return a IQueryable&amp;lt;T&amp;gt; of values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Translation
{
    private static readonly AdventureWorks AdventureWorks = new AdventureWorks();

    internal static void WhereAndSelect()
    {
        // IQueryable&amp;lt;string&amp;gt; products = AdventureWorks.Products
        //    .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;)).Select(product =&amp;gt; product.Name);
        IQueryable&amp;lt;Product&amp;gt; sourceQueryable = AdventureWorks.Products;
        IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;));
        IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(product =&amp;gt; product.Name); // Define query.
        selectQueryable.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once again, a static DbContext is reused in all queries here, to make code shorter. In reality, a DbContext object should always be constructed and disposed for each &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The above example queries products with Name starting with “M”, and returns the products’ Names. By deguaring the lambda expressions, and unwrapping the query methods, the above LINQ to Entities query is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectExpressions()
{
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = AdventureWorks.Products;

    // MethodCallExpression sourceMergeAsCallExpression = sourceQuery.Expression as MethodCallExpression;
    ObjectQuery&amp;lt;Product&amp;gt; objectQuery = new ObjectQuery&amp;lt;Product&amp;gt;(
        $&quot;[{nameof(AdventureWorks)}].[{nameof(AdventureWorks.Products)}]&quot;,
        (AdventureWorks as IObjectContextAdapter).ObjectContext,
        MergeOption.AppendOnly);
    MethodInfo mergeAsMethod = typeof(ObjectQuery&amp;lt;Product&amp;gt;)
        .GetTypeInfo().GetDeclaredMethods(&quot;MergeAs&quot;).Single();
    MethodCallExpression sourceMergeAsCallExpression = Expression.Call(
        instance: Expression.Constant(objectQuery),
        method: mergeAsMethod,
        arguments: Expression.Constant(MergeOption.AppendOnly, typeof(MergeOption)));
    Trace.WriteLine(sourceQueryable.Expression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)

    // Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression = product =&amp;gt; product.Name.StartsWith(&quot;M&quot;);
    ParameterExpression productParameterExpression = Expression.Parameter(typeof(Product), &quot;product&quot;);
    Func&amp;lt;string, bool&amp;gt; startsWithMethod = string.Empty.StartsWith;
    Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; predicateExpression =
        Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
            Expression.Call(
                instance: Expression.Property(productParameterExpression, nameof(Product.Name)),
                method: startsWithMethod.Method,
                arguments: Expression.Constant(&quot;M&quot;, typeof(string))),
            productParameterExpression);
    Trace.WriteLine(predicateExpression);
    // product =&amp;gt; product.Name.StartsWith(&quot;M&quot;)

    // IQueryable&amp;lt;Product&amp;gt; whereQueryable = sourceQueryable.Where(predicateExpression);
    Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;, IQueryable&amp;lt;Product&amp;gt;&amp;gt; whereMethod =
        Queryable.Where;
    MethodCallExpression whereCallExpression = Expression.Call(
        method: whereMethod.Method,
        arg0: sourceMergeAsCallExpression,
        arg1: Expression.Quote(predicateExpression));
    IQueryable&amp;lt;Product&amp;gt; whereQueryable =
        sourceQueryable.Provider.CreateQuery&amp;lt;Product&amp;gt;(whereCallExpression);
    Trace.WriteLine(object.ReferenceEquals(whereCallExpression, whereQueryable.Expression)); // True.
    Trace.WriteLine(whereQueryable.Expression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)
    //    .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;))

    // Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression = product =&amp;gt; product.Name;
    Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; selectorExpression =
        Expression.Lambda&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;(
            Expression.Property(productParameterExpression, nameof(Product.Name)),
            productParameterExpression);
    Trace.WriteLine(selectorExpression);
    // product =&amp;gt; product.Name

    // IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Select(selectorExpression);
    Func&amp;lt;IQueryable&amp;lt;Product&amp;gt;, Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;, IQueryable&amp;lt;string&amp;gt;&amp;gt; selectMethod =
        Queryable.Select;
    MethodCallExpression selectCallExpression = Expression.Call(
        method: selectMethod.Method,
        arg0: whereCallExpression,
        arg1: Expression.Quote(selectorExpression));
    IQueryable&amp;lt;string&amp;gt; selectQueryable = whereQueryable.Provider.CreateQuery&amp;lt;string&amp;gt;(selectCallExpression);
    Trace.WriteLine(object.ReferenceEquals(selectCallExpression, selectQueryable.Expression)); // True.
    Trace.WriteLine(selectQueryable.Expression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)
    //    .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;))
    //    .Select(product =&amp;gt; product.Name)

    // selectQueryable.ForEach(product =&amp;gt; Trace.WriteLine(product));
    using (IEnumerator&amp;lt;string&amp;gt; iterator = selectQueryable.GetEnumerator())
    {
        while (iterator.MoveNext()) // Execute query.
        {
            string product = iterator.Current;
            Trace.WriteLine(product);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the steps how the fluent query builds expression tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Build data source:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The first/source IQueryable&amp;lt;T&amp;gt; object is the sourceQueryable variable. Entity Framework automatically constructs a DbSet&amp;lt;Product&amp;gt; to represent the data source, which implements IQueryable&amp;lt;Product&amp;gt;, and wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A MethodCallExpression expression, which represents ObjectQuery&amp;lt;Product&amp;gt;.MergeAs method on an ObjectQuery&amp;lt;Product&amp;gt; object. By default, MergeAs is called with MergeOption.AppendOnly, which means append new entities to the entity cache, if any. Entity cache will be discussed in a later part.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider, which is a DbQueryProvider object implementing IQueryProvider&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build Where query:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A predicate expression predicateExpression is built for Where,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Where continues the query based on sourceQueryable. But Where only needs sourceQueryable’s expression sourceMergeAsCallExpression and query provider sourceQueryProvider. As fore mentioned, a MethodCallExpression expression whereCallExpression is built, which represents a call to itself with sourceMergeAsCallExpression argument and predicateExpression argument. Then sourceQueryProvider’s CreateQuery method is called with whereCallExpression argument, and a IQueryable&amp;lt;Product&amp;gt; variable whereQueryable is returned for further query.. Here whereQueryable wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The MethodCallExpression expression whereCallExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider whereQueryProvider, which is another DbQueryProvider object&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build Select query:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A selector expression selectorExpression is built for Select&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select continues the query based on whereQueryable. Again, Select only needs whereQueryable’s expression whereCallExpression and query provider whereQueryProvider. A MethodCallExpression expression selectCallExpression is built, which represents a call to itself with whereCallExpression argument and selectorExpression argument. Then whereQueryProvider’s CreateQuery method is called with selectCallExpression, and a IQueryable&amp;lt;string&amp;gt; variable selectQueryable is returned. Once again selectQueryable wraps:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The MethodCallExpression expression selectCallExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A query provider, which is yet another DbQueryProvider object&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, the last IQueryable&amp;lt;T&amp;gt; variable selectQueryable’s Expression property (referencing to selectCallExpression), is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)
|_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
|_Object = null
|_Arguments
  |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;Product&amp;gt;)
  | |_Method = Queryable.Where&amp;lt;Product&amp;gt;
  | |_Object = null
  | |_Arguments
  |   |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;Product&amp;gt;)
  |   | |_Method = ObjectQuery&amp;lt;Product&amp;gt;.MergeAs
  |   | |_Object
  |   | | |_ConstantExpression (NodeType = Constant, Type = ObjectQuery&amp;lt;Product&amp;gt;)
  |   | |  |_Value = new ObjectQuery&amp;lt;Product&amp;gt;(...)
  |   | |_Arguments
  |   |   |_ConstantExpression (NodeType = Constant, Type = MergeOption)
  |   |     |_Value = MergeOption.AppendOnly
  |   |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;)
  |     |_Operand
  |       |_Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, bool&amp;gt;)
  |         |_Parameters
  |         | |_ParameterExpression (NodeType = Parameter, Type = Product)
  |         |   |_Name = &quot;product&quot;
  |         |_Body
  |           |_MethodCallExpression (NodeType = Call, Type = bool)
  |             |_Method = string.StartsWith
  |             |_Object
  |             | |_PropertyExpression (NodeType = MemberAccess, Type = string)
  |             |   |_Expression
  |             |     |_ParameterExpression (NodeType = Parameter, Type = Product)
  |             |     | |_Name = &quot;product&quot;
  |             |     |_Member = &quot;Name&quot;
  |             |_Arguments
  |               |_ConstantExpression (NodeType = Constant, Type = string)
  |                 |_Value = &quot;M&quot;
  |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
    |_Operand
      |_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
        |_Parameters
        | |_ParameterExpression (NodeType = Parameter, Type = Product)
        |   |_Name = &quot;product&quot;
        |_Body
          |_PropertyExpression (NodeType = MemberAccess, Type = string)
            |_Expression
            | |_ParameterExpression (NodeType = Parameter, Type = Product)
            |   |_Name = &quot;product&quot;
            |_Member = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also demonstrates that lambda expression, extension methods, and LINQ query are powerful features. Such a rich abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; products = AdventureWorks.Products
    .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;)).Select(product =&amp;gt; product.Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other kind of query returning a single value, works in the same way. Take above First as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirst()
{
    // string first = AdventureWorks.Products.Select(product =&amp;gt; product.Name).First();
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
    string first = selectQueryable.First();
    Trace.WriteLine(first);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the sourceQueryable and and Select query is the same as the previous example. So this time, just unwrap the First method. The above First query is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstExpressions()
{
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = AdventureWorks.Products;
    Trace.WriteLine(sourceQueryable.Expression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)

    IQueryable&amp;lt;string&amp;gt; selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);
    Trace.WriteLine(selectQueryable.Expression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)
    //    .Select(product =&amp;gt; product.Name)

    // string first = selectQueryable.First();
    Func&amp;lt;IQueryable&amp;lt;string&amp;gt;, string&amp;gt; firstMethod = Queryable.First;
    MethodCallExpression firstCallExpression = Expression.Call(firstMethod.Method, selectQueryable.Expression);
    Trace.WriteLine(firstCallExpression);
    // value(System.Data.Entity.Core.Objects.ObjectQuery`1[Dixin.Linq.EntityFramework.Product])
    //    .MergeAs(AppendOnly)
    //    .Select(product =&amp;gt; product.Name)
    //    .First()

    string first = selectQueryable.Provider.Execute&amp;lt;string&amp;gt;(firstCallExpression); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In First query, the MethodCallExpression expression is built in the same way. The difference is, IQueryableProvider.Execute is called instead of CreateQuery, so that a single value is returned. In Entity Framework, DbQueryProvider.CreateQuery and DbQueryProvider.Execute both internally call ObjectQueryProvider.CreateQuery to get a IQueryable&amp;lt;T&amp;gt;. So above Execute call is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstQuery()
{
    IQueryable&amp;lt;Product&amp;gt; sourceQueryable = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; selectQueryable = sourceQueryable.Select(product =&amp;gt; product.Name);

    Func&amp;lt;IQueryable&amp;lt;string&amp;gt;, string&amp;gt; firstMethod = Queryable.First;
    MethodCallExpression firstCallExpression = Expression.Call(firstMethod.Method, selectQueryable.Expression);
    // IQueryable&amp;lt;string&amp;gt; firstQueryable = selectQueryable.Provider._internalQuery.ObjectQueryProvider
    //    .CreateQuery&amp;lt;string&amp;gt;(firstCallExpression);
    // Above _internalQuery, ObjectQueryProvider and CreateQuery are not public. Reflection is needed:
    Assembly entityFrmaeworkAssembly = typeof(DbContext).Assembly;
    Type dbQueryProviderType = entityFrmaeworkAssembly.GetType(
        &quot;System.Data.Entity.Internal.Linq.DbQueryProvider&quot;);
    FieldInfo internalQueryField = dbQueryProviderType.GetField(
        &quot;_internalQuery&quot;, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
    Type internalQueryType = entityFrmaeworkAssembly.GetType(&quot;System.Data.Entity.Internal.Linq.IInternalQuery&quot;);
    PropertyInfo objectQueryProviderProperty = internalQueryType.GetProperty(&quot;ObjectQueryProvider&quot;);
    Type objectQueryProviderType = entityFrmaeworkAssembly.GetType(
        &quot;System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider&quot;);
    MethodInfo createQueryMethod = objectQueryProviderType
        .GetMethod(
            &quot;CreateQuery&quot;,
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
            null,
            new Type[] { typeof(Expression) },
            null)
        .MakeGenericMethod(typeof(string));
    object internalQuery = internalQueryField.GetValue(selectQueryable.Provider);
    object objectProvider = objectQueryProviderProperty.GetValue(internalQuery);
    IQueryable&amp;lt;string&amp;gt; firstQueryable = createQueryMethod.Invoke(
        objectProvider, new object[] { firstCallExpression }) as IQueryable&amp;lt;string&amp;gt;;

    Func&amp;lt;IEnumerable&amp;lt;string&amp;gt;, string&amp;gt; firstMappingMethod = Enumerable.First;
    string first = firstMappingMethod(firstQueryable); // Execute query.
    Trace.WriteLine(first);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside First:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DbQueryProvider._internalQuery.ObjectQueryProvider.CreateQuery is called to create an IQueryable&amp;lt;T&amp;gt; variable firstQueryable, which is the same as Where and Select&lt;/li&gt;
&lt;li&gt;Queryable.First method is mapped to Enumerable.First method (Entity Framework internally maintains a map between Queryable methods and Enumerable methods)&lt;/li&gt;
&lt;li&gt;finally Enumerable.First is called with firstQueryable, and pulls a single value from firstQueryable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similarly, the last IQueryable&amp;lt;T&amp;gt; variable firstQueryable’s Expression property (referencing to firstCallExpression), is the final abstract syntactic tree, which represents the entire LINQ to Entities query logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression (NodeType = Call, Type = string)
|_Method = Queryable.First&amp;lt;string&amp;gt;
|_Object = null
|_Arguments
  |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;string&amp;gt;)
    |_Method = Queryable.Select&amp;lt;Product, string&amp;gt;
    |_Object = null
    |_Arguments
      |_MethodCallExpression (NodeType = Call, Type = IQueryable&amp;lt;Product&amp;gt;)
      | |_Method = ObjectQuery&amp;lt;Product&amp;gt;.MergeAs
      | |_Object
      | | |_ConstantExpression (NodeType = Constant, Type = ObjectQuery&amp;lt;Product&amp;gt;)
      | |  |_Value = new ObjectQuery&amp;lt;Product&amp;gt;(...)
      | |_Arguments
      |   |_ConstantExpression (NodeType = Constant, Type = MergeOption)
      |     |_Value = MergeOption.AppendOnly
      |_UnaryExpression (NodeType = Quote, Type = Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;)
       |_Operand
          |_Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;Product, string&amp;gt;)
            |_Parameters
            | |_ParameterExpression (NodeType = Parameter, Type = Product)
            |   |_Name = &quot;product&quot;
            |_Body
              |_PropertyExpression (NodeType = MemberAccess, Type = string)
                |_Expression
                | |_ParameterExpression (NodeType = Parameter, Type = Product)
                |   |_Name = &quot;product&quot;
                |_Member = &quot;Name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And again, the entire abstract syntactic tree can be built by C# code as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string first = AdventureWorks.Products.Select(product =&amp;gt; product.Name).First();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Expression tree to database command tree&lt;/h2&gt;
&lt;p&gt;In the next step, EntityFramework.dll translates .NET expression tree to database command tree.&lt;/p&gt;
&lt;h3&gt;DbExpression and DbCommandTree&lt;/h3&gt;
&lt;p&gt;The logic of C# source code can be represented by .NET expression tree, and Entity Framework has a similar design. It defines database command tree, as the abstract syntactic tree of database query. In a .NET expression tree, each node derives from System.Linq.Expressions.Expression; Here in database command tree, each node derives from System.Data.Entity.Core.Common.CommandTrees.DbExpression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common.CommandTrees
{
    using System.Data.Entity.Core.Metadata.Edm;

    public abstract class DbExpression
    {
        public virtual DbExpressionKind ExpressionKind { get; }

        public virtual TypeUsage ResultType { get; }

        // Other members.
    }

    public sealed class DbFilterExpression : DbExpression
    {
        public DbExpressionBinding Input { get; }

        public DbExpression Predicate { get; }

        // Other members.
    }

    public sealed class DbProjectExpression : DbExpression
    {
        public DbExpressionBinding Input { get; }

        public DbExpression Projection { get; }

        // Other members.
    }

    public sealed class DbLimitExpression : DbExpression
    {
        public DbExpression Argument { get; }

        public DbExpression Limit { get; }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here DbExpression.ExpressionKind is similar to Expression.NodeType, and DbExpression.ResultType is similar to Expression.Type. Here are all the DbExpressions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DbExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbApplyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbArithmeticExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbBinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbAndExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbComparisonExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbExceptExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIntersectExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbOrExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbUnionAllExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCaseExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbConstantExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCrossJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbFilterExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbFunctionExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbGroupByExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbInExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbJoinExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLambdaExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLikeExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbLimitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNewInstanceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNullExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbParameterReferenceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbProjectExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbPropertyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbQuantifierExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRelationshipNavigationExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbScanExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbSkipExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbSortExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbUnaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbCastExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbDerefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbDistinctExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbElementExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbEntityRefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsEmptyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsNullExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbIsOfExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbNotExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbOfTypeExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRefExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbTreatExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbRefKeyExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DbVariableReferenceExpression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When representing a complete database query, command tree’s top node is a DbQueryCommandTree object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common.CommandTrees
{
    public abstract class DbCommandTree
    {
        public IEnumerable&amp;lt;KeyValuePair&amp;lt;string, TypeUsage&amp;gt;&amp;gt; Parameters { get; }
    }
    
    public sealed class DbQueryCommandTree : DbCommandTree
    {
        public DbExpression Query { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbQueryCommandTree’s Parameters property contains the parameters for the database query, and Query property is the top node of the DbExpression tree. They are similar to LambdaExpression’s Parameters and Body properties.&lt;/p&gt;
&lt;p&gt;Similar to Expression class, in Entity Framework System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder class provides factory methods to instantiate all kinds of DbExpressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder
{
    using System.Data.Entity.Core.Metadata.Edm;

    public static class DbExpressionBuilder
    {
        public static DbFilterExpression Filter(this DbExpressionBinding input, DbExpression predicate);

        public static DbProjectExpression Project(this DbExpressionBinding input, DbExpression projection);

        public static DbLimitExpression Limit(this DbExpression argument, DbExpression count);

        public static DbScanExpression Scan(this EntitySetBase targetSet);

        public static DbPropertyExpression Property(this DbExpression instance, string propertyName);

        public static DbVariableReferenceExpression Variable(this TypeUsage type, string name);

        public static DbConstantExpression Constant(object value);

        // Other methods...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Convert Expression to DbExpression&lt;/h3&gt;
&lt;p&gt;Entity Framework calls ExpressionConverter and PlanCompiler to convert expression tree to database command tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static DbQueryCommandTree Convert(this IObjectContextAdapter context, Expression expression)
    {
        context.NotNull(nameof(context));

        ObjectContext objectContext = context.ObjectContext;

        // DbExpression dbExpression = new ExpressionConverter(
        //    Funcletizer.CreateQueryFuncletizer(objectContext), expression).Convert();
        // DbQueryCommandTree commandTree = objectContext.MetadataWorkspace.CreateQueryCommandTree(dbExpression);
        // List&amp;lt;ProviderCommandInfo&amp;gt; providerCommands;
        // PlanCompiler.Compile(
        //    commandTree, out providerCommands, out columnMap, out columnCount, out entitySets);
        // return providerCommands.Single().CommandTree as DbQueryCommandTree;
        // Above ExpressionConverter, Funcletizer and PlanCompiler are not public. Reflection is needed:
        Assembly entityFrmaeworkAssembly = typeof(DbContext).Assembly;
        Type funcletizerType = entityFrmaeworkAssembly.GetType(
            &quot;System.Data.Entity.Core.Objects.ELinq.Funcletizer&quot;);
        MethodInfo createQueryFuncletizerMethod = funcletizerType.GetMethod(
            &quot;CreateQueryFuncletizer&quot;, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod);
        Type expressionConverterType = entityFrmaeworkAssembly.GetType(
            &quot;System.Data.Entity.Core.Objects.ELinq.ExpressionConverter&quot;);
        ConstructorInfo expressionConverterConstructor = expressionConverterType.GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance, 
            null, 
            new Type[] { funcletizerType, typeof(Expression) }, 
            null);
        MethodInfo convertMethod = expressionConverterType.GetMethod(
            &quot;Convert&quot;, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
        object funcletizer = createQueryFuncletizerMethod.Invoke(null, new object[] { objectContext });
        object expressionConverter = expressionConverterConstructor.Invoke(
            new object[] { funcletizer, expression });
        DbExpression dbExpression = convertMethod.Invoke(expressionConverter, new object[0]) as DbExpression;
        DbQueryCommandTree commandTree = objectContext.MetadataWorkspace.CreateQueryCommandTree(dbExpression);
        Type planCompilerType = entityFrmaeworkAssembly.GetType(
            &quot;System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler&quot;);
        MethodInfo compileMethod = planCompilerType.GetMethod(
            &quot;Compile&quot;, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod);
        object[] arguments = new object[] { commandTree, null, null, null, null };
        compileMethod.Invoke(null, arguments);
        Type providerCommandInfoType = entityFrmaeworkAssembly.GetType(
            &quot;System.Data.Entity.Core.Query.PlanCompiler.ProviderCommandInfo&quot;);
        PropertyInfo commandTreeProperty = providerCommandInfoType.GetProperty(
            &quot;CommandTree&quot;, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
        object providerCommand = (arguments[1] as IEnumerable&amp;lt;object&amp;gt;).Single();
        return commandTreeProperty.GetValue(providerCommand) as DbQueryCommandTree;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ExpressionConverter translates expression tree and outputs the command tree. PlanCompiler processes the command tree for object-relational mapping, like replacing the scan of AdventureWorks.Product to the scan of [Production].[Product] table, etc. So above Where and Select query’s expression tree can be converted as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectExpressionsToDbExpressions()
{
    Expression expression = AdventureWorks.Products
        .Where(product =&amp;gt; product.Name.StartsWith(&quot;M&quot;)).Select(product =&amp;gt; product.Name).Expression;
    DbQueryCommandTree commandTree = AdventureWorks.Convert(expression);
    Trace.WriteLine(commandTree);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The converted command tree is equivalent to the command tree built below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree WhereAndSelectDbExpressions()
{
    MetadataWorkspace metadata = (AdventureWorks as IObjectContextAdapter).ObjectContext.MetadataWorkspace;
    TypeUsage stringTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetPrimitiveTypes(DataSpace.CSpace)
        .Single(type =&amp;gt; type.ClrEquivalentType == typeof(string)));
    TypeUsage nameRowTypeUsage = TypeUsage.CreateDefaultTypeUsage(RowType.Create(
        Enumerable.Repeat(EdmProperty.Create(nameof(Product.Name), stringTypeUsage), 1),
        Enumerable.Empty&amp;lt;MetadataProperty&amp;gt;()));
    TypeUsage productTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetType(nameof(Product), &quot;CodeFirstDatabaseSchema&quot;, DataSpace.SSpace));
    EntitySet productEntitySet = metadata
        .GetEntityContainer(&quot;CodeFirstDatabase&quot;, DataSpace.SSpace)
        .GetEntitySetByName(nameof(Product), false);

    DbProjectExpression query = DbExpressionBuilder.Project(
        DbExpressionBuilder.BindAs(
            DbExpressionBuilder.Filter(
                DbExpressionBuilder.BindAs(
                    DbExpressionBuilder.Scan(productEntitySet), &quot;Extent1&quot;),
                DbExpressionBuilder.Like(
                    DbExpressionBuilder.Property(
                        DbExpressionBuilder.Variable(productTypeUsage, &quot;Extent1&quot;), nameof(Product.Name)),
                    DbExpressionBuilder.Constant(&quot;M%&quot;))),
            &quot;Filter1&quot;),
        DbExpressionBuilder.New(
            nameRowTypeUsage,
            DbExpressionBuilder.Property(
                DbExpressionBuilder.Variable(productTypeUsage, &quot;Filter1&quot;), nameof(Product.Name))));
    DbQueryCommandTree commandTree = new DbQueryCommandTree(metadata, DataSpace.SSpace, query);
    Trace.WriteLine(commandTree);
    return commandTree;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query
  |_DbProjectExpression (ExpressionKind = Project, ResultType = Collection(Row[&apos;Name&apos; = Edm.String]))
    |_Input
    | |_DbExpressionBinding (VariableType = Product)
    |   |_VariableName = &apos;Filter1&apos;
    |   |_Expression
    |     |_DbFilterExpression (ExpressionKind = Filter, ResultType = Product)
    |       |_Input
    |       | |_DbExpressionBinding (VariableType = Product)
    |       |   |_VariableName = &apos;Extent1&apos;
    |       |   |_Expression
    |       |     |_DbScanExpression (ExpressionKind = Scan, ResultType = Collection(Product))
    |       |       |_Target = Products
    |       |_Predicate
    |         |_DbLikeExpression (ExpressionKind = Like, ResultType = Edm.Boolean)
    |           |_Argument
    |           | |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
    |           |   |_Property = Product.Name
    |           |   |_Instance
    |           |     |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
    |           |       |_VariableName = &apos;Extent1&apos;
    |           |_Pattern
    |             |_DbConstantExpression (ExpressionKind = Constant, ResultType = Edm.String)
    |               |_Value = &apos;M%&apos;
    |_Projection
      |_DbNewInstanceExpression (ExpressionKind = NewInstance, ResultType = Row[&apos;Name&apos; = Edm.String])
        |_Arguments
          |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
            |_Property = Product.Name
            |_Instance
              |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
                |_VariableName = &apos;Filter1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, the other Select and First query’s expression tree is converted to the equivalent command tree built-below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree SelectAndFirstDbExpressions()
{
    MetadataWorkspace metadata = (AdventureWorks as IObjectContextAdapter).ObjectContext.MetadataWorkspace;
    TypeUsage stringTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetPrimitiveTypes(DataSpace.CSpace)
        .Single(type =&amp;gt; type.ClrEquivalentType == typeof(string)));
    TypeUsage nameRowTypeUsage = TypeUsage.CreateDefaultTypeUsage(RowType.Create(
        Enumerable.Repeat(EdmProperty.Create(nameof(Product.Name), stringTypeUsage), 1),
        Enumerable.Empty&amp;lt;MetadataProperty&amp;gt;()));
    TypeUsage productTypeUsage = TypeUsage.CreateDefaultTypeUsage(metadata
        .GetType(nameof(Product), &quot;CodeFirstDatabaseSchema&quot;, DataSpace.SSpace));
    EntitySet productEntitySet = metadata
        .GetEntityContainer(&quot;CodeFirstDatabase&quot;, DataSpace.SSpace)
        .GetEntitySetByName(nameof(Product), false);

    DbProjectExpression query = DbExpressionBuilder.Project(
        DbExpressionBuilder.BindAs(
            DbExpressionBuilder.Limit(
                DbExpressionBuilder.Scan(productEntitySet),
                DbExpressionBuilder.Constant(1)),
            &quot;Limit1&quot;),
        DbExpressionBuilder.New(
            nameRowTypeUsage,
            DbExpressionBuilder.Property(
                DbExpressionBuilder.Variable(productTypeUsage, &quot;Limit1&quot;), nameof(Product.Name))));
    DbQueryCommandTree commandTree = new DbQueryCommandTree(metadata, DataSpace.SSpace, query);
    Trace.WriteLine(commandTree);
    return commandTree;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this abstract syntactic tree can be visualized as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query
  |_DbProjectExpression (ExpressionKind = Project, ResultType = Collection(Row[&apos;Name&apos; = Edm.String]))
    |_Input
    | |_DbExpressionBinding (VariableType = Product)
    |   |_VariableName = &apos;Limit1&apos;
    |   |_Expression
    |     |_DbLimitExpression (ExpressionKind = Limit, ResultType = Collection(Product))
    |       |_Argument
    |       | |_DbScanExpression (ExpressionKind = Scan, ResultType = Collection(Product))
    |       |   |_Target = Products
    |       |_Limit
    |         |_DbConstantExpression (ExpressionKind = Constant, ResultType = Edm.Int32)
    |           |_Value = 1
    |_Projection
      |_DbNewInstanceExpression (ExpressionKind = NewInstance, ResultType = Row[&apos;Name&apos; = Edm.String])
        |_Arguments
          |_DbPropertyExpression (ExpressionKind = Property, ResultType = Edm.String)
            |_Property = Product.Name
            |_Instance
              |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Product)
                |_VariableName = &apos;Limit1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Query methods translation&lt;/h3&gt;
&lt;p&gt;The above ExpressionConverter class is a huge class. It has tons of nested translator classes for all supported expression tree nodes. For example, ObjectQueryCallTranslator’s derived classes translates ObjectQuery&amp;lt;T&amp;gt; query method calls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ObjectQueryCallTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ObjectQueryMergeAsTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SequenceMethodTranslator class’ derived classes translates the Queryable method calls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SequenceMethodTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OneLambdaTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WhereTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SelectTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FirstTranslatorBase&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FirstTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These translators cover all supported Queryable query methods (see previous part for the list). During the conversion, each node’s NodeType is checked. If its NodeType is MethodCall, then this node is a MethodCallExpression node. And if current MethodCallExpression node’s Method property a Queryable.Where method, then the conversion is dispatched to WhereTranslator, which can translate MethodCallExpression node representing Queryable.Where to FilterDbExpression node. Similarly, SelectTranslator can translate MethodCallExpression node representing Queryable.Select to ProjectDbExpression node, FirstTranslator can translate MethodCallExpression node representing Queryable.First to LimitDbExpression node, etc.&lt;/p&gt;
&lt;h3&gt;.NET APIs translation&lt;/h3&gt;
&lt;p&gt;The above Where query’s predicate has a string.StartsWith logic. Entity Framework has a StartsWithTranslator to translate MethodCallExpression node representing string.StartsWith to a DbLikeExpression. node. There are also many other translators for many .NET methods can properties. It is important to know whether a .NET API can be used for LINQ to Entities query, so here is the list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CallTranslator&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HasFlagTranslator
&lt;ul&gt;
&lt;li&gt;Enum: HasFlag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CanonicalFunctionDefaultTranslator
&lt;ul&gt;
&lt;li&gt;Math: Ceiling, Floor, Round, Abs&lt;/li&gt;
&lt;li&gt;decimal: Floor, Ceiling, Round&lt;/li&gt;
&lt;li&gt;string: Replace, ToLower, Trim&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MathTruncateTranslator
&lt;ul&gt;
&lt;li&gt;Math: Truncate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MathPowerTranslator
&lt;ul&gt;
&lt;li&gt;Math: Pow&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GuidNewGuidTranslator
&lt;ul&gt;
&lt;li&gt;Guid: NewGuid&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StringContainsTranslator
&lt;ul&gt;
&lt;li&gt;string: Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IndexOfTranslator
&lt;ul&gt;
&lt;li&gt;string: IndexOf&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StartsWithTranslator
&lt;ul&gt;
&lt;li&gt;string: StartsWith&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EndsWithTranslator:
&lt;ul&gt;
&lt;li&gt;string: EndsWith&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SubstringTranslator
&lt;ul&gt;
&lt;li&gt;string: Substring&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RemoveTranslator
&lt;ul&gt;
&lt;li&gt;string: Remove&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;InsertTranslator
&lt;ul&gt;
&lt;li&gt;string: Insert&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IsNullOrEmptyTranslator
&lt;ul&gt;
&lt;li&gt;string: IsNullOrEmpty&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StringConcatTranslator
&lt;ul&gt;
&lt;li&gt;string: Concat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ToStringTranslator
&lt;ul&gt;
&lt;li&gt;string, byte, sbyte, short, int, long, double, float, Guid, DateTime, DateTimeOffset, TimeSpan, decimal, bool, object: ToString&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TrimTranslator
&lt;ul&gt;
&lt;li&gt;string: Trim&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TrimStartTranslator
&lt;ul&gt;
&lt;li&gt;string: TrimStart&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TrimEndTranslator
&lt;ul&gt;
&lt;li&gt;string: TrimEnd&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;VBCanonicalFunctionDefaultTranslator
&lt;ul&gt;
&lt;li&gt;Microsoft.VisualBasic.Strings: Trim, LTrim, RTrim, Left, Right&lt;/li&gt;
&lt;li&gt;Microsoft.VisualBasic.DateAndTime: Year, Month, Day, Hour, Minute, Second&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;VBCanonicalFunctionRenameTranslator
&lt;ul&gt;
&lt;li&gt;Microsoft.VisualBasic.Strings: Len, Mid, UCase, LCase&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;VBDatePartTranslator
&lt;ul&gt;
&lt;li&gt;Microsoft.VisualBasic.DateAndTime, Microsoft.VisualBasic.DateInterval, Microsoft.VisualBasic.FirstDayOfWeek, Microsoft.VisualBasic.FirstWeekOfYear: DatePart&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SpatialMethodCallTranslator
&lt;ul&gt;
&lt;li&gt;DbGeography: FromText, PointFromText, LineFromText, PolygonFromText, MultiPointFromText, MultiLineFromText, MultiPolygonFromText, GeographyCollectionFromText, FromBinary, PointFromBinary, LineFromBinary, PolygonFromBinary, MultiPointFromBinary, MultiLineFromBinary, MultiPolygonFromBinary, GeographyCollectionFromBinary, FromGm, AsBinary, AsGml, AsText, SpatialEquals, Disjoint, Intersects, Buffer, Distance, Intersection, Union, Difference, SymmetricDifference, ElementAt, PointAt&lt;/li&gt;
&lt;li&gt;DbGeometry: FromText, PointFromText, LineFromText, PolygonFromText, MultiPointFromText, MultiLineFromText, MultiPolygonFromText, GeometryCollectionFromText, FromBinary, PointFromBinary, LineFromBinary, PolygonFromBinary, MultiPointFromBinary, MultiLineFromBinary, MultiPolygonFromBinary, GeometryCollectionFromBinary, FromGml, AsBinary, AsGml, AsText, SpatialEquals, Disjoint, Intersects, Touches, Crosses, Within, Contains, Overlaps, Relate, Buffer, Distance, Intersection, Union, Difference, SymmetricDifference, ElementAt, PointAt, InteriorRingAt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LinqExpressionNormalizer, MethodCallTranslator&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enumerable: Contains&lt;/li&gt;
&lt;li&gt;List&amp;lt;T&amp;gt;: Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PropertyTranslator&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DefaultCanonicalFunctionPropertyTranslator
&lt;ul&gt;
&lt;li&gt;string: Length&lt;/li&gt;
&lt;li&gt;DateTime: Year, Month, Day, Hour, Minute, Second, Millisecond&lt;/li&gt;
&lt;li&gt;DateTimeOffset: Year, Month, Day, Hour, Minute, Second, Millisecond&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RenameCanonicalFunctionPropertyTranslator
&lt;ul&gt;
&lt;li&gt;DateTime: Now, UtcNow&lt;/li&gt;
&lt;li&gt;DateTimeOffset: Now&lt;/li&gt;
&lt;li&gt;TimeSpan: Hours, Minutes, Seconds, Milliseconds&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;VBDateAndTimeNowTranslator
&lt;ul&gt;
&lt;li&gt;Microsoft.VisualBasic.DateAndTime: Now&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EntityCollectionCountTranslator
&lt;ul&gt;
&lt;li&gt;EntityCollection&amp;lt;TEntity&amp;gt;: Count&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NullableHasValueTranslator
&lt;ul&gt;
&lt;li&gt;Nullable&amp;lt;T&amp;gt;: HasValue&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NullableValueTranslator
&lt;ul&gt;
&lt;li&gt;Nullable&amp;lt;T&amp;gt;: Value&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GenericICollectionTranslator
&lt;ul&gt;
&lt;li&gt;ICollection&amp;lt;T&amp;gt;: Count&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SpatialPropertyTranslator
&lt;ul&gt;
&lt;li&gt;DbGeography: CoordinateSystemId, SpatialTypeName, Dimension, IsEmpty, ElementCount, Latitude, Longitude, Elevation, Measure, Length, StartPoint, EndPoint, IsClosed, PointCount, Area&lt;/li&gt;
&lt;li&gt;DbGeometry: CoordinateSystemId, SpatialTypeName, Dimension, Envelope, IsEmpty, IsSimple, Boundary, IsValid, ConvexHull, ElementCount, XCoordinate, YCoordinate, Elevation, Measure, Length, StartPoint, EndPoint, IsClosed, IsRing, PointCount, Area, Centroid, PointOnSurface, ExteriorRing, InteriorRingCount&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EqualsTranslator&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Primitive, enum and entity types: static Equals method with more then 1 parameters&lt;/li&gt;
&lt;li&gt;Primitive, enum and entity types: instance Equals methodwith more than 0 parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LessThanTranslator, LessThanOrEqualsTranslator, GreaterThanTranslator, GreaterThanOrEqualsTranslator&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Primitive and enum type: static Compare method with more than 1 parameters and returning int&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Primitive and enum type: instance CompareTo method with more than 0 parameters and returning int&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, when a LINQ to Entities query has the string.IsNullOrEmpty logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree StringIsNullOrEmptyDbExpressions()
{
    IQueryable&amp;lt;string&amp;gt; products = AdventureWorks.Products
        .Select(product =&amp;gt; product.Name)
        .Where(name =&amp;gt; string.IsNullOrEmpty(name));
    return AdventureWorks.Convert(products.Expression);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The predicate’s body is a simple MethodCallExpression expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MethodCallExpression (NodeType = Call, Type = bool)
|_Method = string.IsNullOrEmpty
|_Object = null
|_Arguments
  |_ParameterExpression (NodeType = Parameter, Type = string)
    |_Name = &quot;name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its translation is dispatched to IsNullOrEmptyTranslator, and it is translate to a DbComparisonExpression, representing a logic that calling database’s Edm.Length function with string variable, and comparing if the result equals to 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbComparisonExpression (ExpressionKind = Equals, ResultType = Edm.Boolean)
|_Left
| |_DbFunctionExpression (ExpressionKind = Function, ResultType = Edm.Int32)
|   |_Function = Edm.Length
|    |_Arguments
|     |_DbVariableReferenceExpression (ExpressionKind = VariableReference, ResultType = Edm.String)
|       |_VariableName = &apos;LQ2&apos;
|_Right
    |_DbConstantExpression (ExpressionKind = Constant, ResultType = Edm.Int32)
    |_Value = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Remote method call vs. local method call&lt;/h3&gt;
&lt;p&gt;Apparently Entity Framework cannot translate arbitrary .NET method to DbExpression. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static bool FilterName(string name) =&amp;gt; string.IsNullOrEmpty(name);

internal static void MethodPredicate()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IQueryable&amp;lt;string&amp;gt; products = source
        .Select(product =&amp;gt; product.Name)
        .Where(name =&amp;gt; FilterName(name)); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
    // NotSupportedException: LINQ to Entities does not recognize the method &apos;Boolean FilterName(Dixin.Linq.EntityFramework.Product)&apos; method, and this method cannot be translated into a store expression.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time string.IsNullOrEmpty is wrapped in a FilterName method. As a result, Entity Framework cannot understand how to convert FilterName call, and throws NotSupportedException. If an API cannot be translated to remote database query it can be called locally with LINQ to Objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void LocalMethodCall()
{
    IQueryable&amp;lt;Product&amp;gt; source = AdventureWorks.Products;
    IEnumerable&amp;lt;string&amp;gt; products = source
        .Select(product =&amp;gt; product.Name) // LINQ to Entities.
        .AsEnumerable() // LINQ to Objects.
        .Where(name =&amp;gt; FilterName(name)); // Define query.
    products.ForEach(product =&amp;gt; Trace.WriteLine(product)); // Execute query.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Database functions translation&lt;/h3&gt;
&lt;p&gt;Some .NET APIs have database translations, but not all database APIs has .NET built-in APIs to translated from, for example, there is no mapping .NET API for SQL database DATEDIFF function. Entity Framework provides mapping methods to address these scenarios. As fore mentioned, Entity Framework implements a provider model, and these mapping methods are provides in 2 levels too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In EntityFramework.dll, System.Data.Entity.DbFunctions class provides mapping methods supported by all database provides, like DbFunctions.Reverse to reverse a string, DbFunction.AsUnicode to ensure a string is treated as Unicode, etc. These common database functions are also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb738626.aspx&quot;&gt;canonical functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In EntityFramework.SqlServer.dll, System.Data.Entity.SqlServer.SqlFunctions class provides mapping methods from SQL database functions, like SqlFunctions.Checksum method for CHECKSUM function, SqlFunctions.CurrentUser for CURRENT_USER function, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following LINQ to Entities query calculates the number of days between current date/time and photo’s last modified date/time. It includes a MethodCallExpression representing a DbFunctions.DiffDays method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree DbFunctionDbExpressions()
{
    var photos = AdventureWorks.ProductPhotos.Select(photo =&amp;gt; new
    {
        FileName = photo.LargePhotoFileName,
        UnmodifiedDays = DbFunctions.DiffDays(photo.ModifiedDate, DateTime.Now)
    });
    return AdventureWorks.Convert(photos.Expression);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This MethodCallExpression node of DbFunctions.DiffDays is translated to a DbFunctionExpression node of canonical function Edm.DiffDays.&lt;/p&gt;
&lt;p&gt;The following LINQ to Entities query filters the product’s Names with a pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static DbQueryCommandTree SqlFunctionDbExpressions()
{
    IQueryable&amp;lt;string&amp;gt; products = AdventureWorks.Products
        .Select(product =&amp;gt; product.Name)
        .Where(name =&amp;gt; SqlFunctions.PatIndex(name, &quot;%o%a%&quot;) &amp;gt; 0);
    return AdventureWorks.Convert(products.Expression);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the MethodCallExpression node of SqlFunctions.PatIndex is translated to a DbFunctionExpression node of SQL database function SqlServer.PATINDEX.&lt;/p&gt;
&lt;h2&gt;Database command tree to SQL&lt;/h2&gt;
&lt;h3&gt;DbExpressionVisitor&amp;lt;TResultType&amp;gt; and SqlGenerator&lt;/h3&gt;
&lt;p&gt;.NET provides System.Linq.Expressions.ExpressionVisitor class to traverse expression tree. Similarly, EntityFramework.dll provides an System.Data.Entity.Core.Common.CommandTrees.DbExpressionVisitor&amp;lt;TResultType&amp;gt; to traverse database command tree nodes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common.CommandTrees
{
    public abstract class DbExpressionVisitor&amp;lt;TResultType&amp;gt;
    {
        public abstract TResultType Visit(DbFilterExpression expression);

        public abstract TResultType Visit(DbProjectExpression expression);

        public abstract TResultType Visit(DbLimitExpression expression);

        public abstract TResultType Visit(DbScanExpression expression);

        public abstract TResultType Visit(DbPropertyExpression expression);

        public abstract TResultType Visit(DbVariableReferenceExpression expression);

        public abstract TResultType Visit(DbConstantExpression expression);

        // Other methods.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This abstract class is implemented by the SqlGenerator class in EntityFramework.SqlServer.dll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer.SqlGen
{
    internal class SqlGenerator : DbExpressionVisitor&amp;lt;ISqlFragment&amp;gt;
    {
        internal string GenerateSql(DbQueryCommandTree tree, out HashSet&amp;lt;string&amp;gt; paramsToForceNonUnicode);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like above ExpressionConverter class, SqlGenerator is also a huge class. It traverses and processes all types of nodes in command tree.&lt;/p&gt;
&lt;h3&gt;Database command tree to SQL&lt;/h3&gt;
&lt;p&gt;The following method can take database command tree and generate SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static DbCommand Generate(this IObjectContextAdapter context, DbQueryCommandTree commandTree)
    {
        context.NotNull(nameof(context));

        MetadataWorkspace metadataWorkspace = context.ObjectContext.MetadataWorkspace;
        StoreItemCollection itemCollection = (StoreItemCollection)metadataWorkspace
            .GetItemCollection(DataSpace.SSpace);
        DbCommandDefinition commandDefinition = SqlProviderServices.Instance
            .CreateCommandDefinition(itemCollection.ProviderManifest, commandTree);
        return commandDefinition.CreateCommand();
        // SqlVersion sqlVersion = (itemCollection.ProviderManifest as SqlProviderManifest).SqlVersion;
        // SqlGenerator sqlGenerator = new SqlGenerator(sqlVersion);
        // HashSet&amp;lt;string&amp;gt; paramsToForceNonUnicode;
        // string sql = sqlGenerator.GenerateSql(commandTree, out paramsToForceNonUnicode)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside the last method call of CreateCommand, a SqlGenerator object is constructed with SQL database’s version (detected with SqlConnection.ServerVersion), and its GenerateSql method is called to generate SQL query text, then the text and parameters (DbQueryCommandTree.Parameters) are wrapped into a DbCommand object, which is returned to caller.&lt;/p&gt;
&lt;p&gt;The above WhereAndSelectDbExpressions methods build command tree from scratch. Take it as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void WhereAndSelectDbExpressionsToSql()
{
    DbQueryCommandTree commandTree = WhereAndSelectDbExpressions();
    string sql = AdventureWorks.Generate(commandTree).CommandText;
    Trace.WriteLine(sql);
    // SELECT 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE [Extent1].[Name] LIKE N&apos;M%&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SqlGenerator traverses the command tree nodes, a specific Visit overloads is called for each supported node type. It generates SELECT clause from DbProjectionExpression node, FROM clause from DbScanExpression node, WHERE clause from DbFilterExpression node, LIKE operator from DbLikeExpression, etc.&lt;/p&gt;
&lt;p&gt;In the other example, SelectAndFirstDbExpressions also builds command tree, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SelectAndFirstDbExpressionsToSql()
{
    DbQueryCommandTree commandTree = SelectAndFirstDbExpressions();
    string sql = AdventureWorks.Generate(commandTree).CommandText;
    Trace.WriteLine(sql);
    // SELECT TOP (1) 
    //    [c].[Name] AS [Name]
    //    FROM [Production].[Product] AS [c]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SqlGenerator generates TOP expression from DbLimitExpression node. Here SQL database’s version matters. Inside SqlGenerator.Visit overload for DbLimitExpression, TOP 1 is generated for SQL Server 2000 (8.0), and TOP (1) is generated for later version.&lt;/p&gt;
&lt;p&gt;Other command trees above can be used to generate SQL in the same way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StringIsNullOrEmptySql()
{
    string sql = AdventureWorks.Generate(StringIsNullOrEmptyDbExpressions()).CommandText;
    Trace.WriteLine(sql);
    // SELECT 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE (LEN([Extent1].[Name])) = 0
}

internal static void DbFunctionSql()
{
    string sql = AdventureWorks.Generate(DbFunctionDbExpressions()).CommandText;
    Trace.WriteLine(sql);
    // SELECT 
    //    1 AS [C1], 
    //    [Extent1].[LargePhotoFileName] AS [LargePhotoFileName], 
    //    DATEDIFF (day, [Extent1].[ModifiedDate], SysDateTime()) AS [C2]
    //    FROM [Production].[ProductPhoto] AS [Extent1]
}

internal static void SqlFunctionSql()
{
    string sql = AdventureWorks.Generate(SqlFunctionDbExpressions()).CommandText;
    Trace.WriteLine(sql);
    // SELECT 
    //    [Extent1].[Name] AS [Name]
    //    FROM [Production].[Product] AS [Extent1]
    //    WHERE ( CAST(PATINDEX([Extent1].[Name], N&apos;%o%a%&apos;) AS int)) &amp;gt; 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Log the translation&lt;/h2&gt;
&lt;p&gt;As demonstrated above, it is easy to log .NET expression tree by calling ToString(). The final SQL can be also logged in several ways, which is discussed in a previous part. However, logging the intermediate database command tree is not very straightforward.&lt;/p&gt;
&lt;h3&gt;DbProviderServices and SqlProviderServices&lt;/h3&gt;
&lt;p&gt;In EntityFramework.dll, the provider model’s contract is defined with System.Data.Entity.Core.Common.DbProviderServices class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Core.Common
{
    public abstract class DbProviderServices : IDbDependencyResolver
    {
        protected abstract DbCommandDefinition CreateDbCommandDefinition(
            DbProviderManifest providerManifest, DbCommandTree commandTree);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in EntityFramework.SqlServer.dll, System.Data.Entity.SqlServer.SqlProviderServices class derives from the above abstract class, and represents the SQL database provider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer
{
    public sealed class SqlProviderServices : DbProviderServices
    {
        protected override DbCommandDefinition CreateDbCommandDefinition(
            DbProviderManifest providerManifest, DbCommandTree commandTree);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After Entity Framework translated expression tree to database command tree, it calls the database provider’s CreateDbCommandDefinition method for further SQL generation. So this method is where database command tree can be logged.&lt;/p&gt;
&lt;h3&gt;Log database command tree&lt;/h3&gt;
&lt;p&gt;It could be easy to define a derived class of SqlProviderServices, and override the CreateDbCommandDefinition method. Unfortunately, SqlProviderServices is a sealed class. So a proxy class can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class LogProviderServices : DbProviderServices
{
    private static readonly SqlProviderServices Sql = SqlProviderServices.Instance;

    private static object RedirectCall(
        Type[] argumentTypes, object[] arguments, [CallerMemberName] string methodName = null)
        =&amp;gt; typeof(SqlProviderServices)
            .GetMethod(
                methodName,
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                null,
                argumentTypes,
                null)
            .Invoke(Sql, arguments);

    private static object RedirectCall&amp;lt;T&amp;gt;(T arg, [CallerMemberName] string methodName = null)
        =&amp;gt; RedirectCall(new Type[] { typeof(T) }, new object[] { arg }, methodName);

    private static object RedirectCall&amp;lt;T1, T2&amp;gt;(T1 arg1, T2 arg2, [CallerMemberName] string methodName = null)
        =&amp;gt; RedirectCall(new Type[] { typeof(T1), typeof(T2) }, new object[] { arg1, arg2 }, methodName);

    private static object RedirectCall&amp;lt;T1, T2, T3&amp;gt;(
        T1 arg1, T2 arg2, T3 arg3, [CallerMemberName] string methodName = null) =&amp;gt; RedirectCall(
            new Type[] { typeof(T1), typeof(T2), typeof(T3) }, new object[] { arg1, arg2, arg3 }, methodName);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above RedirectCall methods redirects method calls to the SqlProviderServices singleton object, represented by SqlProviderServices.Instance. Now in CreateDbCommandDefinition, just log the DbCommandTree parameter, and redirect the call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;protected override DbCommandDefinition CreateDbCommandDefinition(
    DbProviderManifest providerManifest, DbCommandTree commandTree)
{
    Trace.WriteLine(commandTree);
    return (DbCommandDefinition)RedirectCall(providerManifest, commandTree);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the other methods, just redirect them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public override void RegisterInfoMessageHandler(DbConnection connection, Action&amp;lt;string&amp;gt; handler)
        =&amp;gt; Sql.RegisterInfoMessageHandler(connection, handler);

protected override DbCommand CloneDbCommand(DbCommand fromDbCommand)
    =&amp;gt; (DbCommand)RedirectCall(fromDbCommand);

protected override void SetDbParameterValue(DbParameter parameter, TypeUsage parameterType, object value)
    =&amp;gt; RedirectCall(parameter, parameterType, value);

protected override string GetDbProviderManifestToken(DbConnection connection)
    =&amp;gt; (string)RedirectCall(connection);

protected override DbProviderManifest GetDbProviderManifest(string manifestToken)
    =&amp;gt; (DbProviderManifest)RedirectCall(manifestToken);

protected override DbSpatialDataReader GetDbSpatialDataReader(DbDataReader fromReader, string versionHint)
    =&amp;gt; (DbSpatialDataReader)RedirectCall&amp;lt;DbDataReader, string&amp;gt;(fromReader, versionHint);

protected override DbSpatialServices DbGetSpatialServices(string versionHint)
    =&amp;gt; (DbSpatialServices)RedirectCall(versionHint);

protected override string DbCreateDatabaseScript(
    string providerManifestToken, StoreItemCollection storeItemCollection)
    =&amp;gt; (string)RedirectCall(providerManifestToken, storeItemCollection);

protected override void DbCreateDatabase(
    DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
    =&amp;gt; RedirectCall(connection, commandTimeout, storeItemCollection);

protected override bool DbDatabaseExists(
    DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
    =&amp;gt; (bool)RedirectCall(connection, commandTimeout, storeItemCollection);

protected override bool DbDatabaseExists(
    DbConnection connection, int? commandTimeout, Lazy&amp;lt;StoreItemCollection&amp;gt; storeItemCollection)
    =&amp;gt; (bool)RedirectCall(connection, commandTimeout, storeItemCollection);

protected override void DbDeleteDatabase(
    DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
    =&amp;gt; RedirectCall(connection, commandTimeout, storeItemCollection);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final step is to register this new database provider with Entity Framework:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class LogConfiguration : DbConfiguration
{
    public LogConfiguration()
    {
        this.SetProviderServices(SqlProviderServices.ProviderInvariantName, new LogProviderServices());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From now on, all LINQ to Entities queries’ database command tree will be logged. For example, executing above Where and Select query logs the following database command tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query : Collection{Record[&apos;Name&apos;=Edm.String]}
  |_Project
    |_Input : &apos;Filter1&apos;
    | |_Filter
    |   |_Input : &apos;Extent1&apos;
    |   | |_Scan : CodeFirstDatabase.Product
    |   |_Predicate
    |     |_Like
    |       |_Var(Extent1).Name
    |       |_&apos;M%&apos;
    |       |_null
    |_Projection
      |_NewInstance : Record[&apos;Name&apos;=Edm.String]
        |_Column : &apos;Name&apos;
          |_Var(Filter1).Name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the Select and First query logs the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DbQueryCommandTree
|_Parameters
|_Query : Collection{Record[&apos;Name&apos;=Edm.String]}
  |_Project
    |_Input : &apos;Limit1&apos;
    | |_Limit
    |   |_Scan : CodeFirstDatabase.Product
    |   |_1
    |_Projection
      |_NewInstance : Record[&apos;Name&apos;=Edm.String]
        |_Column : &apos;Name&apos;
          |_Var(Limit1).Name
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (10) Performance</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-10-performance/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-10-performance/</guid><description>The previous parts has discussed a few aspects that can impact the performance of Entity Framework and LINQ to Entities, and here is a summary:</description><pubDate>Wed, 17 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-9-performance&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-9-performance&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous parts has discussed a few aspects that can impact the performance of Entity Framework and LINQ to Entities, and here is a summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Properly specify database initializer and provider manifest token resolver can improve the initialization performance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LINQ to Entities query can have better performance than LINQ to Objects query. An intuitive example is, context.Set&amp;lt;TEntity&amp;gt;().Take(2) can have better performance than context.Set&amp;lt;TEntity&amp;gt;().ToList().Take(2):&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the former query, Take is LINQ to Entities method (Queryable.Take). It is translated to database query, only the query result is read to local.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the latter query, Take is LINQ to Object method (Enumerable.Take). This query reads the entire table from database to local, and query locally with Enumerable.Take.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using Select to only query the needed data can have better performance than querying full entity with all data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In lazy loading, accessing an entity’s navigation property can cause additional database query round trips (the N + 1 queries problem). Eager loading can improve the performance by read all needed data with 1 single database query.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Disabling entity tracking can improve the performance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Disabling automatic change detection can improve the performance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When adding multiple entities to repository, each DbSet&amp;lt;T&amp;gt;.Add call triggers change detection. DbSet&amp;lt;T&amp;gt;.AddRange can improve performance because it only triggers change detection once. Similarly, DbSet&amp;lt;T&amp;gt;.RemoveRange can improve performance from multiple DbSet&amp;lt;T&amp;gt;.Remove calls.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This part continues discussing performance.&lt;/p&gt;
&lt;h2&gt;Initialization&lt;/h2&gt;
&lt;p&gt;The following example simply pulls categories from the repository, with one LINQ to Entities query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class Query
{
    internal static void Table()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            IQueryable&amp;lt;ProductCategory&amp;gt; allRowsInTable = adventureWorks.ProductCategories;
            allRowsInTable.ForEach(categoryRow =&amp;gt; Trace.WriteLine(
                $&quot;{categoryRow.ProductCategoryID}:{categoryRow.Name}&quot;));
            // 1:Bikes 2:Components 3:Clothing 4:Accessories 
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing above code, the SQL Profiler will trace a bunch of SQL queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select cast(serverproperty(&apos;EngineEdition&apos;) as int)

SELECT Count(*)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE t.TABLE_SCHEMA + &apos;.&apos; + t.TABLE_NAME IN (&apos;Production.vProductAndDescription&apos;,&apos;Production.ProductCategory&apos;,&apos;Production.ProductSubcategory&apos;,&apos;Production.Product&apos;,&apos;Production.ProductProductPhoto&apos;,&apos;Production.ProductPhoto&apos;)
    OR t.TABLE_NAME = &apos;EdmMetadata&apos;

exec sp_executesql N&apos;SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[__MigrationHistory] AS [Extent1]
        WHERE [Extent1].[ContextKey] = @p__linq__0
    )  AS [GroupBy1]&apos;,N&apos;@p__linq__0 nvarchar(4000)&apos;,@p__linq__0=N&apos;Dixin.Linq.EntityFramework.AdventureWorks&apos;

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[__MigrationHistory] AS [Extent1]
    )  AS [GroupBy1]

SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ModelHash] AS [ModelHash]
    FROM [dbo].[EdmMetadata] AS [Extent1]
    ORDER BY [Extent1].[Id] DESC

SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only the last SELECT query is the expected LINQ to Entities query translation. Actually, before a database’s first operation at runtime (e.g., querying Production.ProductCategory table here), Entity Framework does a lot of work to initialize its object-relational mapping:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize provider manifest&lt;/li&gt;
&lt;li&gt;Initialize the entity data model. Entity framework automatically builds the object models (CLR models, not above entities), conceptual models, storage models, object-conceptual model mappings, conceptual-storage model mappings, etc..&lt;/li&gt;
&lt;li&gt;Initialize the database, if needed.&lt;/li&gt;
&lt;li&gt;Initialize mapping views, which are the mapping information for entity sets.&lt;/li&gt;
&lt;li&gt;Initialize a dynamic assembly &quot;EntityFrameworkDynamicProxies-{OriginalAssemblyName}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot;, and define proxy classes in it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above initialization steps executes only once at runtime, and they can be improved from the default behavior.&lt;/p&gt;
&lt;h3&gt;Provider manifest initialization&lt;/h3&gt;
&lt;p&gt;As fore mentioned, Entity Framework implements the provider model to work with different kinds of data stores, and it need to get the basic information of current data store. For SQL database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The database server’s version is detected by calling DbConnection.ServerVersion&lt;/li&gt;
&lt;li&gt;The engine edition is queried by above &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms174396.aspx&quot;&gt;SERVERPROPERTY&lt;/a&gt; metadata function, to determine whether it is a on premise database (SQL Server) or cloud database (SQL Azure, aka Azure SQL Database).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this tutorial, the server version and engine edition is known. So these information can be provided to Entity Framework via System.Data.Entity.Infrastructure.IManifestTokenResolver:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SqlConfiguration : DbConfiguration
{
    public SqlConfiguration()
    {
        this.SetManifestTokenResolver(new SqlManifestTokenResolver());
    }
}

public class SqlManifestTokenResolver : IManifestTokenResolver
{
    public string ResolveManifestToken(DbConnection connection) =&amp;gt; &quot;2012&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For SQL database, the supported provider manifest tokens are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.SqlServer
{
    using System.Data.Entity.Core.Common;

    internal class SqlProviderManifest : DbXmlEnabledProviderManifest
    {
        internal const string TokenSql8 = &quot;2000&quot;;

        internal const string TokenSql9 = &quot;2005&quot;;

        internal const string TokenSql10 = &quot;2008&quot;;

        internal const string TokenSql11 = &quot;2012&quot;;

        internal const string TokenAzure11 = &quot;2012.Azure&quot;;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For any on premise SQL engine newer than 11.0, just use “2012”.&lt;/p&gt;
&lt;p&gt;Also, apparently the AdventureWorks database does not have the migration history and entity data model info, and creating database is not needed as well. So the database initialization can be turned off, by setting the initializer to NullDatabaseInitializer&amp;lt;TContext&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    static AdventureWorks()
    {
        Database.SetInitializer(new NullDatabaseInitializer&amp;lt;AdventureWorks&amp;gt;()); // Call once.
        // Equivalent to: Database.SetInitializer&amp;lt;AdventureWorks&amp;gt;(null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where NullDatabaseInitializer&amp;lt;TContext&amp;gt; is just an empty class doing nothing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class NullDatabaseInitializer&amp;lt;TContext&amp;gt; : IDatabaseInitializer&amp;lt;TContext&amp;gt; where TContext : DbContext
    {
        public virtual void InitializeDatabase(TContext context)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all the additional database queries for initialization are turned off.&lt;/p&gt;
&lt;h3&gt;Database initialization&lt;/h3&gt;
&lt;p&gt;The database initialization work is represented by System.Data.Entity.IDatabaseInitializer&amp;lt;TContext&amp;gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public interface IDatabaseInitializer&amp;lt;in TContext&amp;gt; where TContext : DbContext
    {
        void InitializeDatabase(TContext context);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Entity Framework provides several built-in initializers under System.Data.Entity namespace:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NullDatabaseInitializer&amp;lt;TContext&amp;gt;: Do nothing for initialization&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseAlways&amp;lt;TContext&amp;gt;: Always drop the database and create again&lt;/li&gt;
&lt;li&gt;DropCreateDatabaseIfModelChanges&amp;lt;TContext&amp;gt;: Drop and create database when the code mapping mismatches database schema.&lt;/li&gt;
&lt;li&gt;MigrateDatabaseToLatestVersion&amp;lt;TContext, TMigrationsConfiguration&amp;gt;: Use the specified code to update the database schema to the latest version.&lt;/li&gt;
&lt;li&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: Create database if not exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CreateDatabaseIfNotExists&amp;lt;TContext&amp;gt;: is the default initializer, so it is executed here too. As a result, Entity Framework attempts to &lt;a href=&quot;https://romiller.com/2014/06/10/reducing-code-first-database-chatter/&quot;&gt;query the existence of the mapped tables and views, database migration history, and entity data model info, etc&lt;/a&gt;. Apparently, here AdventureWorks database does not have the migration and entity data model info; recreating database is not needed as well. So the database initialization can be turned off, by setting the initializer to NullDatabaseInitializer&amp;lt;TContext&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    static AdventureWorks()
    {
        Database.SetInitializer(new NullDatabaseInitializer&amp;lt;AdventureWorks&amp;gt;()); // Call once.
        // Equivalent to: Database.SetInitializer&amp;lt;AdventureWorks&amp;gt;(null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where NullDatabaseInitializer&amp;lt;TContext&amp;gt; is just an empty class doing nothing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public class NullDatabaseInitializer&amp;lt;TContext&amp;gt; : IDatabaseInitializer&amp;lt;TContext&amp;gt; where TContext : DbContext
    {
        public virtual void InitializeDatabase(TContext context)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all the additional database queries for initialization are turned off.&lt;/p&gt;
&lt;h3&gt;Mapping views initialization&lt;/h3&gt;
&lt;p&gt;Mapping views are not the views inside the database. They are System.Data.Entity.Infrastructure.MappingViews.DbMappingView objects, representing the mapping information for entity sets. Instead of generate these objects at runtime, pre-generate them at design time can improve the performance. Microsoft provides a Visual Studio extension, Entity Framework Power Tools, to generate these code. It needs to be &lt;a href=&quot;http://thedatafarm.com/data-access/installing-ef-power-tools-into-vs2015/&quot;&gt;modified&lt;/a&gt; to installed with the latest Visual Studio. After the installation, just right click the code file containing the database mapping (the class derived from DbContext), and in the menu click Entity Framework =&amp;gt; Generate Views, it will generate a file, containing the code to create the DbMappingView objects.&lt;/p&gt;
&lt;h2&gt;Cache&lt;/h2&gt;
&lt;p&gt;After the metadata is initialized, they are cached, so that the initialization only happens once for the AppDomain. Entity Framework also implement cache for entities and query translation.&lt;/p&gt;
&lt;h3&gt;Entity cache&lt;/h3&gt;
&lt;p&gt;As fore mentioned, by default, the entities queried from repository are cached and tracked. This behavior can be demonstrated by the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CachedEntity()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category1 = adventureWorks.ProductCategories
            .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
        category1.Name = &quot;Cache&quot;;

        ProductCategory category2 = adventureWorks.ProductCategories
            .Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
        Trace.WriteLine(category2.Name); // Cache
        Trace.WriteLine(category1 == category2); // True

        ProductCategory category3 = adventureWorks.ProductCategories
            .SqlQuery(@&quot;
                SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
                FROM [Production].[ProductCategory]
                ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
            .Single();
        Trace.WriteLine(category1 == category3); // True
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the first query reads data from the repository and materialize the data to a category entity, and update its Name. Then the repository is queried again by Name. After reading the data, Entity Framework founds the primary key is the same as the cached entity, so Entity Framework does not materialize the data just read, it reuses the previous category entity. Performance can be improved by skipping the materialization, but tricky result can happen. The second query reads entity with Name “Bikes”, but the query result entity has Name “Cache”. This is not only LINQ to Entities queries’ behavior, When DbSet&amp;lt;T&amp;gt;.SqlQuery to directly execute SQL query in the repository, Entity Framework still looks up cache before materializing.&lt;/p&gt;
&lt;p&gt;Entity is not cached when tracking is turned off, or entity is not queried from the repository. Each of the following queries materializes a new entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UncachedEntity()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category1 = adventureWorks.ProductCategories
            .Single(entity =&amp;gt; entity.ProductCategoryID == 1);
        category1.Name = &quot;Cache&quot;;

        ProductCategory category2 = adventureWorks.ProductCategories
            .AsNoTracking().Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
        Trace.WriteLine(category2.Name); // Bikes
        Trace.WriteLine(category1 == category2); // False

        ProductCategory category3 = adventureWorks.Database
            .SqlQuery&amp;lt;ProductCategory&amp;gt;(@&quot;
                SELECT TOP (1) [ProductCategory].[ProductCategoryID], [ProductCategory].[Name]
                FROM [Production].[ProductCategory]
                ORDER BY [ProductCategory].[ProductCategoryID]&quot;)
            .Single();
        Trace.WriteLine(category1 == category3); // False
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbSet.Find accept the primary keys and returns an entity. Calling Find can improve the performance, because it looks up cache before querying the repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Find()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        Product[] products = adventureWorks.Products
            .Where(product =&amp;gt; product.Name.StartsWith(&quot;Road&quot;)).ToArray(); // SELECT.
        Product fromCache = adventureWorks.Products.Find(999); // No database query.
        Trace.WriteLine(products.Contains(fromCache)); // True
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here when Find is called, entity with the specified primary key is already queries, cached and tracked, so Find directly returns the cached entity, without repository query or data materialization.&lt;/p&gt;
&lt;h3&gt;LINQ query translation cache&lt;/h3&gt;
&lt;p&gt;As discussed in the query translation part, Entity Framework translates a LINQ to Entities query in 2 steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Converts .NET expression tree to database command tree&lt;/li&gt;
&lt;li&gt;Generate SQL from database command tree&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To improve the performance, the generated SQL is automatically cached for each database command tree. Take the following query as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TranslationCache()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        int minLength = 1;
        IQueryable&amp;lt;ProductCategory&amp;gt; query = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= minLength)
            .Include(category =&amp;gt; category.ProductSubcategories);
        query.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Entity Framework always convert the LINQ query’s expression tree to database command tree, then it generates the cache key with the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The database command tree’s root DbExpression object’s string representation. Here it is: [Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[Dixin.Linq.EntityFramework.ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),@p__linq__0:Edm.Int32(Nullable=False,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;The parameters’ string representation: @@1p__linq__0:System.Int32&lt;/li&gt;
&lt;li&gt;The path of the Include query: ProductSubcategories&lt;/li&gt;
&lt;li&gt;The query’s MergeOption. As fore mentioned, it is AppendOnly by default.&lt;/li&gt;
&lt;li&gt;System.Data.Entity.Core.Objects.ObjectContextOptions’s UseCSharpNullComparisonBehavior property value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The translations are cached in a dictionary, so the generated key is used to look up a dictionary value. If not found, then generate SQL and add to the dictionary. This cached value is called query plan, and represented by System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan. It includes the translated database query represented by DbCommand and System.Data.Entity.Core.Common.DbCommandDefinition, and other metadata, like parameters, result type, etc..&lt;/p&gt;
&lt;p&gt;The following example executes 2 LINQ to Entities queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UncachedTranslation()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithConstant1 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= 1);
        queryWithConstant1.Load();

        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithConstant2 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= 10);
        queryWithConstant2.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These first LINQ query builds expression trees with a ConstantExpression node representing int value 1. The second query builds similar expression tree but with a different ConstantExpression node representing int value 10. SO they are converted to 2 different database command trees, with 2 different DbConstantExpression nodes. The 2 database command trees’ string representations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[Dixin.Linq.EntityFramework.ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),1:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;[Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[Dixin.Linq.EntityFramework.ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),10:Edm.Int32(Nullable=True,DefaultValue=))))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So their query translation cannot be reused for each other. To resolve this problem, these queries can be parameterized by simply replace the constants with variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CachedTranslation()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        int minLength = 1;
        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithClosure1 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= minLength);
        queryWithClosure1.Load();

        minLength = 10;
        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithClosure2 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= minLength);
        queryWithClosure2.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As discussed in the C# features chapter, the predicate lambda expressions capture variable minLength with the closure syntactic sugar. The above code is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
private sealed class DisplayClass1
{
    public int minLength;
}

[CompilerGenerated]
private sealed class DisplayClass2
{
    public int minLength;
}

internal static void CompiledCachedTranslation()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        int minLength = 1;
        DisplayClass1 displayClass1 = new DisplayClass1() { minLength = minLength };
        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithClosure1 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= displayClass1.minLength);
        queryWithClosure1.Load();

        minLength = 10;
        DisplayClass1 displayClass2 = new DisplayClass1() { minLength = minLength };
        IQueryable&amp;lt;ProductCategory&amp;gt; queryWithClosure2 = adventureWorks.ProductCategories
            .Where(category =&amp;gt; category.Name.Length &amp;gt;= displayClass2.minLength);
        queryWithClosure2.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The variable access is compiled to filed access. So in the LINQ queries’ expression trees, there are no longer ConstantExpression nodes, but FieldExpression nodes. Entity Framework converts these FieldExpression nodes to DbParameterReference nodes, representing int parameters. As a result, these 2 LINQ queries are converted to identical database command trees, with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;identical root node string representation: [Filter](BV&apos;LQ1&apos;=([Scan](AdventureWorks.ProductCategories:Transient.collection[Dixin.Linq.EntityFramework.ProductCategory(Nullable=True,DefaultValue=)]))([&amp;gt;=](FUNC&amp;lt;Edm.Length(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))&amp;gt;:ARGS((Var(&apos;LQ1&apos;)[.]Name)),@p__linq__0:Edm.Int32(Nullable=False,DefaultValue=))))&lt;/li&gt;
&lt;li&gt;identical parameters’ string representation: @@1p__linq__0:System.Int32&lt;/li&gt;
&lt;li&gt;and all the other identical metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the query translations have identical cache key, and their translations can be reused for each other.&lt;/p&gt;
&lt;p&gt;If a query method accepts values instead of lambda expression, this parameterization approach does not work. For example, Skip and Take accept int values as parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UncachedSkipTake()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        int skip = 1;
        int take = 1;
        IQueryable&amp;lt;ProductSubcategory&amp;gt; skipTakeWithVariable1 = adventureWorks.ProductSubcategories
            .OrderBy(p =&amp;gt; p.ProductSubcategoryID).Skip(skip).Take(take);
        skipTakeWithVariable1.Load();

        skip = 10;
        take = 10;
        IQueryable&amp;lt;ProductSubcategory&amp;gt; skipTakeWithVariable2 = adventureWorks.ProductSubcategories
            .OrderBy(p =&amp;gt; p.ProductSubcategoryID).Skip(skip).Take(take);
        skipTakeWithVariable2.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above LINQ queries access to variable skip and take, but these variable access are also represented by ConstantExpression nodes. So their expression trees are different, and converted database command trees are different, and their translations cannot be reused for each other. To resolve this problem, Entity Framework provides a lambda expression version for these methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    using System.Linq;
    using System.Linq.Expressions;

    public static class QueryableExtensions
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Skip&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);

        public static IQueryable&amp;lt;TSource&amp;gt; Take&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; countAccessor);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now Skip and Take can access variables via closure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CachedSkipTake()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        int skip = 1;
        int take = 1;
        IQueryable&amp;lt;ProductSubcategory&amp;gt; skipTakeWithClosure1 = adventureWorks.ProductSubcategories
            .OrderBy(p =&amp;gt; p.ProductSubcategoryID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
        skipTakeWithClosure1.Load();

        skip = 10;
        take = 10;
        IQueryable&amp;lt;ProductSubcategory&amp;gt; skipTakeWithClosure2 = adventureWorks.ProductSubcategories
            .OrderBy(p =&amp;gt; p.ProductSubcategoryID).Skip(() =&amp;gt; skip).Take(() =&amp;gt; take);
        skipTakeWithClosure2.Load();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These LINQ queries have FieldExpression nodes again. Entity Framework can convert them to identical parameterized database command trees. Now their translations can be reused for each other.&lt;/p&gt;
&lt;h3&gt;SQL query plan cache&lt;/h3&gt;
&lt;p&gt;LINQ queries with different constants are translated to different SQL queries. Above queryWithConstant1 and queryWithConstant2 are translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE (LEN([Extent1].[Name])) &amp;gt;= 1

SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE (LEN([Extent1].[Name])) &amp;gt;= 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently they have different query plans in SQL database, which cannot be reused for each other:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-10_13D39/image_16.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-10_13D39/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With parameterization, queryWithClosure1 and queryWithClosure2 are translated to identical SQL queries, with different parameter values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE (LEN([Extent1].[Name])) &amp;gt;= @p__linq__0&apos;,N&apos;@p__linq__0 int&apos;,@p__linq__0=1

exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE (LEN([Extent1].[Name])) &amp;gt;= @p__linq__0&apos;,N&apos;@p__linq__0 int&apos;,@p__linq__0=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in SQL database, queryWithClosure1’s query plan is cached and reused for queryWithClosure2:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-10_13D39/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-and-LINQ-to-Entities-10_13D39/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Asynchrony&lt;/h2&gt;
&lt;p&gt;Generally, for long running IO bound operation, asynchrony can improve the application responsiveness and service scalability. Entity Framework supports asynchrony for database CRUD operations, and these async APIs are very easy to use with C# async/await keywords.&lt;/p&gt;
&lt;h3&gt;Asynchronous data queries and changes&lt;/h3&gt;
&lt;p&gt;For LINQ to Entities queries, Entity Framework starts to read the data when values are pulled from IQueryable&amp;lt;T&amp;gt; data source, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull the values from IQueryable&amp;lt;T&amp;gt; with the iterator pattern, typically a foreach loop.&lt;/li&gt;
&lt;li&gt;Call a query method to return a single value from the IQueryable&amp;lt;T&amp;gt;, like First, etc..&lt;/li&gt;
&lt;li&gt;Call a LINQ to Objects query method to return a new collection, like ToArray, etc..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For these operations and APIs, Entity Framework provides async parities as IQueryable&amp;lt;T&amp;gt; extension methods, defined in System.Data.Entity.QueryableExtensions class:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;QueryableExtensions.ForEachAsync asynchronously pulls each value from IQueryable&amp;lt;T&amp;gt; data source and execute the specified action with each value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;QueryableExtensions provides async methods to return a single value:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Element: FirstAsync, FirstOrDefaultAsync, SingleAsync, SingleOrDefaultAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aggregation: CountAsync, LongCountAsync, MinAsync, MaxAsync, SumAsync, AverageAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quantifier: AllAsync, AnyAsync, ContainsAsync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;QueryableExtensions provides async methods to return a new collection: ToArrayAsync, ToDictionaryAsync, ToListAsync&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For data changes, DbContext.SaveChangesAsync is provided as a parity of DbContext.SaveChanges. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task Async()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        IQueryable&amp;lt;ProductCategory&amp;gt; categories = adventureWorks.ProductCategories;
        await categories.ForEachAsync( // Async version of foreach/ForEach.
            category =&amp;gt; Trace.WriteLine(category.Name));

        ProductSubcategory subcategory = await adventureWorks.ProductSubcategories
            .FirstAsync(entity =&amp;gt; entity.Name.StartsWith(&quot;A&quot;)); // Async version of First.
        Trace.WriteLine(subcategory.Name);

        Product[] products = await adventureWorks.Products
            .Where(product =&amp;gt; product.ListPrice &amp;lt;= 10)
            .ToArrayAsync(); // Async version of ToArray.

        adventureWorks.Products.RemoveRange(products);
        await adventureWorks.SaveChangesAsync(); // Async version of SaveChanges.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Transactions with asynchronous operations&lt;/h3&gt;
&lt;p&gt;Entity Framework and ADO.NET async APIs also work with DbContextTransaction and DbTransaction naturally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task DbContextTransactionAsync()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    using (DbContextTransaction transaction = adventureWorks.Database.BeginTransaction(
        IsolationLevel.ReadUncommitted))
    {
        try
        {
            Trace.WriteLine(adventureWorks.QueryCurrentIsolationLevel()); // ReadUncommitted

            ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
            adventureWorks.ProductCategories.Add(category);
            Trace.WriteLine(await adventureWorks.SaveChangesAsync()); // 1

            Trace.WriteLine(await adventureWorks.Database.ExecuteSqlCommandAsync(
                &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {0}&quot;,
                nameof(ProductCategory))); // 1
            transaction.Commit();
        }
        catch
        {
            transaction.Rollback();
            throw;
        }
    }
}

internal static async Task DbTransactionAsync()
{
    using (SqlConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
    {
        await connection.OpenAsync();
        using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
        {
            try
            {
                using (AdventureWorks adventureWorks = new AdventureWorks(connection))
                {
                    adventureWorks.Database.UseTransaction(transaction);
                    Trace.WriteLine(adventureWorks.QueryCurrentIsolationLevel()); // Serializable

                    ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                    adventureWorks.ProductCategories.Add(category);
                    Trace.WriteLine(await adventureWorks.SaveChangesAsync()); // 1.
                }

                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                    DbParameter parameter = command.CreateParameter();
                    parameter.ParameterName = &quot;@p0&quot;;
                    parameter.Value = nameof(ProductCategory);
                    command.Parameters.Add(parameter);
                    command.Transaction = transaction;
                    Trace.WriteLine(await command.ExecuteNonQueryAsync()); // 1
                }
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TransactionScope by default does not support across thread transaction flow. Using the the async/await syntactic sugar for TransactionScope causes InvalidOperationException: A TransactionScope must be disposed on the same thread that it was created.. To resolved this, .NET 4.5.1+ introduced a new constructor for TransactionScope to explicitly enable transaction flow across thread continuations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task TransactionScopeAsync()
{
    using (TransactionScope scope = new TransactionScope(
        TransactionScopeOption.Required,
        new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead },
        TransactionScopeAsyncFlowOption.Enabled))
    {
        using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = DbContextExtensions.CurrentIsolationLevelSql;
            await connection.OpenAsync();
            using (DbDataReader reader = await command.ExecuteReaderAsync())
            {
                await reader.ReadAsync();
                Trace.WriteLine(reader[0]); // RepeatableRead
            }
        }

        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
            adventureWorks.ProductCategories.Add(category);
            Trace.WriteLine(await adventureWorks.SaveChangesAsync()); // 1
        }

        using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
            DbParameter parameter = command.CreateParameter();
            parameter.ParameterName = &quot;@p0&quot;;
            parameter.Value = nameof(ProductCategory);
            command.Parameters.Add(parameter);

            await connection.OpenAsync();
            Trace.WriteLine(await command.ExecuteNonQueryAsync()); // 1
        }

        scope.Complete();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Asynchronous concurrency conflicts&lt;/h3&gt;
&lt;p&gt;Entity Framework also provides async APIs for other database operations. In the previous concurrency part, a DbContext.SaveChanges overload is implemented to handle concurrency conflict, refresh entity, and retry saving changes. Here a async version can be implemented easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;DbEntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, int retryCount = 3)
    {
        context.NotNull(nameof(context));
        Argument.Range(retryCount &amp;gt; 0, $&quot;{retryCount} must be greater than 0.&quot;, nameof(retryCount));

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return await context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                await resolveConflictsAsync(exception.Entries);
            }
        }
        return await context.SaveChangesAsync();
    }

    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, Func&amp;lt;IEnumerable&amp;lt;DbEntityEntry&amp;gt;, Task&amp;gt; resolveConflictsAsync, RetryStrategy retryStrategy)
    {
        context.NotNull(nameof(context));
        resolveConflictsAsync.NotNull(nameof(resolveConflictsAsync));
        retryStrategy.NotNull(nameof(retryStrategy));

        RetryPolicy retryPolicy = new RetryPolicy(
            new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(), retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt;
            resolveConflictsAsync(((DbUpdateConcurrencyException)e.LastException).Entries).Wait();
        return await retryPolicy.ExecuteAsync(async () =&amp;gt; await context.SaveChangesAsync());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the async/await syntactic sugar, the implementation looks very similar to the synchronous version. The following are the SaveChangesAsync overloads to accept RefreshConflict enumeration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
    {
        context.NotNull(nameof(context));
        Argument.Range(retryCount &amp;gt; 0, $&quot;{retryCount} must be greater than 0.&quot;, nameof(retryCount));

        return await context.SaveChangesAsync(
            async conflicts =&amp;gt;
            {
                foreach (DbEntityEntry tracking in conflicts)
                {
                    await tracking.RefreshAsync(refreshMode);
                }
            },
            retryCount);
    }

    public static async Task&amp;lt;int&amp;gt; SaveChangesAsync(
        this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy)
    {
        context.NotNull(nameof(context));
        retryStrategy.NotNull(nameof(retryStrategy));

        return await context.SaveChangesAsync(
            async conflicts =&amp;gt;
            {
                foreach (DbEntityEntry tracking in conflicts)
                {
                    await tracking.RefreshAsync(refreshMode);
                }
            },
            retryStrategy);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of calling the previously defined Refresh extension method to refresh the DbEntityEntry object, here a async method RefreshAsync is called to refresh asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbEntutyEntryExtensions
{
    public static async Task&amp;lt;DbEntityEntry&amp;gt; RefreshAsync(this DbEntityEntry tracking, RefreshConflict refreshMode)
    {
        tracking.NotNull(nameof(tracking));

        switch (refreshMode)
        {
            case RefreshConflict.StoreWins:
                {
                    await tracking.ReloadAsync();
                    break;
                }
            case RefreshConflict.ClientWins:
                {
                    DbPropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
                    if (databaseValues == null)
                    {
                        tracking.State = EntityState.Detached;
                    }
                    else
                    {
                        tracking.OriginalValues.SetValues(databaseValues);
                    }
                    break;
                }
            case RefreshConflict.MergeClinetAndStore:
                {
                    DbPropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();
                    if (databaseValues == null)
                    {
                        tracking.State = EntityState.Detached;
                    }
                    else
                    {
                        DbPropertyValues originalValues = tracking.OriginalValues.Clone();
                        tracking.OriginalValues.SetValues(databaseValues);
                        databaseValues.PropertyNames
                            .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                            .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
                    }
                    break;
                }
        }
        return tracking;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now concurrency conflict can be resolved automatically and asynchronously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task SaveChangesAsync()
{
    using (AdventureWorks adventureWorks1 = new AdventureWorks())
    using (AdventureWorks adventureWorks2 = new AdventureWorks())
    {
        const int id = 950;
        Product productCopy1 = await adventureWorks1.Products.FindAsync(id);
        Product productCopy2 = await adventureWorks2.Products.FindAsync(id);

        productCopy1.Name = nameof(adventureWorks1);
        productCopy1.ListPrice = 100;
        await adventureWorks1.SaveChangesAsync();

        productCopy2.Name = nameof(adventureWorks2);
        productCopy2.ProductSubcategoryID = 1;
        await adventureWorks2.SaveChangesAsync(RefreshConflict.MergeClinetAndStore);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Visual Studio Entity Data Model Wizard Not Responding</title><link>https://dixin.github.io/posts/visual-studio-entity-data-model-wizard-not-responding/</link><guid isPermaLink="true">https://dixin.github.io/posts/visual-studio-entity-data-model-wizard-not-responding/</guid><description>This post is for the issue that Entity Data Model Wizard becomes not responding. In Visual Studio 2015, when clicking the Finish button to create the entity data model from SQL Server 2014 SP! databas</description><pubDate>Sat, 13 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post is for the issue that Entity Data Model Wizard becomes not responding. In Visual Studio 2015, when clicking the Finish button to create the entity data model from SQL Server 2014 SP! database, the wizard is frozen:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are some solutions like &lt;a href=&quot;http://stackoverflow.com/questions/16901708/ado-net-entity-data-model-bug&quot;&gt;deleting all data connections&lt;/a&gt; in Server explorer (by delete file %AppData%\Microsoft\VisualStudio\14.0\ServerExplorer\DefaultView.SEView), but didn’t work for Visual Studio 2015 + SQL Server 2014 SP1. After trouble shooting with SQL Server Profiler, it shows Visual Studio hangs because it of the following query (the code is formatted for readability):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT
    [UnionAll1].[Ordinal] AS [C1],
    [Extent1].[CatalogName] AS [CatalogName],
    [Extent1].[SchemaName] AS [SchemaName],
    [Extent1].[Name] AS [Name],
    [UnionAll1].[Name] AS [C2],
    [UnionAll1].[IsNullable] AS [C3],
    [UnionAll1].[TypeName] AS [C4],
    [UnionAll1].[MaxLength] AS [C5],
    [UnionAll1].[Precision] AS [C6],
    [UnionAll1].[DateTimePrecision] AS [C7],
    [UnionAll1].[Scale] AS [C8],
    [UnionAll1].[IsIdentity] AS [C9],
    [UnionAll1].[IsStoreGenerated] AS [C10],
    CASE
        WHEN ([Project5].[C2] IS NULL) THEN CAST(0 AS bit)
        ELSE [Project5].[C2]
    END AS [C11]
FROM (
    SELECT
        QUOTENAME(TABLE_SCHEMA) + QUOTENAME(TABLE_NAME) [Id],
        TABLE_CATALOG [CatalogName],
        TABLE_SCHEMA [SchemaName],
        TABLE_NAME [Name]
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = &apos;BASE TABLE&apos;) AS [Extent1]
INNER JOIN (
    SELECT
        [Extent2].[Id] AS [Id],
        [Extent2].[Name] AS [Name],
        [Extent2].[Ordinal] AS [Ordinal],
        [Extent2].[IsNullable] AS [IsNullable],
        [Extent2].[TypeName] AS [TypeName],
        [Extent2].[MaxLength] AS [MaxLength],
        [Extent2].[Precision] AS [Precision],
        [Extent2].[DateTimePrecision] AS [DateTimePrecision],
        [Extent2].[Scale] AS [Scale],
        [Extent2].[IsIdentity] AS [IsIdentity],
        [Extent2].[IsStoreGenerated] AS [IsStoreGenerated],
        0 AS [C1],
        [Extent2].[ParentId] AS [ParentId]
    FROM (
        SELECT
            QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id],
            QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId],
            c.COLUMN_NAME [Name],
            c.ORDINAL_POSITION [Ordinal],
            CAST(CASE c.IS_NULLABLE
                WHEN &apos;YES&apos; THEN 1
                WHEN &apos;NO&apos; THEN 0
                ELSE 0
            END AS bit) [IsNullable],
            CASE
                WHEN c.DATA_TYPE IN (&apos;varchar&apos;, &apos;nvarchar&apos;, &apos;varbinary&apos;) AND
                    c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + &apos;(max)&apos;
                ELSE c.DATA_TYPE
            END
            AS [TypeName],
            c.CHARACTER_MAXIMUM_LENGTH [MaxLength],
            CAST(c.NUMERIC_PRECISION AS integer) [Precision],
            CAST(c.DATETIME_PRECISION AS integer) [DateTimePrecision],
            CAST(c.NUMERIC_SCALE AS integer) [Scale],
            c.COLLATION_CATALOG [CollationCatalog],
            c.COLLATION_SCHEMA [CollationSchema],
            c.COLLATION_NAME [CollationName],
            c.CHARACTER_SET_CATALOG [CharacterSetCatalog],
            c.CHARACTER_SET_SCHEMA [CharacterSetSchema],
            c.CHARACTER_SET_NAME [CharacterSetName],
            CAST(0 AS bit) AS [IsMultiSet],
            CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsIdentity&apos;) AS bit) AS [IsIdentity],
            CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsComputed&apos;) | CASE
                WHEN c.DATA_TYPE = &apos;timestamp&apos; THEN 1
                ELSE 0
            END AS bit) AS [IsStoreGenerated],
            c.COLUMN_DEFAULT AS [Default]
        FROM INFORMATION_SCHEMA.COLUMNS c
        INNER JOIN INFORMATION_SCHEMA.TABLES t
            ON c.TABLE_CATALOG = t.TABLE_CATALOG
            AND c.TABLE_SCHEMA = t.TABLE_SCHEMA
            AND c.TABLE_NAME = t.TABLE_NAME
            AND t.TABLE_TYPE = &apos;BASE TABLE&apos;) AS [Extent2]
    UNION ALL
    SELECT
        [Extent3].[Id] AS [Id],
        [Extent3].[Name] AS [Name],
        [Extent3].[Ordinal] AS [Ordinal],
        [Extent3].[IsNullable] AS [IsNullable],
        [Extent3].[TypeName] AS [TypeName],
        [Extent3].[MaxLength] AS [MaxLength],
        [Extent3].[Precision] AS [Precision],
        [Extent3].[DateTimePrecision] AS [DateTimePrecision],
        [Extent3].[Scale] AS [Scale],
        [Extent3].[IsIdentity] AS [IsIdentity],
        [Extent3].[IsStoreGenerated] AS [IsStoreGenerated],
        6 AS [C1],
        [Extent3].[ParentId] AS [ParentId]
    FROM (
        SELECT
            QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id],
            QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId],
            c.COLUMN_NAME [Name],
            c.ORDINAL_POSITION [Ordinal],
            CAST(CASE c.IS_NULLABLE
                WHEN &apos;YES&apos; THEN 1
                WHEN &apos;NO&apos; THEN 0
                ELSE 0
            END AS bit) [IsNullable],
            CASE
                WHEN c.DATA_TYPE IN (&apos;varchar&apos;, &apos;nvarchar&apos;, &apos;varbinary&apos;) AND
                    c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + &apos;(max)&apos;
                ELSE c.DATA_TYPE
            END
            AS [TypeName],
            c.CHARACTER_MAXIMUM_LENGTH [MaxLength],
            CAST(c.NUMERIC_PRECISION AS integer) [Precision],
            CAST(c.DATETIME_PRECISION AS integer) AS [DateTimePrecision],
            CAST(c.NUMERIC_SCALE AS integer) [Scale],
            c.COLLATION_CATALOG [CollationCatalog],
            c.COLLATION_SCHEMA [CollationSchema],
            c.COLLATION_NAME [CollationName],
            c.CHARACTER_SET_CATALOG [CharacterSetCatalog],
            c.CHARACTER_SET_SCHEMA [CharacterSetSchema],
            c.CHARACTER_SET_NAME [CharacterSetName],
            CAST(0 AS bit) AS [IsMultiSet],
            CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsIdentity&apos;) AS bit) AS [IsIdentity],
            CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsComputed&apos;) | CASE
                WHEN c.DATA_TYPE = &apos;timestamp&apos; THEN 1
                ELSE 0
            END AS bit) AS [IsStoreGenerated],
            c.COLUMN_DEFAULT [Default]
        FROM INFORMATION_SCHEMA.COLUMNS c
        INNER JOIN INFORMATION_SCHEMA.VIEWS v
            ON c.TABLE_CATALOG = v.TABLE_CATALOG
            AND c.TABLE_SCHEMA = v.TABLE_SCHEMA
            AND c.TABLE_NAME = v.TABLE_NAME
        WHERE NOT (v.TABLE_SCHEMA = &apos;dbo&apos;
        AND v.TABLE_NAME IN (&apos;syssegments&apos;, &apos;sysconstraints&apos;)
        AND SUBSTRING(CAST(SERVERPROPERTY(&apos;productversion&apos;) AS varchar(20)), 1, 1) = 8)) AS [Extent3]) AS [UnionAll1]
    ON (0 = [UnionAll1].[C1])
    AND ([Extent1].[Id] = [UnionAll1].[ParentId])
LEFT OUTER JOIN (
    SELECT
        [UnionAll2].[Id] AS [C1],
        CAST(1 AS bit) AS [C2]

    FROM (
        SELECT
            QUOTENAME(tc.CONSTRAINT_SCHEMA) + QUOTENAME(tc.CONSTRAINT_NAME) [Id],
            QUOTENAME(tc.TABLE_SCHEMA) + QUOTENAME(tc.TABLE_NAME) [ParentId],
            tc.CONSTRAINT_NAME [Name],
            tc.CONSTRAINT_TYPE [ConstraintType],
            CAST(CASE tc.IS_DEFERRABLE
                WHEN &apos;NO&apos; THEN 0
                ELSE 1
            END AS bit) [IsDeferrable],
            CAST(CASE tc.INITIALLY_DEFERRED
                WHEN &apos;NO&apos; THEN 0
                ELSE 1
            END AS bit) [IsInitiallyDeferred]
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
        WHERE tc.TABLE_NAME IS NOT NULL) AS [Extent4]
    INNER JOIN (
        SELECT
            7 AS [C1],
            [Extent5].[ConstraintId] AS [ConstraintId],
            [Extent6].[Id] AS [Id]
        FROM (
            SELECT
                QUOTENAME(CONSTRAINT_SCHEMA) + QUOTENAME(CONSTRAINT_NAME) [ConstraintId],
                QUOTENAME(TABLE_SCHEMA) + QUOTENAME(TABLE_NAME) + QUOTENAME(COLUMN_NAME) [ColumnId]
            FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE) AS [Extent5]
        INNER JOIN (
            SELECT
                QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id],
                QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId],
                c.COLUMN_NAME [Name],
                c.ORDINAL_POSITION [Ordinal],
                CAST(CASE c.IS_NULLABLE
                    WHEN &apos;YES&apos; THEN 1
                    WHEN &apos;NO&apos; THEN 0
                    ELSE 0
                END AS bit) [IsNullable],
                CASE
                    WHEN c.DATA_TYPE IN (&apos;varchar&apos;, &apos;nvarchar&apos;, &apos;varbinary&apos;) AND
                        c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + &apos;(max)&apos;
                    ELSE c.DATA_TYPE
                END
                AS [TypeName],
                c.CHARACTER_MAXIMUM_LENGTH [MaxLength],
                CAST(c.NUMERIC_PRECISION AS integer) [Precision],
                CAST(c.DATETIME_PRECISION AS integer) [DateTimePrecision],
                CAST(c.NUMERIC_SCALE AS integer) [Scale],
                c.COLLATION_CATALOG [CollationCatalog],
                c.COLLATION_SCHEMA [CollationSchema],
                c.COLLATION_NAME [CollationName],
                c.CHARACTER_SET_CATALOG [CharacterSetCatalog],
                c.CHARACTER_SET_SCHEMA [CharacterSetSchema],
                c.CHARACTER_SET_NAME [CharacterSetName],
                CAST(0 AS bit) AS [IsMultiSet],
                CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsIdentity&apos;) AS bit) AS [IsIdentity],
                CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsComputed&apos;) | CASE
                    WHEN c.DATA_TYPE = &apos;timestamp&apos; THEN 1
                    ELSE 0
                END AS bit) AS [IsStoreGenerated],
                c.COLUMN_DEFAULT AS [Default]
            FROM INFORMATION_SCHEMA.COLUMNS c
            INNER JOIN INFORMATION_SCHEMA.TABLES t
                ON c.TABLE_CATALOG = t.TABLE_CATALOG
                AND c.TABLE_SCHEMA = t.TABLE_SCHEMA
                AND c.TABLE_NAME = t.TABLE_NAME
                AND t.TABLE_TYPE = &apos;BASE TABLE&apos;) AS [Extent6]
            ON [Extent6].[Id] = [Extent5].[ColumnId]
        UNION ALL
        SELECT
            11 AS [C1],
            [Extent7].[ConstraintId] AS [ConstraintId],
            [Extent8].[Id] AS [Id]
        FROM (
            SELECT
                CAST(NULL AS nvarchar(1)) [ConstraintId],
                CAST(NULL AS nvarchar(max)) [ColumnId]
            WHERE 1 = 2) AS [Extent7]
        INNER JOIN (
            SELECT
                QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id],
                QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId],
                c.COLUMN_NAME [Name],
                c.ORDINAL_POSITION [Ordinal],
                CAST(CASE c.IS_NULLABLE
                    WHEN &apos;YES&apos; THEN 1
                    WHEN &apos;NO&apos; THEN 0
                    ELSE 0
                END AS bit) [IsNullable],
                CASE
                    WHEN c.DATA_TYPE IN (&apos;varchar&apos;, &apos;nvarchar&apos;, &apos;varbinary&apos;) AND
                        c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + &apos;(max)&apos;
                    ELSE c.DATA_TYPE
                END
                AS [TypeName],
                c.CHARACTER_MAXIMUM_LENGTH [MaxLength],
                CAST(c.NUMERIC_PRECISION AS integer) [Precision],
                CAST(c.DATETIME_PRECISION AS integer) AS [DateTimePrecision],
                CAST(c.NUMERIC_SCALE AS integer) [Scale],
                c.COLLATION_CATALOG [CollationCatalog],
                c.COLLATION_SCHEMA [CollationSchema],
                c.COLLATION_NAME [CollationName],
                c.CHARACTER_SET_CATALOG [CharacterSetCatalog],
                c.CHARACTER_SET_SCHEMA [CharacterSetSchema],
                c.CHARACTER_SET_NAME [CharacterSetName],
                CAST(0 AS bit) AS [IsMultiSet],
                CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsIdentity&apos;) AS bit) AS [IsIdentity],
                CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + &apos;.&apos; + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, &apos;IsComputed&apos;) | CASE
                    WHEN c.DATA_TYPE = &apos;timestamp&apos; THEN 1
                    ELSE 0
                END AS bit) AS [IsStoreGenerated],
                c.COLUMN_DEFAULT [Default]
            FROM INFORMATION_SCHEMA.COLUMNS c
            INNER JOIN INFORMATION_SCHEMA.VIEWS v
                ON c.TABLE_CATALOG = v.TABLE_CATALOG
                AND c.TABLE_SCHEMA = v.TABLE_SCHEMA
                AND c.TABLE_NAME = v.TABLE_NAME
            WHERE NOT (v.TABLE_SCHEMA = &apos;dbo&apos;
            AND v.TABLE_NAME IN (&apos;syssegments&apos;, &apos;sysconstraints&apos;)
            AND SUBSTRING(CAST(SERVERPROPERTY(&apos;productversion&apos;) AS varchar(20)), 1, 1) = 8)) AS [Extent8]
            ON [Extent8].[Id] = [Extent7].[ColumnId]) AS [UnionAll2]
        ON (7 = [UnionAll2].[C1])
        AND ([Extent4].[Id] = [UnionAll2].[ConstraintId])
    WHERE [Extent4].[ConstraintType] = N&apos;PRIMARY KEY&apos;) AS [Project5]
    ON [UnionAll1].[Id] = [Project5].[C1]
WHERE [Extent1].[Name] LIKE N&apos;%&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This query executes for almost 7 minutes to retrieve 491 rows of schema info:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is too long running. After trying around, the only working solution is to &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb933794.aspx&quot;&gt;change&lt;/a&gt; SQL Server 2014 SP! database’s default &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb510680.aspx&quot;&gt;compatibility mode&lt;/a&gt; (120) to SQL Server 2012 (110):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER DATABASE [AdventureWorks2014]
SET COMPATIBILITY_LEVEL = 110;
GO

SELECT compatibility_level
FROM sys.databases WHERE name = N&apos;AdventureWorks2014&apos;;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then above schema query executes in 8 seconds:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/2458277efd49_7AB8/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Disregarding this long running query execution as &lt;a href=&quot;https://entityframework.codeplex.com/workitem/2445&quot;&gt;a regression&lt;/a&gt;, at least in Entity Model Wizard, the UI thread should not be used to execute the query, which causes Visual Studio frozen.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (8) Transactions</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-8-transactions/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-8-transactions/</guid><description>As discussed above, by default DbContext.SaveChanges execute all data creation, update and deletion in a transaction, so that all the work can succeed or fail as a unit. The following example tries to</description><pubDate>Wed, 10 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As discussed above, by default DbContext.SaveChanges execute all data creation, update and deletion in a transaction, so that all the work can succeed or fail as a unit. The following example tries to update 2 entities, so there will be 2 UPDATE statements in the transaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Transactions
{
    internal static void Default()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            ProductCategory category = adventureWorks.ProductCategories.First();
            category.Name = &quot;Update&quot;; // Valid value.
            ProductSubcategory subcategory = adventureWorks.ProductSubcategories.First();
            subcategory.ProductCategoryID = -1; // Invalid value.
            try
            {
                adventureWorks.SaveChanges();
            }
            catch (DbUpdateException exception)
            {
                Trace.WriteLine(exception);
                // System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
                // ---&amp;gt; System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. 
                // ---&amp;gt; System.Data.SqlClient.SqlException: The UPDATE statement conflicted with the FOREIGN KEY constraint &quot;FK_ProductSubcategory_ProductCategory_ProductCategoryID&quot;. The conflict occurred in database &quot;D:\ONEDRIVE\WORKS\DRAFTS\CODESNIPPETS\DATA\ADVENTUREWORKS_DATA.MDF&quot;, table &quot;Production.ProductCategory&quot;, column &apos;ProductCategoryID&apos;. The statement has been terminated.
                adventureWorks.Entry(category).Reload();
                Trace.WriteLine(category.Name); // Accessories
                adventureWorks.Entry(subcategory).Reload();
                Trace.WriteLine(subcategory.ProductCategoryID); // 1
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The category entity has valid properties, so its UPDATE statement executes successfully. The subcategory has a invalid foreign key value, so tis UPDATE statement fails. As a result, Entity Framework rollbacks the entire session, and throws DbUpdateException. Then, if querying these 2 entities again, they both have the original property values before update. In this example, there are 6 SQL statements in total: 2 SELECT statements to query entities, 2 UPDATE statements in a transaction, and 2 SELECT statements to query the entities again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) 
    [c].[ProductCategoryID] AS [ProductCategoryID], 
    [c].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [c]

SELECT TOP (1) 
    [c].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [c].[Name] AS [Name], 
    [c].[ProductCategoryID] AS [ProductCategoryID]
    FROM [Production].[ProductSubcategory] AS [c]

BEGIN TRANSACTION
    exec sp_executesql N&apos;UPDATE [Production].[ProductCategory]
    SET [Name] = @0
    WHERE ([ProductCategoryID] = @1)
    &apos;,N&apos;@0 nvarchar(50),@1 int&apos;,@0=N&apos;Update&apos;,@1=4

    exec sp_executesql N&apos;UPDATE [Production].[ProductSubcategory]
    SET [ProductCategoryID] = @0
    WHERE ([ProductSubcategoryID] = @1)
    &apos;,N&apos;@0 int,@1 int&apos;,@0=-1,@1=1
ROLLBACK TRANSACTION

SELECT TOP (1) 
    [c].[ProductCategoryID] AS [ProductCategoryID], 
    [c].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [c]

SELECT TOP (1) 
    [c].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [c].[ProductCategoryID] AS [ProductCategoryID], 
    [c].[Name] AS [Name]
    FROM [Production].[ProductSubcategory] AS [c]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DbContextTransaction&lt;/h2&gt;
&lt;p&gt;In Entity Framework, there are some options to customize or control the transaction. Database.BeginTransaction method can start a transaction, and returns a System.Data.Entity.DbContextTransaction object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Transactions
{
    internal static void DbContextTransaction()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        using (DbContextTransaction transaction = adventureWorks.Database.BeginTransaction(
            IsolationLevel.ReadUncommitted))
        {
            try
            {
                Trace.WriteLine(adventureWorks.QueryCurrentIsolationLevel()); // ReadUncommitted

                ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                adventureWorks.ProductCategories.Add(category);
                Trace.WriteLine(adventureWorks.SaveChanges()); // 1

                Trace.WriteLine(adventureWorks.Database.ExecuteSqlCommand(
                    &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = {0}&quot;,
                    nameof(ProductCategory))); // 1
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling Database.BeginTransaction, the transaction’s &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms189122.aspx&quot;&gt;isolation level&lt;/a&gt; can be optionally specified. If an isolation level is not provided for BeginTransaction, it will be read committed by default. Here BeginTransaction is called with System.Data.IsolationLevel.ReadUncommitted, the lowest isolation level. Internally, Entity Framework calls ADO.NET to start the transaction, and ADO.NET converts IsolationLevel enumeration to System.Data.SqlClient.TdsEnums.TransactionManagerIsolationLevel enumeration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.SqlClient
{
    internal static class TdsEnums
    {
        internal enum TransactionManagerIsolationLevel
        {
            Unspecified, // 0
            ReadUncommitted, // 1
            ReadCommitted, // 2
            RepeatableRead, // 3
            Serializable, // 4
            Snapshot // 5
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then value 3 (ReadUncommitted) is written to a packet (represented by System.Data.SqlClient.SNIPacket class), and sent to SQL database via TDS protocol. There is no SQL statement like &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms173763.aspx&quot;&gt;SET TRANSACTION ISOLATION LEVEL&lt;/a&gt; executed, so the actual isolation level cannot be logged by Entity Framework, or traced by SQL Profiler. In above example, QueryCurrentIsolationLevel is called to verify the current transaction’s isolation level. It is an extension method of DbContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public const string CurrentIsolationLevelSql = @&quot;
        SELECT
            CASE transaction_isolation_level
                WHEN 0 THEN N&apos;Unspecified&apos;
                WHEN 1 THEN N&apos;ReadUncommitted&apos;
                WHEN 2 THEN N&apos;ReadCommitted&apos;
                WHEN 3 THEN N&apos;RepeatableRead&apos;
                WHEN 4 THEN N&apos;Serializable&apos;
                WHEN 5 THEN N&apos;Snapshot&apos;
            END
        FROM sys.dm_exec_sessions
        WHERE session_id = @@SPID&quot;;

    public static string QueryCurrentIsolationLevel(this DbContext context)
    {
        context.NotNull(nameof(context));

        return context.Database.SqlQuery&amp;lt;string&amp;gt;(CurrentIsolationLevelSql).Single();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It queries the server-scope view &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms176013.aspx&quot;&gt;sys.dm_exec_sessions&lt;/a&gt; with current session id, which can be retrieved by built-in function &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms189535.aspx&quot;&gt;@@SPID&lt;/a&gt;. As expected, the query result is “ReadUncommitted”. After that, a category entity is created and SaveChanges is called. Entity Framework detects a transaction is explicitly created, so SaveChanges does not involve an individual transaction like all the previous examples. Then Database.ExecuteSqlCommnd is called to delete that category entity. Eventually, to commit the transaction, call DbContextTransaction.Commit, to rollback the transaction, call DbContextTransaction.Rollback. And the complete SQL execution is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION
    SELECT         
        CASE transaction_isolation_level
            WHEN 0 THEN N&apos;Unspecified&apos;
            WHEN 1 THEN N&apos;ReadUncommitted&apos;
            WHEN 2 THEN N&apos;ReadCommitted&apos;
            WHEN 3 THEN N&apos;RepeatableRead&apos;
            WHEN 4 THEN N&apos;Serializable&apos;
            WHEN 5 THEN N&apos;Snapshot&apos;
        END
    FROM sys.dm_exec_sessions
    WHERE session_id = @@SPID

    exec sp_executesql N&apos;INSERT [Production].[ProductCategory]([Name])
    VALUES (@0)
    SELECT [ProductCategoryID]
    FROM [Production].[ProductCategory]
    WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductCategoryID] = scope_identity()&apos;,N&apos;@0 nvarchar(50)&apos;,@0=N&apos;ProductCategory&apos;

    exec sp_executesql N&apos;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&apos;,N&apos;@p0 nvarchar(15)&apos;,@p0=N&apos;ProductCategory&apos;
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DbTransaction&lt;/h2&gt;
&lt;p&gt;Besides creating a transaction explicitly, Entity Framework can also use an existing ADO.NET transaction, represented by System.Data.Common.DbTransaction class. Such a DbTransaction object can be created by calling DbConnection.BeginTransaction, so an existing DbConnection object will be used here. To have Entity Framework use an existing connection as well, add a constructor for AdventureWorks class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class AdventureWorks
{
    public AdventureWorks(DbConnection connection, bool contextOwnsConnection = false)
        : base(connection, contextOwnsConnection)
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the DbContext can use an existing connection by calling above constructor, and it can use an existing transaction by calling Database.UseTransaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DbTransaction()
{
    using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
    {
        connection.Open();
        using (DbTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
        {
            try
            {
                using (AdventureWorks adventureWorks = new AdventureWorks(connection))
                {
                    adventureWorks.Database.UseTransaction(transaction);
                    Trace.WriteLine(adventureWorks.QueryCurrentIsolationLevel()); // Serializable

                    ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
                    adventureWorks.ProductCategories.Add(category);
                    Trace.WriteLine(adventureWorks.SaveChanges()); // 1.
                }

                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
                    DbParameter parameter = command.CreateParameter();
                    parameter.ParameterName = &quot;@p0&quot;;
                    parameter.Value = nameof(ProductCategory);
                    command.Parameters.Add(parameter);
                    command.Transaction = transaction;
                    Trace.WriteLine(command.ExecuteNonQuery()); // 1
                }
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, an DbConnection object is explicitly constructed. Similar to Database.BeginTransaction, DbConnection.BeginTransaction starts a transaction, and returns a DbTransaction object. Isolation level can be optionally provided to DbConnection.BeginTransaction as well. Here Serializable is specified, which is the highest isolation level. After that, DbContext uses the existing connection and transaction to verify current session’s isolation level, and create a category object. DbContext knows an existing transaction is used, so SaveChanges does not start an individual transaction. Then the connection is used again to execute a DbCommand to delete the category entity. Similar to DbContextTransaction again, eventually just call DbTransaction.Commit to commit the transaction, or call DbTransaction.Rollback to rollback. Here the executed SQL is exactly the same as previous DbContextTransaction example.&lt;/p&gt;
&lt;h2&gt;TransactionScope&lt;/h2&gt;
&lt;p&gt;The DbContextTransaction object only work with its source DbContext object, and DbTransaction object only work with its source DbConnection object. .NET provides System.Transactions.TransactionScope to work across the lifecycle of multiple DbContext or DbConnection objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void TransactionScope()
{
    using (TransactionScope scope = new TransactionScope(
        TransactionScopeOption.Required,
        new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead }))
    {
        using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = DbContextExtensions.CurrentIsolationLevelSql;
            connection.Open();
            using (DbDataReader reader = command.ExecuteReader())
            {
                reader.Read();
                Trace.WriteLine(reader[0]); // RepeatableRead
            }
        }

        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
            adventureWorks.ProductCategories.Add(category);
            Trace.WriteLine(adventureWorks.SaveChanges()); // 1
        }

        using (DbConnection connection = new SqlConnection(ConnectionStrings.AdventureWorks))
        using (DbCommand command = connection.CreateCommand())
        {
            command.CommandText = &quot;DELETE FROM [Production].[ProductCategory] WHERE [Name] = @p0&quot;;
            DbParameter parameter = command.CreateParameter();
            parameter.ParameterName = &quot;@p0&quot;;
            parameter.Value = nameof(ProductCategory);
            command.Parameters.Add(parameter);

            connection.Open();
            Trace.WriteLine(command.ExecuteNonQuery()); // 1
        }

        scope.Complete();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When constructing TransactionScope, the isolation level is specified to be RepeatableRead. Unlike DbContextTransaction or DbTransaction, TransactionScope’s default isolation level is Serializable, if not specified. When SaveChanges is called, it detects the ambient transaction by calling System.Transactions.Transaction.Current, so it does not start an individual transaction. Here the executed SQL is the same as previous examples. TransactionScope can also be used with async programming, which will be discussed later.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (9) Optimistic Concurrency</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-9-optimistic-concurrency/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-9-optimistic-concurrency/</guid><description>Conflicts can occur if the same piece of data is read and changed concurrently. Generally, there are 2  approaches:</description><pubDate>Wed, 10 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-8-optimistic-concurrency&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Conflicts can occur if the same piece of data is read and changed concurrently. Generally, there are 2 &lt;a href=&quot;https://en.wikipedia.org/wiki/Concurrency_control&quot;&gt;concurrency control&lt;/a&gt; approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pessimistic concurrency: one database client can lock the data being accessed, in order to prevent other database clients to change that data concurrently. Entity Framework does not have built-in support for this approach.&lt;/li&gt;
&lt;li&gt;Optimistic concurrency: This is how Entity Framework works with database. No data is locked in the database for CRUD. Any database client is allowed to read and change any data concurrently. As a result, concurrency conflict can happen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate Entity Framework’s behavior for concurrency, the following DbReaderWriter class is defined as database CRUD client:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter : IDisposable
{
    private readonly DbContext context;

    internal DbReaderWriter(DbContext context)
    {
        this.context = context;
    }

    internal TEntity Read&amp;lt;TEntity&amp;gt;
        (params object[] keys) where TEntity : class =&amp;gt; this.context.Set&amp;lt;TEntity&amp;gt;().Find(keys);

    internal int Write(Action change)
    {
        change();
        return this.context.SaveChanges();
    }

    internal DbSet&amp;lt;TEntity&amp;gt; Set&amp;lt;TEntity&amp;gt;() where TEntity : class =&amp;gt; this.context.Set&amp;lt;TEntity&amp;gt;();

    public void Dispose() =&amp;gt; this.context.Dispose();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple DbReaderWriter objects can be be used to read and write data concurrently.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Concurrency
{
    internal static void NoCheck() // Check no column, last client wins.
    {
        const int id = 1;
        using (DbReaderWriter readerWriter1 = new DbReaderWriter(new AdventureWorks()))
        using (DbReaderWriter readerWriter2 = new DbReaderWriter(new AdventureWorks()))
        {

            ProductCategory category1 = readerWriter1.Read&amp;lt;ProductCategory&amp;gt;(id);
            ProductCategory category2 = readerWriter2.Read&amp;lt;ProductCategory&amp;gt;(id);

            readerWriter1.Write(() =&amp;gt; category1.Name = nameof(readerWriter1));
            readerWriter2.Write(() =&amp;gt; category2.Name = nameof(readerWriter2)); // Win.
        }
        using (DbReaderWriter readerWriter3 = new DbReaderWriter(new AdventureWorks()))
        {
            ProductCategory category3 = readerWriter3.Read&amp;lt;ProductCategory&amp;gt;(id);
            Trace.WriteLine(category3.Name); // readerWriter2
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here 2 DbReaderWriter objects read and write data concurrently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads category with Name “Bikes”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads category with Name “Bikes”. As fore mentioned, these 2 entities are independent 2 objects because they are are from different DbContext objects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 updates category’s Name from “Bikes” to “readerWriter1”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[ProductCategory]
SET [Name] = @0
WHERE ([ProductCategoryID] = @1)
&apos;,N&apos;@0 nvarchar(50),@1 int&apos;,@0=N&apos;readerWriter1&apos;,@1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, in database, this category’s Name is no longer “Bikes”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 updates category’s Name from “Bikes” to “readerWriter2”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[ProductCategory]
SET [Name] = @0
WHERE ([ProductCategoryID] = @1)
&apos;,N&apos;@0 nvarchar(50),@1 int&apos;,@0=N&apos;readerWriter2&apos;,@1=1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As discussed before, by default, when DbContext translates changes to UPDATE statements, primary key is used to locate the row. Apparently, above 2 UPDATE statements can both execute successfully, without concurrency conflict. This is the default behavior of Entity Framework, the last database client wins. So later when readerWriter3 reads the entity with the same primary key, the category entity’s Name is “readerWriter2”.&lt;/p&gt;
&lt;h2&gt;Detect Concurrency conflicts&lt;/h2&gt;
&lt;p&gt;Concurrency conflicts can be detected by checking entities’ property values besides primary keys. To required Entity Framework to check a certain property, just add a System.ComponentModel.DataAnnotations.ConcurrencyCheckAttribute to it. Remember when defining ProductPhoto entity class, its ModifiedDate has a [ConcurrencyCheck] attribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class ProductPhoto
{
    [ConcurrencyCheck]
    public DateTime ModifiedDate { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Entity Framework translate changes of a photo, the ModifiedDate property will be checked too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ConcurrencyCheck()
{
    using (DbReaderWriter readerWriter1 = new DbReaderWriter(new AdventureWorks()))
    using (DbReaderWriter readerWriter2 = new DbReaderWriter(new AdventureWorks()))
    {
        const int id = 1;
        ProductPhoto photoCopy1 = readerWriter1.Read&amp;lt;ProductPhoto&amp;gt;(id);
        ProductPhoto photoCopy2 = readerWriter2.Read&amp;lt;ProductPhoto&amp;gt;(id);

        readerWriter1.Write(() =&amp;gt;
        {
            photoCopy1.LargePhotoFileName = nameof(readerWriter1);
            photoCopy1.ModifiedDate = DateTime.Now;
        });
        readerWriter2.Write(() =&amp;gt;
        {
            photoCopy2.LargePhotoFileName = nameof(readerWriter2);
            photoCopy2.ModifiedDate = DateTime.Now;
        });
        // System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0).Entities may have been modified or deleted since entities were loaded.See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions. 
        // ---&amp;gt; System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0).Entities may have been modified or deleted since entities were loaded.See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the translated SQL statement, the WHERE clause contains primary key ProductID and also original ModifiedDate value:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads product with ModifiedDate “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads product with ModifiedDate “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates the product with primary key and ModifiedDate, and update its Name and ModifiedDate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[ProductPhoto]
SET [LargePhotoFileName] = @0, [ModifiedDate] = @1
WHERE (([ProductPhotoID] = @2) AND ([ModifiedDate] = @3))
&apos;,N&apos;@0 nvarchar(50),@1 datetime2(7),@2 int,@3 datetime2(7)&apos;,@0=N&apos;readerWriter1&apos;,@1=&apos;2016-07-04 23:24:24.6053455&apos;,@2=1,@3=&apos;2008-04-30 00:00:00&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, in database the product’s ModifiedDate is no longer “2008-04-30 00:00:00”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then readerWriter2 tries to locate the product with primary key and ModifiedDate, and update its Name and ModifiedDate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[ProductPhoto]
SET [LargePhotoFileName] = @0, [ModifiedDate] = @1
WHERE (([ProductPhotoID] = @2) AND ([ModifiedDate] = @3))
&apos;,N&apos;@0 nvarchar(50),@1 datetime2(7),@2 int,@3 datetime2(7)&apos;,@0=N&apos;readerWriter1&apos;,@1=&apos;2016-07-04 23:24:24.6293420&apos;,@2=1,@3=&apos;2008-04-30 00:00:00&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This time readerWriter2 fails. Between readerWriter2 reads and writers a photo, this photo is changed by readerWriter1. So in readerWrtier2’s UPDATE statement cannot locate any row to update. Entity Framework detects that 0 row is updated, and throws System.Data.Entity.Infrastructure.DbUpdateConcurrencyException.&lt;/p&gt;
&lt;p&gt;Another API for concurrency check is System.ComponentModel.DataAnnotations.TimestampAttribute. It can only be used for a byte[] property, which maps to a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms182776.aspx&quot;&gt;rowversion&lt;/a&gt; (timestamp) column. For SQL database, these 2 terms rowversion and timestamp are the same thing. Timestamp is just a &lt;a href=&quot;https://technet.microsoft.com/en-us/library/ms177566.aspx&quot;&gt;synonym&lt;/a&gt; of rowversion data type. A row’s non nullable rowversion column is a 8 bytes (binary(8)) counter maintained by database, its value increases for each change of the row.&lt;/p&gt;
&lt;p&gt;Microsoft’s AdventureWorks sample database does not have such a rowversion column, so create one for the [Production].[Product] table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER TABLE [Production].[Product] ADD [RowVersion] rowversion NOT NULL
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add the mapping property to Product entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Timestamp]
    public byte[] RowVersion { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example update and and delete the same entity concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void RowVersion()
{
    using (DbReaderWriter readerWriter1 = new DbReaderWriter(new AdventureWorks()))
    using (DbReaderWriter readerWriter2 = new DbReaderWriter(new AdventureWorks()))
    {
        const int id = 999;
        Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
        Trace.WriteLine(productCopy1.RowVersion.ToRowVersionString()); // 0x0000000000000803
        Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
        Trace.WriteLine(productCopy2.RowVersion.ToRowVersionString()); // 0x0000000000000803

        readerWriter1.Write(() =&amp;gt; productCopy1.Name = nameof(readerWriter1));
        Trace.WriteLine(productCopy1.RowVersion.ToRowVersionString()); // 0x00000000000324B1
        readerWriter2.Write(() =&amp;gt; readerWriter2.Set&amp;lt;Product&amp;gt;().Remove(productCopy2));
        // System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
        // ---&amp;gt; System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above ToRowVersionString is an extension method to get a readable string representation from a rowversion, which is an array of 8 System.Byte values in .NET:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string ToRowVersionString(this byte[] rowVersion) =&amp;gt;
    $&quot;0x{BitConverter.ToString(rowVersion).Replace(&quot;-&quot;, string.Empty)}&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When updating and deleting photo entities, its auto generated RowVersion property value is checked too. So this is how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 reads photo with RowVersion 0x0000000000000803&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads photo with RowVersion 0x0000000000000803&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates the photo with primary key and RowVersion, and update its RowVersion. Regarding database will automatically increase the RowVersion value, Entity Framework also queries the increased RowVersion value with the primary key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[Product]
SET [Name] = @0
WHERE (([ProductID] = @1) AND ([RowVersion] = @2))
SELECT [RowVersion]
FROM [Production].[Product]
WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductID] = @1&apos;,N&apos;@0 nvarchar(50),@1 int,@2 binary(8)&apos;,@0=N&apos;readerWriter1&apos;,@1=999,@2=0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this moment, in database the product’s RowVersion is no longer 0x0000000000000803.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then readerWriter2 tries to locate the product with primary key and RowVersion, and delete it&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;DELETE [Production].[Product]
WHERE (([ProductID] = @0) AND ([RowVersion] = @1))&apos;,N&apos;@0 int,@1 binary(8)&apos;,@0=999,@1=0x0000000000000803
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The deletion fails because the concurrent update changes the RowVersion, and the row cannot be located with the primary key and RowVersion. Again, Entity Framework detects 0 row is deleted, and throws DbUpdateConcurrencyException.&lt;/p&gt;
&lt;h2&gt;Resolve concurrency conflicts&lt;/h2&gt;
&lt;p&gt;As fore mentioned, when SaveChanges detects concurrency conflict, it throws DbUpdateConcurrencyException:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure
{
    using System.Collections.Generic;

    public class DbUpdateException : DataException
    {
        public IEnumerable&amp;lt;DbEntityEntry&amp;gt; Entries { get; }
    }

    public class DbUpdateConcurrencyException : DbUpdateException
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbUpdateConcurrencyException has an Entries property, inherited from DbUpdateException. Entries returns a sequence of DbEntityEntry objects, representing the conflicting entities’ tracking information.&lt;/p&gt;
&lt;p&gt;So the basic idea of resolving concurrency conflicts, is to handle DbUpdateConcurrencyException and retry SaveChanges:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int Write(Action change, Action&amp;lt;IEnumerable&amp;lt;DbEntityEntry&amp;gt;&amp;gt; handleDbUpdateConcurrencyException, int retryCount = 3)
    {
        change();
        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return this.context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception)
            {
                handleDbUpdateConcurrencyException(exception.Entries);
            }
        }
        return this.context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above Write overload, if SaveChanges throws DbUpdateConcurrencyException, the handleDbUpdateConcurrencyException function is called. This function is expected to handle the exception and resolve the conflicts properly. Then SaveChanges is called again. If the last retry of SaveChanges still throws DbUpdateConcurrencyException, the exception is not caught or handled here, but thrown to the caller of Write.&lt;/p&gt;
&lt;h3&gt;Retain database values (database wins)&lt;/h3&gt;
&lt;p&gt;Similar to previous examples, the following example constructs 2 DbReaderWriter objects to update a product concurrently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UpdateProduct(Action&amp;lt;DbEntityEntry&amp;gt; resolveProductConflict)
{
    const int id = 950;
    using (DbReaderWriter readerWriter1 = new DbReaderWriter(new AdventureWorks()))
    using (DbReaderWriter readerWriter2 = new DbReaderWriter(new AdventureWorks()))
    {
        Product productCopy1 = readerWriter1.Read&amp;lt;Product&amp;gt;(id);
        Product productCopy2 = readerWriter2.Read&amp;lt;Product&amp;gt;(id);
        readerWriter1.Write(() =&amp;gt;
            {
                productCopy1.Name = nameof(readerWriter1);
                productCopy1.ListPrice = 100;
            });
        readerWriter2.Write(
            change: () =&amp;gt;
                {
                    productCopy2.Name = nameof(readerWriter2);
                    productCopy2.ProductSubcategoryID = 1;
                },
            handleDbUpdateConcurrencyException: exception =&amp;gt;
                {
                    // Logging.
                    DbEntityEntry tracking = exception.Entries.Single();
                    Product original = (Product)tracking.OriginalValues.ToObject();
                    Product updateTo = (Product)tracking.CurrentValues.ToObject();
                    Product database = productCopy1; // Values saved in database.

                    Trace.WriteLine(
                        $&quot;Original:  ({original.Name},   {original.ListPrice}, {original.ProductSubcategoryID}, {original.RowVersion.ToRowVersionString()})&quot;);
                    Trace.WriteLine(
                        $&quot;Database:  ({database.Name}, {database.ListPrice}, {database.ProductSubcategoryID}, {database.RowVersion.ToRowVersionString()})&quot;);
                    Trace.WriteLine(
                        $&quot;Update to: ({updateTo.Name}, {updateTo.ListPrice}, {updateTo.ProductSubcategoryID})&quot;);

                    // Resolve product conflict.
                    resolveProductConflict(tracking);
                });
    }

    using (DbReaderWriter readerWriter3 = new DbReaderWriter(new AdventureWorks()))
    {
        Product resolved = readerWriter3.Read&amp;lt;Product&amp;gt;(id);
        Trace.WriteLine(
            $&quot;Resolved:  ({resolved.Name}, {resolved.ListPrice}, {resolved.ProductSubcategoryID}, {resolved.RowVersion.ToRowVersionString()})&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the concurrency conflict happens:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 reads product, the RowVersion is 0x00000000000007D1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter1 locates product with primary key ProductID and original RowVersion 0x00000000000007D1, and updates product’s Name and ListPrice. After the update, in database, product’s Rowversion is increased to 0x0000000000036335&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[Product]
SET [Name] = @0, [ListPrice] = @1
WHERE (([ProductID] = @2) AND ([RowVersion] = @3))
SELECT [RowVersion]
FROM [Production].[Product]
WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductID] = @2&apos;,N&apos;@0 nvarchar(50),@1 decimal(18,2),@2 int,@3 binary(8)&apos;,@0=N&apos;readerWriter1&apos;,@1=100.00,@2=950,@3=0x00000000000007D1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 tries to locate product with primary key and original RowVersion 0x00000000000007D1, and update product’s Name and ProductSubcategoryID.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[Product]
SET [Name] = @0, [ProductSubcategoryID] = @1
WHERE (([ProductID] = @2) AND ([RowVersion] = @3))
SELECT [RowVersion]
FROM [Production].[Product]
WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductID] = @2&apos;,N&apos;@0 nvarchar(50),@1 int,@2 int,@3 binary(8)&apos;,@0=N&apos;readerWriter2&apos;,@1=1,@2=950,@3=0x00000000000007D1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;readerWriter2 fails to update product, because it cannot locate the product with original RowVersion 0x00000000000007D1. In ReaderWriter.Write, SaveChanges throws handleDbUpdateConcurrencyException.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a result, the provided handleDbUpdateConcurrencyException function is called, it retrieves the conflicting product’s tracking information from DbUpdateConcurrencyException.Entries, and logs these information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;product’s original property values, which are read by readerWriter2&lt;/li&gt;
&lt;li&gt;product’s property values in database, which are already updated to database by readerWriter1 at this moment&lt;/li&gt;
&lt;li&gt;product’s current property values, which should be updated to database by readerWriter2, but failed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then it calls resolveProductConflict function to actually resolve the conflict.&lt;/p&gt;
&lt;p&gt;After these are done, DbReaderWriter.Write’s retry logic calls SaveChanges again. This time, SaveChanges should succeed, becuase there is no conflict anymore (In this example, there are only 2 database clients reading/writing data concurrently. In reality, the concurrency can be higher, an appropriate retry count or retry strategy should be specified.). Eventually, readerWriter3 reads the product from database, verify its property values after 2 concurrent updates.&lt;/p&gt;
&lt;p&gt;So the question is, how should resolveProductConflict function resolve the conflict? One simple option, called “database wins”, is to give up the client update, and let database retain whatever values it has for that entity. This seems to be easy – just catch DbUpdateConcurrencyException and do nothing, then database naturally wins, and retains its values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal partial class DbReaderWriter
{
    internal int WriteDatabaseWins(Action change)
    {
        change();
        try
        {
            return this.context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            return 0;
            // this.context is in a corrupted state.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, handling conflict with this approach can leave the DbContext, the entity to update, and the entity’s tracking information in a corrupted state. For the caller, since the change saving is done, the entity’s property values should be in sync with database values, but the values can be out of sync and still conflicting. Also, an entity to update has a tracking state Modified, after change saving is done, its tracking state can be still Modified. A much safer approach is to reload and refresh the entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DatabaseWins() =&amp;gt;
    UpdateProduct(resolveProductConflict: tracking =&amp;gt;
        {
            Trace.WriteLine(tracking.State); // Modified
            Trace.WriteLine(tracking.Property(nameof(Product.Name)).IsModified); // True
            Trace.WriteLine(tracking.Property(nameof(Product.ListPrice)).IsModified); // False
            Trace.WriteLine(tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified); // True

            tracking.Reload();

            Trace.WriteLine(tracking.State); // Unchanged
            Trace.WriteLine(tracking.Property(nameof(Product.Name)).IsModified); // False
            Trace.WriteLine(tracking.Property(nameof(Product.ListPrice)).IsModified); // False
            Trace.WriteLine(tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified); // False
        });
// Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
// Database:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
// Update to: (readerWriter2, 256.4900, 1)
// Resolved:  (readerWriter1, 100.0000, 8, 0x0000000000036335)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UpdateProduct is called with a resolveProductConflict function, which resolves the conflict by calling Reload method on the DbEntityEntry object representing the conflicting product’s tracking information:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;As fore mentioned, DbEntityEntry.Reload executes a SELECT statement to read the product’s property values from database&lt;/li&gt;
&lt;li&gt;Reload also refresh the product entity and all tracking information:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;product entity’s property values are refreshed to the queried database values&lt;/li&gt;
&lt;li&gt;the tracked original property values, represented by tracking.OriginalValues, are refreshed to the queried database values&lt;/li&gt;
&lt;li&gt;the tracked current property values, represented by tracking.CurrentValues, are refreshed to the queried database values&lt;/li&gt;
&lt;li&gt;tracking.State is also refreshed to Unchanged.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;At this moment, product entity is refurnished, as if it is just initially read from database.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, no changed entity is detected. SaveChanges succeeds without executing any SQL, and returns 0. As a result, readerWriter2 gives up updating any value to database, and whatever values in database are retained.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has database values, with Name and ListPrice updated by readerWrtier1.&lt;/p&gt;
&lt;h3&gt;Overwrite database values (client wins)&lt;/h3&gt;
&lt;p&gt;Another simple option, called “client wins”, is to disregard values in database, and overwrite them with whatever data submitted from client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ClientWins() =&amp;gt;
    UpdateProduct(resolveProductConflict: tracking =&amp;gt;
        {
            DbPropertyValues databaseValues = tracking.GetDatabaseValues();
            // Refresh original values, which go to WHERE clause.
            tracking.OriginalValues.SetValues(databaseValues);

            Trace.WriteLine(tracking.State); // Modified
            Trace.WriteLine(tracking.Property(nameof(Product.Name)).IsModified); // True
            Trace.WriteLine(tracking.Property(nameof(Product.ListPrice)).IsModified); // True
            Trace.WriteLine(tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified); // True
        });
// Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
// Database:  (readerWriter1, 100.0000, 8, 0x0000000000036336)
// Update to: (readerWriter2, 256.4900, 1)
// Resolved:  (readerWriter2, 256.4900, 1, 0x0000000000036337)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same conflict is resolved differently:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;As fore mentioned, DbEntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database, and it does not impact the product entity or its tracking information. At this moment, since readerWriter2 updated product’s Name and ProductSubcategoryID, these 2 properties are still tracked as modified, and ListPrice is still tracked as unmodified.&lt;/li&gt;
&lt;li&gt;Manually refresh conflict.OriginalValues, the tracked original property values, to the queried database values.&lt;/li&gt;
&lt;li&gt;At this moment, tracking.State is still Modified. However, for the Name, ListPrice and ProductSubcategoryID properties of product, their values in tracking.OriginalValues are different from the values in tracking.CurrentValue. Now these 3 properties are all tracked as modified.&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, product entity is detected to be updated. So Entity Framework translates the product change to a UPDATE statement. In the SET clause, since there are 3 properties tracked as modified, 3 columns are set. In the WHERE clause to locate the product with primary key and RowVersion again, and the RowVersion property value in updated tracking.OriginalValues is used. This time product can be located, and all 3 properties are updated. SaveChanges succeeds and returns 1&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[Product]
SET [Name] = @0, [ListPrice] = @1, [ProductSubcategoryID] = @2
WHERE (([ProductID] = @3) AND ([RowVersion] = @4))
SELECT [RowVersion]
FROM [Production].[Product]
WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductID] = @3&apos;,N&apos;@0 nvarchar(50),@1 decimal(18,2),@2 int,@3 int,@4 binary(8)&apos;,@0=N&apos;readerWriter2&apos;,@1=256.49,@2=1,@3=950,@4=0x0000000000036336
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product again, product has the Name, ListPrice and ProductSubcategoryID values from readerWrter2, their database values are overwritten.&lt;/p&gt;
&lt;h3&gt;Merge with database values&lt;/h3&gt;
&lt;p&gt;A more complex option, is to merge the client values and database values. For each property:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If original value is different from database value, which means database value is already updated by other concurrent client, then give up updating this property, and retain the database value&lt;/li&gt;
&lt;li&gt;If original value is the same as database value, which means no concurrency conflict for this property, then process normally&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static void MergeClientAndDatabase() =&amp;gt;
    UpdateProduct(resolveProductConflict: tracking =&amp;gt;
        {
            DbPropertyValues databaseValues = tracking.GetDatabaseValues();
            DbPropertyValues originalValues = tracking.OriginalValues.Clone();
            // Refresh original values, which go to WHERE clause.
            tracking.OriginalValues.SetValues(databaseValues);
            databaseValues.PropertyNames // Navigation properties are not included.
                // If original value is updated in database,
                .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                // then give up update, and retain the database value.
                .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);

            Trace.WriteLine(tracking.State); // Modified
            Trace.WriteLine(tracking.Property(nameof(Product.Name)).IsModified); // False
            Trace.WriteLine(tracking.Property(nameof(Product.ListPrice)).IsModified); // False
            Trace.WriteLine(tracking.Property(nameof(Product.ProductSubcategoryID)).IsModified); // True
        });
// Original:  (ML Crankset,   256.4900, 8, 0x00000000000007D1)
// Database:  (readerWriter1, 100.0000, 8, 0x0000000000036338)
// Update to: (readerWriter2, 256.4900, 1)
// Resolved:  (readerWriter1, 100.0000, 1, 0x0000000000036339)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Again, DbEntityEntry.GetDatabaseValues executes a SELECT statement to read the product’s property values from database&lt;/li&gt;
&lt;li&gt;Backup tracking.Original values, then refresh conflict.OriginalValues to the database values, so that these values can go to the translated WHERE clause. For Name and ListPrice, the backup original value is different from the database value, which is concurrently updated by readerWriter1. So their property state is refreshed to unmodified, and they will not go to the translated SET clause.&lt;/li&gt;
&lt;li&gt;At this moment, tracking.State is still Modified, but only ProductSubcategoryID does not conflict with database value, and will be updated normally&lt;/li&gt;
&lt;li&gt;When DbReaderWriter.Write’s retry logic calls SaveChanges again, Entity Framework translates the product change to a UPDATE statement, which has refreshed RowVersion in WHERE clause, and only ProductSubcategoryID in SET clause. And SaveChanges should successfully execute and return 1&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;UPDATE [Production].[Product]
SET [ProductSubcategoryID] = @0
WHERE (([ProductID] = @1) AND ([RowVersion] = @2))
SELECT [RowVersion]
FROM [Production].[Product]
WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductID] = @1&apos;,N&apos;@0 int,@1 int,@2 binary(8)&apos;,@0=1,@1=950,@2=0x0000000000036338
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, when readerWriter3 reads the product, product has Name and ListPrice values from readerWrtier1, and ProductSubcategoryID value from readerWriter2.&lt;/p&gt;
&lt;h2&gt;SaveChanges with concurrency conflict handling&lt;/h2&gt;
&lt;p&gt;Similar to above DbReaderWriter.Write method, a general SaveChanges method extension method for DbContext can be defined to handle concurrency conflict and apply simple retry logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;DbEntityEntry&amp;gt;&amp;gt; resolveConflicts, int retryCount = 3)
    {
        context.NotNull(nameof(context));
        resolveConflicts.NotNull(nameof(resolveConflicts));
        Argument.Range(retryCount &amp;gt; 0, $&quot;{retryCount} must be greater than 0.&quot;, nameof(retryCount));

        for (int retry = 1; retry &amp;lt; retryCount; retry++)
        {
            try
            {
                return context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException exception) when (retry &amp;lt; retryCount)
            {
                resolveConflicts(exception.Entries);
            }
        }
        return context.SaveChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To apply custom retry logic, Microsoft &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn440728.aspx&quot;&gt;Exception Handling Application Block&lt;/a&gt; can be used. It is a library providing contracts and implementations for retry logic, and it can be installed from &lt;a href=&quot;https://www.nuget.org/packages/EnterpriseLibrary.TransientFaultHandling/&quot;&gt;Nuget&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-Package EnterpriseLibrary.TransientFaultHandling
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then a SaveChanges overload with customizable retry logic can be defined with the help of this library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TransientDetection&amp;lt;TException&amp;gt; : ITransientErrorDetectionStrategy
    where TException : Exception
{
    public bool IsTransient(Exception ex) =&amp;gt; ex is TException;
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(
        this DbContext context, Action&amp;lt;IEnumerable&amp;lt;DbEntityEntry&amp;gt;&amp;gt; resolveConflicts, RetryStrategy retryStrategy)
    {
        context.NotNull(nameof(context));
        resolveConflicts.NotNull(nameof(resolveConflicts));
        retryStrategy.NotNull(nameof(retryStrategy));

        RetryPolicy retryPolicy = new RetryPolicy(
            new TransientDetection&amp;lt;DbUpdateConcurrencyException&amp;gt;(), retryStrategy);
        retryPolicy.Retrying += (sender, e) =&amp;gt; 
            resolveConflicts(((DbUpdateConcurrencyException)e.LastException).Entries);
        return retryPolicy.ExecuteAction(context.SaveChanges);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ITransientErrorDetectionStrategy is the contract to detect each exception, and determine whether the action should be retried. Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryStrategy is the contract of retry logic. Then Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy executes the action with the specified exception detection, exception handling, and retry logic together.&lt;/p&gt;
&lt;p&gt;As discussed above, to resolve a concurrency conflict, the entity and its tracking information need to be refreshed. So the more specific SaveChanges overloads can be implemented by applying refresh for each conflict:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum RefreshConflict
{
    StoreWins,

    ClientWins,

    MergeClinetAndStore
}

public static partial class DbContextExtensions
{
    public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
    {
        context.NotNull(nameof(context));
        Argument.Range(retryCount &amp;gt; 0, $&quot;{retryCount} must be greater than 0.&quot;, nameof(retryCount));

        return context.SaveChanges(
            conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryCount);
    }

    public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy)
    {
        context.NotNull(nameof(context));
        retryStrategy.NotNull(nameof(retryStrategy));

        return context.SaveChanges(
            conflicts =&amp;gt; conflicts.ForEach(tracking =&amp;gt; tracking.Refresh(refreshMode)), retryStrategy);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Entity Framework already provides a System.Data.Entity.Core.Objects.RefreshMode enumeration, but it only has 2 members: StoreWins and ClientWins. So a RefreshConflict enumeration has to be defined with 3 members. And here the Refresh method is an extension method for DbEntityEntry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class DbEntutyEntryExtensions
{
    public static DbEntityEntry Refresh(this DbEntityEntry tracking, RefreshConflict refreshMode)
    {
        tracking.NotNull(nameof(tracking));

        switch (refreshMode)
        {
            case RefreshConflict.StoreWins:
                {
                    // When entity is already deleted in database, Reload sets tracking state to Detached.
                    // When entity is already updated in database, Reload sets tracking state to Unchanged.
                    tracking.Reload(); // Execute SELECT.
                    // Hereafter, SaveChanges ignores this entity.
                    break;
                }
            case RefreshConflict.ClientWins:
                {
                    DbPropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
                    if (databaseValues == null)
                    {
                        // When entity is already deleted in database, there is nothing for client to win against.
                        // Manually set tracking state to Detached.
                        tracking.State = EntityState.Detached;
                        // Hereafter, SaveChanges ignores this entity.
                    }
                    else
                    {
                        // When entity is already updated in database, refresh original values, which go to in WHERE clause.
                        tracking.OriginalValues.SetValues(databaseValues);
                        // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
                    }
                    break;
                }
            case RefreshConflict.MergeClinetAndStore:
                {
                    DbPropertyValues databaseValues = tracking.GetDatabaseValues(); // Execute SELECT.
                    if (databaseValues == null)
                    {
                        // When entity is already deleted in database, there is nothing for client to merge with.
                        // Manually set tracking state to Detached.
                        tracking.State = EntityState.Detached;
                        // Hereafter, SaveChanges ignores this entity.
                    }
                    else
                    {
                        // When entity is already updated, refresh original values, which go to WHERE clause.
                        DbPropertyValues originalValues = tracking.OriginalValues.Clone();
                        tracking.OriginalValues.SetValues(databaseValues);
                        // If database has an different value for a property, then retain the database value.
                        databaseValues.PropertyNames // Navigation properties are not included.
                            .Where(property =&amp;gt; !object.Equals(originalValues[property], databaseValues[property]))
                            .ForEach(property =&amp;gt; tracking.Property(property).IsModified = false);
                        // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
                    }
                    break;
                }
        }
        return tracking;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Refresh extension method covers the update conflict discussed above, as well as deletion conflict. When the currently entity is already deleted in database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If refresh mode is StoreWins, DbEntityEntry.Load is called. It executes SELECT query. Since no entity can be read, Entity Frmaework knows this entity is already deleted in database. It refreshes the tracking state to Detached. This entity is off the tracking by DbContext. Later when SaveChanges is retried, it ignores this entity.&lt;/li&gt;
&lt;li&gt;If refresh mode is ClientWins or Merge, DbEntityEntry.GetDatabaseValues is called. It executes SELECT query. Since no entity is read, it returns null. In this case, there is nothing for the client to win against or merge with. So entity’s tracking state is manually refreshed to Detached. And when SaveChanges is retried, it ignores this entity too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now the these SaveChanges extension methods can be used to manage concurrent conflict easily. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveChanges()
{
    using (AdventureWorks adventureWorks1 = new AdventureWorks())
    using (AdventureWorks adventureWorks2 = new AdventureWorks())
    {
        const int id = 950;
        Product productCopy1 = adventureWorks1.Products.Find(id);
        Product productCopy2 = adventureWorks2.Products.Find(id);

        productCopy1.Name = nameof(adventureWorks1);
        productCopy1.ListPrice = 100;
        adventureWorks1.SaveChanges();

        productCopy2.Name = nameof(adventureWorks2);
        productCopy2.ProductSubcategoryID = 1;
        adventureWorks2.SaveChanges(RefreshConflict.MergeClinetAndStore);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Features (8) Covariance and Contravariance</title><link>https://dixin.github.io/posts/understanding-csharp-features-8-covariance-and-contravariance/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-8-covariance-and-contravariance/</guid><description>\] - \]</description><pubDate>Sat, 06 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)&quot;&gt;covariance/contravariance&lt;/a&gt;, variance is the capability to replace a type with a less-derived type or a more-derived type in a context. C# 4.0 and CLR 4 introduced covariance and contravariance for generics.&lt;/p&gt;
&lt;h2&gt;Is-a relationship for inheritance&lt;/h2&gt;
&lt;p&gt;Since covariance and contravariance is about deriving, the following &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/27db6csx.aspx&quot;&gt;inheritance hierarchy&lt;/a&gt; is defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Base
{
}

public class Derived : Base
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, a Derived object “&lt;a href=&quot;https://en.wikipedia.org/wiki/Is-a&quot;&gt;is a&lt;/a&gt;” Base object.&lt;/p&gt;
&lt;h2&gt;Non-generic delegate&lt;/h2&gt;
&lt;p&gt;By using above Base/Derived as input/output of method, there are 4 combinations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Methods
{
    public static Base DerivedIn_BaseOut(Derived @in)
    {
        return new Base();
    }

    public static Derived DerivedIn_DerivedOut(Derived @in)
    {
        return new Derived();
    }

    public static Base BaseIn_BaseOut(Base @in)
    {
        return new Base();
    }

    public static Derived BaseIn_DerivedOut(Base @in)
    {
        return new Derived();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Bind method to a delegate&lt;/h3&gt;
&lt;p&gt;Before C# 4.0, C# already supported covariance and contravariance for delegates without generics. Consider the following delegate type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate Base DerivedIn_BaseOut(Derived @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above Methods.DerivedIn_BaseOut’s signature matches this delegate type, so Methods.DerivedIn_BaseOut can be bound to its delegate instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Bind()
    {
        // Binding: DerivedIn_BaseOut delegate type and DerivedIn_BaseOut method have exactly the same signature.
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.DerivedIn_BaseOut;

        // When calling derivedIn_BaseOut delegate instance, DerivedIn_BaseOut method executes.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Covariance&lt;/h3&gt;
&lt;p&gt;Methods.DerivedIn_DerivedOut has a different signature from DerivedIn_BaseOut delegate type. The former returns a more derived type. There is a “is-a” relationship between their return types, but there is no intuitive relationship between the two signatures.&lt;/p&gt;
&lt;p&gt;However, C# compiler and the CLR both allow the following binding (assignment) before C# 4.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Covariance()
    {
        // Covariance: Derived &quot;is a&quot; Base =&amp;gt; DerivedIn_DerivedOut &quot;is a&quot; DerivedIn_BaseOut.
        DerivedIn_BaseOut derivedIn_DerivedOut = Methods.DerivedIn_DerivedOut;

        // When calling derivedIn_BaseOut delegate instance, DerivedIn_DerivedOut method executes.
        // derivedIn_BaseOut should output a Base object, while DerivedIn_DerivedOut outputs a Derived object.
        // The actual Derived object &quot;is a&quot; required Base output. This binding always works.
        Base @out = derivedIn_DerivedOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a bound method can return a more derived type than the delegate type. This is called covariance.&lt;/p&gt;
&lt;h3&gt;Contravariance&lt;/h3&gt;
&lt;p&gt;Methods.BaseIn_BaseOut required a less-derived parameter then DerivedIn_BaseOut delegate type. The following binding also works before C# 4.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Contravariance()
    {
        // Contravariance: Derived is a Base =&amp;gt; BaseIn_BaseOut is a DerivedIn_BaseOut.
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.BaseIn_BaseOut;

        // When calling derivedIn_BaseOut delegate instance, BaseIn_BaseOut method executes.
        // derivedIn_BaseOut should have a Derived input, while BaseIn_BaseOut requires a Base input.
        // The actual Derived object &quot;is a&quot; required Base input. This binding always works.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a method can have less derived parameter type than the delegate type. This is called contravariance.&lt;/p&gt;
&lt;h3&gt;Covariance and contravariance&lt;/h3&gt;
&lt;p&gt;It is easy to predict, Methods.BaseIn_DerivedOut, with more derived parameter type and less derived return type, can be also bound to DerivedIn_BaseOut:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{

    public static void CovarianceAndContravariance()
    {
        // Covariance and contravariance: Derived is a Base =&amp;gt; BaseIn_DerivedOut is a DerivedIn_BaseOut. 
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.BaseIn_DerivedOut;

        // When calling derivedInBaseOut delegate instance, BaseIn_DerivedOut method executes.
        // derivedIn_BaseOut should have a Derived input, while BaseIn_DerivedOut requires a Base input.
        // derivedIn_BaseOut should output a Base object, while BaseIn_DerivedOut outputs a Derived object. 
        // This binding always works.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here covariance and contravariance both happen for the same binding.&lt;/p&gt;
&lt;h3&gt;Invalid variance&lt;/h3&gt;
&lt;p&gt;In the following bindings, there is no valid variance, so they cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public delegate Derived BaseIn_DerivedOut(Base @base);

    public static void InvalidVariance()
    {
#if ERROR
        // baseIn_DerivedOut should output a Derived object, while BaseIn_DerivedOut outputs a Base object. 
        // Base is not Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut1 = Methods.BaseIn_BaseOut;

        // baseIn_DerivedOut should have a Base input, while DerivedIn_BaseOut required a Derived output.
        // Base is not a Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut2 = Methods.DerivedIn_BaseOut;

        // baseIn_DerivedOut should have a Base input, while DerivedIn_DerivedOut required a Derived input.
        // baseIn_DerivedOut should output a Derived object, while derivedIn_DerivedOut outputs a Base object. 
        // Base is not a Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut3 = Methods.DerivedIn_DerivedOut;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Is-a relationship of delegates&lt;/h3&gt;
&lt;p&gt;The root of variances is that, in inheritance hierarchy, derived object “is a” base object. This “is-a” relationship can be promoted to a relationship between method and delegate types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output: Derived is a Base =&amp;gt; DerivedIn_DerivedOut is a DerivedIn_BaseOut;&lt;/li&gt;
&lt;li&gt;Contravariance of input: Derived is a Base =&amp;gt; BaseIn_BaseOut is a DerivedIn_BaseOut;&lt;/li&gt;
&lt;li&gt;Covariance of output and contravariance of input: Derived is a Base =&amp;gt; BaseIn_DerivedOut is a DerivedIn_BaseOut.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please notice these rules does not apply to value types. Basically value types has nothing to do with covariance/contravariance.&lt;/p&gt;
&lt;h2&gt;Generic delegate&lt;/h2&gt;
&lt;p&gt;With C# 2.0 generic delegate, the above XxxIn_XxxOut delegate types can be represented by the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TOut Func&amp;lt;TIn, TOut&amp;gt;(TIn @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then above method bindings become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
    public static void BindMethods()
    {
        // Bind.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut1 = Methods.DerivedIn_BaseOut;

        // Covariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut2 = Methods.DerivedIn_DerivedOut;

        // Contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut3 = Methods.BaseIn_BaseOut;

        // Covariance and contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut4 = Methods.BaseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 3.0 introduced lambda expression. However, the above bindings cannot be used for lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegate
{
    public static void BindLambdas()
    {
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = (Derived @in) =&amp;gt; new Base();
        Func&amp;lt;Derived, Derived&amp;gt; derivedIn_DerivedOut = (Derived @in) =&amp;gt; new Derived();
        Func&amp;lt;Base, Base&amp;gt; baseIn_BaseOut = (Base @in) =&amp;gt; new Base();
        Func&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = (Base @in) =&amp;gt; new Derived();

#if ERROR
        // Covariance.
        derivedIn_BaseOut = derivedIn_DerivedOut;

        // Contravariance.
        derivedIn_BaseOut = baseIn_BaseOut;

        // Covariance and contravariance.
        derivedIn_BaseOut = baseIn_DerivedOut;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The out and in keywords&lt;/h3&gt;
&lt;p&gt;C# 4.0 uses the in/out keywords to specify a type parameter is contravariant/covariant. So above generic delegate can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TOut Func&amp;lt;in TIn, out TOut&amp;gt;(TIn @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the bindings work for both methods and lambda expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
    public static void BindMethods()
    {
        // Bind.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut1 = Methods.DerivedIn_BaseOut;

        // Covariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut2 = Methods.DerivedIn_DerivedOut;

        // Contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut3 = Methods.BaseIn_BaseOut;

        // Covariance and contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut4 = Methods.BaseIn_DerivedOut;
    }

    public static void BindLambdas()
    {
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = (Derived @in) =&amp;gt; new Base();
        Func&amp;lt;Derived, Derived&amp;gt; derivedIn_DerivedOut = (Derived @in) =&amp;gt; new Derived();
        Func&amp;lt;Base, Base&amp;gt; baseIn_BaseOut = (Base @in) =&amp;gt; new Base();
        Func&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = (Base @in) =&amp;gt; new Derived();

        // Covariance.
        derivedIn_BaseOut = derivedIn_DerivedOut;

        // Contravariance.
        derivedIn_BaseOut = baseIn_BaseOut;

        // Covariance and ontravariance.
        derivedIn_BaseOut = baseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The in/out keywords also constrains the usage of the decorated type parameter to guarantee the variances. The following generic delegate types are invalid and cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
#if ERROR
    // CS1961 Invalid variance: The type parameter &apos;TOut&apos; must be covariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TOut&amp;gt;.Invoke()&apos;. &apos;TOut&apos; is contravariant.
    public delegate TOut Func&amp;lt;in TOut&amp;gt;();

    // CS1961 Invalid variance: The type parameter &apos;TIn&apos; must be contravariantly valid on &apos;GenericDelegateWithVariances.Action&amp;lt;TIn&amp;gt;.Invoke(TIn)&apos;. &apos;TIn&apos; is covariant.
    public delegate void Action&amp;lt;out TIn&amp;gt;(TIn @in);

    // CS1961 Invalid variance: The type parameter &apos;TOut&apos; must be covariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TIn, TOut&amp;gt;.Invoke(TIn)&apos;. &apos;TOut&apos; is contravariant.
    // CS1961 Invalid variance: The type parameter &apos;TIn&apos; must be contravariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TIn, TOut&amp;gt;.Invoke(TIn)&apos;. &apos;TIn&apos; is covariant.
    public delegate TOut Func&amp;lt;out TIn, in TOut&amp;gt;(TIn @in);
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, it looks in is only for input, and out is only for output. In .NET 4.0+:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate TOut Func&amp;lt;out TOut&amp;gt;();

    public delegate TOut Func&amp;lt;out TOut, in TIn&amp;gt;(TIn @in);

    public delegate TOut Func&amp;lt;out TOut, in TIn1, in TIn2&amp;gt;(TIn1 in1, TIn2 in2);

    public delegate TOut Func&amp;lt;out TOut, in TIn1, in TIn2, in TIn3&amp;gt;(TIn1 in1, TIn2 in2, TIn3 in3);
    
    // ...

    public delegate void Action&amp;lt;in TIn&amp;gt;(TIn @in);

    public delegate void Action&amp;lt;in TIn1, in TIn2&amp;gt;(TIn1 in1, TIn2 in2);

    public delegate void Action&amp;lt;in TIn1, in TIn2, in TIn3&amp;gt;(TIn1 in1, TIn2 in2, TIn3 in3);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type parameter is renamed to be more intuitive.&lt;/p&gt;
&lt;h2&gt;Higher-order function&lt;/h2&gt;
&lt;p&gt;So far all the discussion are about first-order function. The variances of higher-order function could be more interesting.&lt;/p&gt;
&lt;h3&gt;Variance of input&lt;/h3&gt;
&lt;p&gt;The following delegate type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate void ActionIn&amp;lt;T&amp;gt;(Action&amp;lt;T&amp;gt; action);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can represent a higher-order function type, which take a function as parameter.&lt;/p&gt;
&lt;p&gt;Regarding T for Action&amp;lt;T&amp;gt; is contravariant, is T still contravariant for ActionIn&amp;lt;T&amp;gt;? The answer is no. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrderFunction
{
#if ERROR
    public delegate void ActionIn&amp;lt;in T&amp;gt;(Action&amp;lt;T&amp;gt; action);

    public static void ContravarianceOfInput()
    {
        // Higher-order funcitons:
        ActionIn&amp;lt;Derived&amp;gt; derivedInIn = (Action&amp;lt;Derived&amp;gt; derivedIn) =&amp;gt; derivedIn(new Derived());
        ActionIn&amp;lt;Base&amp;gt; baseInIn = (Action&amp;lt;Base&amp;gt; baseIn) =&amp;gt; baseIn(new Base());

        // Regarding Action&amp;lt;Base&amp;gt; &quot;is a&quot; ActionIn&amp;lt;Derived&amp;gt;,
        // assumes there is still contravariance of input,
        // which is, ActionIn&amp;lt;Base&amp;gt; &quot;is a&quot; ActionIn&amp;lt;Derived&amp;gt;
        derivedInIn = baseInIn;

        // When calling baseInIn, derivedInIn executes.
        // baseInIn should have a Action&amp;lt;Base&amp;gt; input, while derivedInIn requires a Action&amp;lt;Derived&amp;gt; input.
        // The actual Action&amp;lt;Base&amp;gt; &quot;is a&quot; required Action&amp;lt;Derived&amp;gt;. This binding should always works.
        baseInIn(new Action&amp;lt;Base&amp;gt;((Base @in) =&amp;gt; { }));
    }
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is the problem here? And how to fix?&lt;/p&gt;
&lt;h3&gt;Revisit covariance and contravariance&lt;/h3&gt;
&lt;p&gt;First, covariance/contravariance can be viewed in another way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Func&amp;lt;T&amp;gt;: Derived “is a” Base =&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt;. This is named covariance (not out-variance) because the direction of “is a” relationship remains.&lt;/li&gt;
&lt;li&gt;Action&amp;lt;T&amp;gt;: Derived “is a” Base =&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt;. This is named contravariance (not in-variance) because the direction of “is a” relationship reverses.
&lt;ul&gt;
&lt;li&gt;In the original “is a” relationship, Derived is on the left side, Base is on the right side&lt;/li&gt;
&lt;li&gt;In the new “is a” relationship, Derived goes to the right, and Base goes to the left&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To examine the variance for higher-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Func&amp;lt;T&amp;gt; can be made higher order, by just replacing T with Func&amp;lt;T&amp;gt;. Then:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Derived/Base. Comparing to 1, T is covariant for Func&amp;lt;T&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Func&amp;lt;Derived&amp;gt;/Func&amp;lt;Base&amp;gt;. Comparing to 1, T is covariant for Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Func&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; /Func&amp;lt;Func&amp;lt;Base&amp;gt;&amp;gt; . Comparing to 1, T is covariant for Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Action&amp;lt;T&amp;gt; can be made higher order, by just replacing T with Action&amp;lt;T&amp;gt;. Then:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Base/Derived. the direction of “Is-a” relationship reverses. Comparing to 1, T is contravariant for Action&amp;lt;T&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Action&amp;lt;Derived&amp;gt;/Action&amp;lt;Base&amp;gt;. the direction of “Is-a” relationship reverses again, so that Derived goes back to left, and Base goes back to right. Comparing to 1, T is covariant for Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; /Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;. Comparing to 1, T is contravariant for Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In above code, ActionIn&amp;lt;T&amp;gt; is equivalent to Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;. So, T is covariant for Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;/ActionIn&amp;lt;T&amp;gt;, not contravariant. The fix is to use out keyword to decorate T, and swap the binding:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrderFunction
{
    // Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;
    public delegate void ActionIn&amp;lt;out T&amp;gt;(Action&amp;lt;T&amp;gt; action);

    public static void CovarianceOfInput() // Not contravariance.
    {
        // Higher-order funcitons:
        ActionIn&amp;lt;Derived&amp;gt; derivedInIn = (Action&amp;lt;Derived&amp;gt; derivedIn) =&amp;gt; derivedIn(new Derived());
        ActionIn&amp;lt;Base&amp;gt; baseInIn = (Action&amp;lt;Base&amp;gt; baseIn) =&amp;gt; baseIn(new Base());

        // Not derivedInIn = baseInIn;
        baseInIn = derivedInIn;

        // When calling baseInIn, derivedInIn executes.
        // baseInIn should have a Action&amp;lt;Base&amp;gt; input, while derivedInIn requires a Action&amp;lt;Derived&amp;gt; input.
        // The actual Action&amp;lt;Base&amp;gt; &quot;is a&quot; required Action&amp;lt;Derived&amp;gt;. This binding always works.
        baseInIn(new Action&amp;lt;Base&amp;gt;((Base @in) =&amp;gt; { }));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other case, type parameter as output, is straightforward, because the type parameter is always covariant for any first-order/higher-order function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrderFunction
{
    public delegate Func&amp;lt;TOut&amp;gt; FuncOut&amp;lt;out TOut&amp;gt;();

    public static void CovarianceOfOutput()
    {
        // First order functions.
        Func&amp;lt;Base&amp;gt; baseOut = () =&amp;gt; new Base();
        Func&amp;lt;Derived&amp;gt; derivedOut = () =&amp;gt; new Derived();
        // T is covarianct for Func&amp;lt;T&amp;gt;.
        baseOut = derivedOut;

        // Higher-order funcitons:
        FuncOut&amp;lt;Base&amp;gt; baseOutOut = () =&amp;gt; baseOut;
        FuncOut&amp;lt;Derived&amp;gt; derivedOutOut = () =&amp;gt; derivedOut;

        // Covariance of output: FuncOut&amp;lt;Derived&amp;gt; &quot;is a&quot; FuncOut&amp;lt;Base&amp;gt;
        baseOutOut = derivedOutOut;

        // When calling baseOutOut, derivedOutOut executes.
        // baseOutOut should output a Func&amp;lt;Base&amp;gt;, while derivedOutOut outputs a Func&amp;lt;Derived&amp;gt;.
        // The actual Func&amp;lt;Derived&amp;gt; &quot;is a&quot; required Func&amp;lt;Base&amp;gt;. This binding always works.
        baseOut = baseOutOut();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Variances for higher-order function&lt;/h3&gt;
&lt;p&gt;Variances are straightforward for first-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output (out keyword): Derived “is a” Base =&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt; (“Is-a” remains.)&lt;/li&gt;
&lt;li&gt;Contravariance of input (in keyword): Derived “is a” Base =&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (“Is-a” reverses.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For higher-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Output is always covariant:
&lt;ul&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt;&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt;&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Input can be either contravariant or covariant, depends on how many times the direction of “is-a” relationship reverses:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (contravariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; (covariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; (contravariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public static class OutputCovarianceForHigherOrder
{
    public delegate T Func&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;
    public delegate Func&amp;lt;T&amp;gt; FuncOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    public delegate FuncOut&amp;lt;T&amp;gt; FuncOutOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;
    public delegate FuncOutOut&amp;lt;T&amp;gt; FuncOutOutOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // ...
}

public static class InputVarianceReversalForHigherOrder
{
    public delegate void Action&amp;lt;in T&amp;gt;(T @in); // Contravariant T as input.

    // Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;
    public delegate void ActionIn&amp;lt;out T&amp;gt;(Action&amp;lt;T&amp;gt; action); // Covariant T as input.

    // Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    public delegate void ActionInIn&amp;lt;in T&amp;gt;(ActionIn&amp;lt;T&amp;gt; actionIn); // Contravariant T as input.

    // Action&amp;lt;Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;
    public delegate void ActionInInIn&amp;lt;out T&amp;gt;(ActionInIn&amp;lt;T&amp;gt; actionInIn); // Covariant T as input.

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Generic interface&lt;/h2&gt;
&lt;p&gt;In C# 4.0+, covariance and contravariance are used for generic interfaces. Covariance and contravariance&lt;/p&gt;
&lt;p&gt;An interface can be viewed as a set of method signatures, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IOut&amp;lt;TOut&amp;gt; // TOut is only used as output.
{
    TOut Out1(); // TOut is covariant for Out1 (Func&amp;lt;TOut&amp;gt;).

    TOut Out2(object @in); // TOut is covariant for Out2 (Func&amp;lt;object, TOut&amp;gt;).

    TOut Out3 { get; } // TOut is covariant for Out3&apos;s getter (Func&amp;lt;object, TOut&amp;gt;).
}

public interface IIn&amp;lt;TIn&amp;gt; // TIn is only used as input.
{
    void In1(TIn @in); // TIn is contravariant for In1 (Action&amp;lt;TIn&amp;gt;).

    object In2(TIn @in); // TIn is contravariant for In2 (Func&amp;lt;TIn, object&amp;gt;).

    TIn In3 { set; } // TIn is contravariant for In3&apos;s setter (Action&amp;lt;TIn&amp;gt;).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Covariance&lt;/h3&gt;
&lt;p&gt;For interface IOut&amp;lt;TOut&amp;gt;, TOut is covariant for all members, so TOut can be made covariant at interface level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IOut&amp;lt;out TOut&amp;gt; // TOut is covariant for all members of interface.
{
    TOut Out1();

    TOut Out2(object @in);

    TOut Out3 { get; } // TOut get_Out3();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the following interface binding (assignment) works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void Covariance()
    {
        IOut&amp;lt;Base&amp;gt; baseOut = default(IOut&amp;lt;Base&amp;gt;);
        IOut&amp;lt;Derived&amp;gt; derivedOut = default(IOut&amp;lt;Derived&amp;gt;);

        // Covariance: Derived &quot;is a&quot; Base =&amp;gt; IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;.
        baseOut = derivedOut;

        // So that, when calling baseOut.Out1, the underlying derivedOut.Out1 executes.
        // derivedOut.Out1 method (Func&amp;lt;Derived&amp;gt;) &quot;is a&quot; baseOut.Out1 method (Func&amp;lt;Base&amp;gt;).
        Base out1 = baseOut.Out1();

        // When calling baseOut.Out2, the underlying derivedOut.Out2 executes.
        // derivedOut.Out2 (Func&amp;lt;object, Derived&amp;gt;) &quot;is a&quot; baseOut.Out2 (Func&amp;lt;object, Base&amp;gt;).
        Base out2 = baseOut.Out2(@in: new object());

        // Out3 property is getter only. The getter is a get_Out3 method (Func&amp;lt;TOut&amp;gt;).
        // derivedOut.Out3 getter (Func&amp;lt;Derived&amp;gt;) &quot;is a&quot; baseOut.Out3 getter (Func&amp;lt;Base&amp;gt;).
        Base out3 = baseOut.Out3;

        // So, IOut&amp;lt;Derived&amp;gt; interface &quot;is an&quot; IOut&amp;lt;Base&amp;gt; interface. Above binding always works.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET 4.0+, System.Collections.Generic.IEnumerator&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    /// &amp;lt;summary&amp;gt;Supports a simple iteration over a generic collection.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Contravariance&lt;/h3&gt;
&lt;p&gt;For interface IIn&amp;lt;TIn&amp;gt;, TIn is contravariant for all members, so TIn can be made contravariant at interface level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn&amp;lt;in TIn&amp;gt; // TIn is contravariant for all members of interface.
{
    void In1(TIn @in);

    object In2(TIn @in);

    TIn In3 { set; } // void set_In3(TIn @in);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the following interface binding works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void Contravariance()
    {
        IIn&amp;lt;Derived&amp;gt; derivedIn = default(IIn&amp;lt;Derived&amp;gt;);
        IIn&amp;lt;Base&amp;gt; baseIn = default(IIn&amp;lt;Base&amp;gt;);

        // Contravariance: Derived &quot;is a&quot; Base =&amp;gt; IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;.
        derivedIn = baseIn;

        // When calling derivedIn.In1, the underlying baseIn.In1 executes.
        // baseIn.In1 method (Action&amp;lt;Base&amp;gt;) &quot;is a&quot; derivedIn.In1 method (Action&amp;lt;Derived&amp;gt;).
        derivedIn.In1(new Derived());

        // When calling derivedIn.In2, the underlying baseIn.In2 executes.
        // baseIn.In2 (Func&amp;lt;Base, object&amp;gt;) &quot;is a&quot; derivedIn.In2 (Func&amp;lt;Derived, object&amp;gt;).
        object @out = derivedIn.In2(new Derived());

        // In3 property is setter only. The setter is a set_In3 method (Action&amp;lt;TOut&amp;gt;).
        // baseIn.In3 setter (Action&amp;lt;Base&amp;gt;) &quot;is a&quot; derivedIn.In3 setter (Action&amp;lt;Base&amp;gt;).
        derivedIn.In3 = new Derived();

        // So, IIn&amp;lt;Base&amp;gt; interface &quot;is an&quot; IIn&amp;lt;Derived&amp;gt; interface. Above binding always works.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET 4.0+, System.IComparable&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    /// &amp;lt;summary&amp;gt;Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering instances.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to compare.This type parameter is contravariant. That is, you can use either the type you specified or any type that is less derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IComparable&amp;lt;in T&amp;gt;
    {
        int CompareTo(T other);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Covariance and contravariance&lt;/h3&gt;
&lt;p&gt;A generic interface can have both covariant and contravariance type parameters, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn_Out&amp;lt;in TIn, out TOut&amp;gt;
{
    void In(TIn @in);
    TOut Out();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void CovarianceAndContravariance()
    {
        IIn_Out&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = default(IIn_Out&amp;lt;Derived, Base&amp;gt;);
        IIn_Out&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = default(IIn_Out&amp;lt;Base, Derived&amp;gt;);

        // Covariance and contravariance: IIn_Out&amp;lt;Base, Derived&amp;gt; &quot;is a&quot; IIn_Out&amp;lt;Derived, Base&amp;gt;.
        derivedIn_BaseOut = baseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Invariance&lt;/h3&gt;
&lt;p&gt;In the following generic interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn_Out&amp;lt;T&amp;gt;
{
    T Out(); // T is covariant for Out (Func&amp;lt;T&amp;gt;).

    void In(T @in); // T is contravaraint for In (Action&amp;lt;T&amp;gt;).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;T is not covariant for some member, and not contravariant for some other member. So, T cannot be variant at the interface level. In .NET, System.Collections.Generic.IList&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IList&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        T this[int index]
        {
            get; // T is covariant.
            set; // T is contravariant.
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Is-a relationship of generic interfaces&lt;/h3&gt;
&lt;p&gt;The “is-a” relationship can be promoted to generic interfaces (sets of method signatures):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance: Derived is a Base =&amp;gt; IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;;&lt;/li&gt;
&lt;li&gt;Contravariance: Derived is a Base =&amp;gt; IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;;&lt;/li&gt;
&lt;li&gt;Covariance and contravariance: Derived is a Base =&amp;gt; IIn_Out&amp;lt;Base, Derived&amp;gt; &quot;is a&quot; IIn_Out&amp;lt;Derived, Base&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Array&lt;/h2&gt;
&lt;p&gt;An array T[] can be viewed as an IList&amp;lt;T&amp;gt;. As fore mentioned, T is invariant for IList&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h3&gt;Covariance&lt;/h3&gt;
&lt;p&gt;C# unexpectedly support covariance for array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void Covariance()
    {
        // IList&amp;lt;Base&amp;gt; baseArray = new Base[2];
        Base[] baseArray = new Base[2];

        // IList&amp;lt;Derived&amp;gt; derivedArray = new Derived[3];
        Derived[] derivedArray = new Derived[2];

        // T of IList&amp;lt;T&amp;gt; is invariant,
        // so logically binding IList&amp;lt;derivedArray&amp;gt; to IList&amp;lt;Base&amp;gt; could not be compiled.
        // But C# compiles it, to be compliant with Java :(
        baseArray = derivedArray; // Array covariance.

        // At runtime, baseArray refers to a Derived array.
        // So A Derived object can be an element of baseArray[0].
        baseArray[0] = new Derived();

        // At runtime, baseArray refers to a Derived array.
        // A Base object &quot;is not a&quot; Derivd object.
        // And ArrayTypeMismatchException is thrown at runtime.
        baseArray[1] = new Base();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code can be compiled but throws ArrayTypeMismatchException at runtime. In some scenarios, this can be confusing and makes code buggy. For example, when using array as parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void ProcessArray(Base[] array)
    {
        array[0] = new Base(); // ArrayTypeMismatchException.
        }

    public static void CallProcessArray()
    {
        Derived[] array = new Derived[1];
        ProcessArray(array); // Array covariance. Compliable.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, value type has nothing to do with variances, the following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void ValueType()
    {
        object[] objectArray = new object[1];
        int[] int32Array = new int[1];
#if ERROR
        // No covariance.
        objectArray = int32Array;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Comments&lt;/h3&gt;
&lt;p&gt;Here are some comments for array covariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/news/2008/08/GenericVariance&quot;&gt;Jonathan Allen said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On a historical note, C# and VB both support array covariance (&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/09/01/understanding-csharp-covariance-and-contravariance-6-typing-issues.html&quot;&gt;out/IEnumerable scenario&lt;/a&gt;) even though it can lead to runtime errors in contravariant situations (in/IWriter scenario). This was done in order to make C# more compatible with Java. This is generally considered a poor decision, but it cannot be undone at this time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the book “&lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0321154932&quot;&gt;The Common Language Infrastructure Annotated Standard&lt;/a&gt;”, Jim Miller said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The decision to support covariant arrays was primarily to allow Java to run on the VES. The covariant design is not thought to be the best design in general, but it was chosen in the interest of broad reach.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx&quot;&gt;Rick Byers said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve heard that Bill Joy, one of the original Java designers, has since said that he tried to remove array covariance in 1995 but wasn&apos;t able to do it in time, and has regretted having it in Java ever since.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Anders Hejlsberg (&lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;chief architect&lt;/a&gt; of C#) &lt;a href=&quot;http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/&quot;&gt;said in this video&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This isn&apos;t type safe. A lot of people maybe don&apos;t even realize that there&apos;s a hole there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://ericlippert.com/&quot;&gt;Eric Lippert&lt;/a&gt; (member of C# design team) &lt;a href=&quot;http://www.informit.com/articles/article.aspx?p=2425867&quot;&gt;put array covariance the top 1 of 10 worst C# features&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C# 1.0 has unsafe array covariance not because the designers of C# thought that the scenario was particularly compelling, but rather because the Common Language Runtime (CLR) has the feature in its type system, so C# gets it &quot;for free.&quot; The CLR has it because Java has this feature; the CLR team wanted to design a runtime that could implement Java efficiently, should that become necessary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a C# feature that should never be used.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;C# 3.0 features are C# level syntactical sugars provided by C# compiler, but the covariance/contravariance is a feature of C# 4.0/CLR 4. The ore mentioned System.Func&amp;lt;in TIn, out TOut&amp;gt; generic delegate is compiled to following IL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class public auto ansi sealed System.Func`2&amp;lt;-TIn, +TOut&amp;gt;
       extends System.MulticastDelegate
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the definition of System.IComparable&amp;lt;in T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class interface public abstract auto ansi System.IComparable`1&amp;lt;-T&amp;gt;
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C#’s out/in decorators is compiled to CLR’s +/- operators, which is more difficult to remember, &lt;a href=&quot;http://blogs.msdn.com/ericlippert/archive/2007/10/31/covariance-and-contravariance-in-c-part-eight-syntax-options.aspx&quot;&gt;even for the members of the C# design committee&lt;/a&gt;. +/- can be read as “’is-a’ direction remains/reverses”.&lt;/p&gt;
&lt;h2&gt;Variances in .NET&lt;/h2&gt;
&lt;p&gt;Not many generic types in .NET have variant type parameter(s). LINQ can be uses to query these generic types from .NET libraries.&lt;/p&gt;
&lt;p&gt;The following method queries a specified directory, and retrieve all .NET assemblies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Assembly&amp;gt; GetAssemblies(string directory)
    {
        return Directory.EnumerateFiles(directory, &quot;*.dll&quot;)
            .Select(file =&amp;gt;
                {
                    try
                    {
                        return Assembly.LoadFrom(file);
                    }
                    catch (BadImageFormatException)
                    {
                        return null;
                    }
                })
            .Where(assembly =&amp;gt; assembly != null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following method queries one specified assembly, and filter generic types with any variant type parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Type&amp;gt; GetTypesWithVariance(Assembly assembly)
    {
        try
        {
            return assembly.ExportedTypes.Where(type =&amp;gt;
                type.IsGenericTypeDefinition &amp;amp;&amp;amp; type.GetGenericArguments().Any(argument =&amp;gt;
                    (argument.GenericParameterAttributes &amp;amp; GenericParameterAttributes.Covariant)
                    == GenericParameterAttributes.Covariant
                    ||
                    (argument.GenericParameterAttributes &amp;amp; GenericParameterAttributes.Contravariant)
                    == GenericParameterAttributes.Contravariant));
        }
        catch (TypeLoadException)
        {
            return Enumerable.Empty&amp;lt;Type&amp;gt;();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last method queries the assemblies in the same directory of mscorlib.dll, and retrieves the wanted types, and orders them by name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Type&amp;gt; GetTypesWithVariance()
    {
        string mscorlibPath = typeof(object).Assembly.Location;
        string gacPath = Path.GetDirectoryName(mscorlibPath);
        return GetAssemblies(gacPath)
            .SelectMany(GetTypesWithVariance)
            .OrderBy(type =&amp;gt; type.Name);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the result of executing the last method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System namespace:
&lt;ul&gt;
&lt;li&gt;Action`1 to Action`16, Func`1 to Func`17&lt;/li&gt;
&lt;li&gt;Comparison&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Converter`2&lt;/li&gt;
&lt;li&gt;IComparable&amp;lt;T&amp;gt;,&lt;/li&gt;
&lt;li&gt;IObservable&amp;lt;T&amp;gt;, IObserver&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IProgress&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Predicate&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic namespace:
&lt;ul&gt;
&lt;li&gt;IComparer&amp;lt;T&amp;gt;, IEqualityComparer&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt;, IEnumerator&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IReadOnlyCollection&amp;lt;T&amp;gt;, IReadOnlyList&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Linq namespace:
&lt;ul&gt;
&lt;li&gt;IGrouping`2&lt;/li&gt;
&lt;li&gt;IOrderedQueryable&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MSDN has a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd799517#VariantList&quot;&gt;List of Variant Generic Interface and Delegate Types&lt;/a&gt;, but it is inaccurate. For example, it says TElement is covariant for IOrderedEnumerable&amp;lt;TElement&amp;gt;, but actually not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;LINQ&lt;/h3&gt;
&lt;p&gt;As fore mentioned, T is covariant for IEnumerator&amp;lt;T&amp;gt;. As a result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    /// &amp;lt;summary&amp;gt;Exposes the enumerator, which supports a simple iteration over a collection of a specified type.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); // T is covariant.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;T is also covariant for IEnumerable&amp;lt;T&amp;gt;, since T is covariant for all member(s). In another word: Derived “is a” Base =&amp;gt; IEnumerable&amp;lt;Derived&amp;gt; “is an” IEnumerable&amp;lt;Base&amp;gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void Linq()
    {
        IEnumerable&amp;lt;Derived&amp;gt; derivedEnumerable = Enumerable.Empty&amp;lt;Derived&amp;gt;();
        IEnumerable&amp;lt;Base&amp;gt; baseEnumerable = Enumerable.Empty&amp;lt;Base&amp;gt;();

        // IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);
        baseEnumerable = baseEnumerable.Concat(derivedEnumerable);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before C# 4.0, IEnumerable&amp;lt;Derived&amp;gt; is not an IEnumerable&amp;lt;Base&amp;gt;, above code cannot be compiled, unless explicitly telling compiler derivedEnumerable is an IEnumerable&amp;lt;Base&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;baseEnumerable = baseEnumerable.Concat(derivedEnumerable.Cast&amp;lt;Base&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Sync Windows Live Writer Drafts and Posts Across PCs</title><link>https://dixin.github.io/posts/sync-windows-live-writer-drafts-and-posts-across-pcs/</link><guid isPermaLink="true">https://dixin.github.io/posts/sync-windows-live-writer-drafts-and-posts-across-pcs/</guid><description>Windows Live Writer saves drafts and posts under Documents\My Weblog Posts. To sync this directory with OneDrive, just move it to OneDrive (e.g. OneDrive\Documents\WindowsLiveWriter), and create a</description><pubDate>Wed, 27 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Sync files through OneDrive&lt;/h2&gt;
&lt;p&gt;Windows Live Writer saves drafts and posts under Documents\My Weblog Posts. To sync this directory with OneDrive, just move it to OneDrive (e.g. OneDrive\Documents\WindowsLiveWriter), and create a junction to redirect:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;D:\Documents&amp;gt;mklink /J &quot;My Weblog Posts&quot; &quot;D:\OneDrive\Documents\WindowsLiveWriter&quot;&lt;/p&gt;
&lt;p&gt;Junction created for My Weblog Posts &amp;lt;&amp;lt;===&amp;gt;&amp;gt; D:\OneDrive\Documents\WindowsLiveWriter&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After doing this for each PC, all Windows Live Writer files are in sync.&lt;/p&gt;
&lt;h2&gt;Sync destination blog id&lt;/h2&gt;
&lt;p&gt;With the above step, draft files (Documents\My Weblog Posts\Drafts\*.wpost) can work across PCs, but posts (Documents\My Weblog Posts\Recent Posts\*.wpost) cannot. In the following scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In PC 1, writes a draft and post it to blog. There will be a post file saved, e.g.: Documents\My Weblog Posts\Recent Posts\LINQ via C#.wpost.&lt;/li&gt;
&lt;li&gt;In PC 2, opens Documents\My Weblog Posts\Recent Posts\LINQ via C#.wpost, edit it and post to blog again.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the blog, the original post is not updated. Instead, a new entry is posted to blog. and a new post file is saved to local as Documents\My Weblog Posts\Recent Posts\LINQ via C#[2].wpost. The same issue happens when Windows is reinstalled in the same PC.&lt;/p&gt;
&lt;p&gt;So why is LINQ via C#[2].wpost generated? What is the difference from LINQ via C#.wpost? These 2 files can be compared with Code Compare:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It looks .wpost files are binary files. So try to open them with 7-zip. Bingo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So extract the contents of LINQ via C#.wpost and LINQ via C#[2].wpost to 2 directories, and compares the directories again with Code Compare:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It turns out the DestinationBlogId is the problem:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;They are 2 different GUIDs. Now search the GUID from LINQ via C#[2].wpost in PC 2’s registry, it is under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows Live\Writer\Weblogs\:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Recover_C7EE/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Apparently, it is a generated id when configuring Windows Live Writer to add the blog with credentials. Simply press F2 to rename it to the other GUID. Then, repeat this for all the PCs to have the same blog id, the problem is resolved. Now editing post files will update the original blog entry.&lt;/p&gt;
&lt;h2&gt;Appendix: Enable HTML5 support&lt;/h2&gt;
&lt;p&gt;Windows Live Writer does not work with this blog’s theme, trying to update the them will fails, and the Windows Live Writer’s log shows errors. The reason is the editor is rendered with IE in IE 7 mode, so later technologies like HTML5 and CSS3 cannot be supported. Fortunately, &lt;a href=&quot;http://weblogs.asp.net/jongalloway/8-windows-live-writer-tips&quot;&gt;there is a simple solution&lt;/a&gt;. In registry, under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION, add a value “WindowsLiveWriter.exe”, with DWORD data “9000”, which means IE9 mode of IE11 on Windows 10. Problem resolved. 9000 is specified here instead of 11000, because Windows Live Writer does not render tables correctly in IE10 and IE11 mode.&lt;/p&gt;
</content:encoded></item><item><title>C# 6.0 String Interpolation, FormattableString, and Code Analysis CA1305: Specify IFormatProvider</title><link>https://dixin.github.io/posts/csharp-6-0-string-interpolation-formattablestring-and-code-analysis-ca1305-specify-iformatprovider/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-6-0-string-interpolation-formattablestring-and-code-analysis-ca1305-specify-iformatprovider/</guid><description>C# 6.0 introduces a syntactic sugar , it is safer and more readable than [composite formatting](https://msdn.microsof</description><pubDate>Tue, 26 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# 6.0 introduces a syntactic sugar &lt;a href=&quot;https://en.wikipedia.org/wiki/String_interpolation#C.23.NET&quot;&gt;string interpolation&lt;/a&gt;, it is safer and more readable than &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/txafckwd.aspx&quot;&gt;composite formatting&lt;/a&gt;. Here is a small example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Diagnostics;

internal static class Program
{
    private static void Main() =&amp;gt; Trace.WriteLine($&quot;Machine name: {Environment.MachineName}.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, string interpolation does not get along with code analysis. By default, the $ syntax will be compiled to composite formatting, by calling the string.Format overload without IFormatProvider parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Diagnostics;

internal static class Program
{
    private static void Main() =&amp;gt; Trace.WriteLine(string.Format(&quot;Machine name: {0}.&quot;, Environment.MachineName));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result, Code Analysis/FxCop issues a CA1305 warning for every interpolated string: Specify IFormatProvider. This is very annoying.&lt;/p&gt;
&lt;p&gt;Interpolated string has a infamous feature, it can be also compiled to System.FormattableString:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    using System.Globalization;

    public abstract class FormattableString : IFormattable
    {
        protected FormattableString() { }

        public abstract string Format { get; }

        public abstract int ArgumentCount { get; }

        public abstract object[] GetArguments();

        public abstract object GetArgument(int index);

        public abstract string ToString(IFormatProvider formatProvider);

        string IFormattable.ToString(string ignored, IFormatProvider formatProvider) =&amp;gt; this.ToString(formatProvider);

        public static string Invariant(FormattableString formattable)
        {
            if (formattable == null)
            {
                throw new ArgumentNullException(nameof(formattable));
            }

            return formattable.ToString(CultureInfo.InvariantCulture);
        }

        public override string ToString() =&amp;gt; this.ToString(CultureInfo.CurrentCulture);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here FormattableString.Invariant seems to be a solution. Notice FormattableString is an abstract class. It is inherited by System.Runtime.CompilerServices.FormattableStringFactory.ConcreteFormattableString:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Runtime.CompilerServices
{
    public static class FormattableStringFactory
    {
        private sealed class ConcreteFormattableString : FormattableString
        {
            private readonly string _format;

            private readonly object[] _arguments;

            public override string Format =&amp;gt; this._format;

            public override int ArgumentCount =&amp;gt; this._arguments.Length;

            internal ConcreteFormattableString(string format, object[] arguments)
            {
                this._format = format;
                this._arguments = arguments;
            }

            public override object[] GetArguments() =&amp;gt; this._arguments;

            public override object GetArgument(int index) =&amp;gt; this._arguments[index];

            public override string ToString
                (IFormatProvider formatProvider) =&amp;gt; string.Format(formatProvider, this._format, this._arguments);
        }

        public static FormattableString Create(string format, params object[] arguments)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            return new ConcreteFormattableString(format, arguments);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that, FormattableString.Invariant calls ConcreteFormattableString.ToString, which then calls string.Format, the overload with IFormatProvider. Code Analysis warning CA1305: Specify IFormatProvider can be fixed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Diagnostics;

using static System.FormattableString;

internal static class Program
{
    private static void Main() =&amp;gt; Trace.WriteLine(Invariant($&quot;Machine name: {Environment.MachineName}.&quot;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above interpolated string is compiled to composite formatting call to FormattableStringFactory.Create:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

using static System.FormattableString;
internal static class Program
{
    private static void Main() =&amp;gt; Trace.WriteLine(Invariant(
        // $&quot;Machine name: {Environment.MachineName}.&quot; is compiled to:
        FormattableStringFactory.Create(&quot;Machine name: {0}.&quot;, Environment.MachineName)));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the conclusion is, to fix Code Analysis CA1305 for C# 6.0 string interpolation, FormattableString.Invariant has to be called for every occurrence of $ syntax. This is still very annoying. Hope there can be another syntactic sugar for this, for example, a $$ prefix to call FormattableString.Invariant.&lt;/p&gt;
&lt;p&gt;Also, MSDN and many other articles are inaccurate about interpolated string and FormattableString. &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn961160.aspx&quot;&gt;MSDN says&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are implicit type conversions from an interpolated string&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In .NET, the term “&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms173105.aspx&quot;&gt;implicit type conversion&lt;/a&gt;” is usually about runtime behavior, implemented by calling a type conversion operator defined with the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx&quot;&gt;implicit keyword&lt;/a&gt;. However, as demonstrated above, interpolated string becomes FormattableString/IFormattable at compile time.&lt;/p&gt;
</content:encoded></item><item><title>DiskPart Problem: Cannot Select Partition</title><link>https://dixin.github.io/posts/diskpart-problem-cannot-select-partition/</link><guid isPermaLink="true">https://dixin.github.io/posts/diskpart-problem-cannot-select-partition/</guid><description>When working with USB drive, the DiskPart command cannot select the partition of the USB disk:</description><pubDate>Tue, 19 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When working with USB drive, the DiskPart command cannot select the partition of the USB disk:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\Users\Administrator&amp;gt;diskpart&lt;/p&gt;
&lt;p&gt;Microsoft DiskPart version 6.1.7601 Copyright (C) 1999-2008 Microsoft Corporation. On computer: DIXINYAN-M17X&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; list disk&lt;/p&gt;
&lt;p&gt;Disk ### Status Size Free Dyn Gpt -------- ------------- ------- ------- --- --- Disk 0 Online 931 GB 3072 KB Disk 1 Online 3726 GB 0 B * Disk 2 Online 1901 MB 0 B&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; select disk 2&lt;/p&gt;
&lt;p&gt;Disk 2 is now the selected disk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Disk 2 is a USD drive, select it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DISKPART&amp;gt; list part&lt;/p&gt;
&lt;p&gt;Partition ### Type Size Offset ------------- ---------------- ------- ------- * Partition 1 Primary 1901 MB 0 B&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; select part 1&lt;/p&gt;
&lt;p&gt;There is no partition selected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Somehow the partition cannot be selected and manipulated. After searching around, it seems the only solution to to recreate the partition with DiskPart:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DISKPART&amp;gt; clean&lt;/p&gt;
&lt;p&gt;DiskPart succeeded in cleaning the disk.&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; create part primary&lt;/p&gt;
&lt;p&gt;DiskPart succeeded in creating the specified partition.&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; list part&lt;/p&gt;
&lt;p&gt;Partition ### Type Size Offset ------------- ---------------- ------- ------- * Partition 1 Primary 1901 MB 64 KB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now Partition 1 can be selected:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DISKPART&amp;gt; select part 1&lt;/p&gt;
&lt;p&gt;Partition 1 is now the selected partition.&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; active&lt;/p&gt;
&lt;p&gt;DiskPart marked the current partition as active.&lt;/p&gt;
&lt;p&gt;DISKPART&amp;gt; format fs=fat32 quick&lt;/p&gt;
&lt;p&gt;100 percent completed&lt;/p&gt;
&lt;p&gt;DiskPart successfully formatted the volume.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Understanding C# Features (6) Closure</title><link>https://dixin.github.io/posts/understanding-csharp-features-6-closure/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-6-closure/</guid><description>\] - \]</description><pubDate>Mon, 18 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;Non-local variable&lt;/h2&gt;
&lt;p&gt;In a C# class, it is &lt;a href=&quot;http://www.bbc.co.uk/films/2003/08/08/american_pie_the_wedding_2003_review.shtml&quot;&gt;perfectly nature normal thing&lt;/a&gt; for a method to access a variable defined inside or outside its body, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DisplayClass
{
    int nonLocalVariable = 0; // Outside the scope of method Add.

    public int Add()
    {
        int localVariable = 1; // Inside the scope of method Add.
        return localVariable + nonLocalVariable; // 1.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here in DisplayClass, the field is defined outside the scope of the method, so that it can be viewed as a &lt;a href=&quot;https://en.wikipedia.org/wiki/Non-local_variable&quot;&gt;non-local variable&lt;/a&gt; of method, in contrast of the local variable defined inside method scope. Non-local variable is also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx&quot;&gt;captured variable&lt;/a&gt;. This tutorial uses term non-local variable, because it is more specific.&lt;/p&gt;
&lt;p&gt;The concept of non-local variable also applies to lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Closure
{
    public static void Outer()
    {
        int nonLocalVariable = 0; // Outside the scope of function add.
        Func&amp;lt;int&amp;gt; add = () =&amp;gt;
            {
                int localVariable = 1; // Inside the scope of function add.
                return localVariable + nonLocalVariable;
            };

        int result = add(); // 1;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nonLocalVariable is defined outside the scope of function add, so it is a non-local variable of add, in contrast of the local variable defined inside add. This capability for a function or method to reference a non-local value, is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Closure_(computer_programming)&quot;&gt;closure&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;In above lambda expression example, nonLocalVariable is created in the scope of outer method Lambda, and it does not exist at all in the scope of inner function add. How does this function access nonLocalVariable? Above DisplayClass example is the answer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class CompiledClosure
{
    [CompilerGenerated]
    private sealed class DisplayClass0
    {
        public int nonLocalVariable;

        internal int Add()
        {
            int localVariable = 1;
            return localVariable + this.nonLocalVariable;
        }
    }

    public static void Outer()
    {
        DisplayClass0 displayClass0 = new DisplayClass0();
        displayClass0.nonLocalVariable = 0;
        Func&amp;lt;int&amp;gt; add = displayClass0.Add;
        int result = add(); // 1.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# compiler generates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A inner class (DisplayClass0) to host the lambda expression; if there are more lambda expressions accessing non-local variables, more inner classes (DisplayClass1, …) will be generated to host these lambda expressions.&lt;/li&gt;
&lt;li&gt;A method (Add) to represent the function (add)&lt;/li&gt;
&lt;li&gt;A field to represent the non-local variable (nonLocalVariable). If there are more non-local variables accessed by that lambda expression, more fields will be generated to represent each of these non-local variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The generated logic becomes exactly the same case as the initial example. Accessing non-local variable becomes accessing field of the same class, naturally.&lt;/p&gt;
&lt;p&gt;In the Outer method, the inner add function creation becomes the instantiation of DisplayClass0. the non-local variable is passed by assigning it to the corresponding field. And, of course, the inner function call becomes a normal method call. C# closure is such a powerful syntactic sugar, which greatly simplifies the code.&lt;/p&gt;
&lt;h2&gt;Non-local variable can change&lt;/h2&gt;
&lt;p&gt;In above examples, non-local variables does not change. But if they changes, of course the referencing functions will be impacted, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ChangedNonLocal()
{
    int nonLocalVariable = 1; // Outside the scope of function add.
    Func&amp;lt;int&amp;gt; add = () =&amp;gt;
    {
        int localVariable = 0; // Inside the scope of function add.
        return localVariable + nonLocalVariable;
    };

    nonLocalVariable = 2; // Non-local variable can change.
    int result = add(); // 2 instead of 1.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes, this can be confusing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void MultipleReferences()
{
    List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; functions = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;(3);
    for (int nonLocalVariable = 0; nonLocalVariable &amp;lt; 3; nonLocalVariable++) // Outside the scope of function print.
    {
        Func&amp;lt;int&amp;gt; function = () =&amp;gt; nonLocalVariable; // nonLocalVariable: 0, 1, 2.
        functions.Add(function);
    }

    // Now nonLocalVariable is 3.
    foreach (Func&amp;lt;int&amp;gt; function in functions)
    {
        int result = function();
        Trace.WriteLine(result); // 3, 3, 3 instead of 0, 1, 2.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, 3 functions are created by the for loop. The nonLocalVariable is 0, 1, 2, when each function is created. However, when the for loop finishes executing, nonLocalVariable becomes 3. So when calling each of these 3 functions, the output will be 3, 3, 3 instead of 0, 1, 2.&lt;/p&gt;
&lt;p&gt;This can be resolved by copying the current value of nonLocalVariable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void CopyCurrent()
{
    List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; functions = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;(3);
    for (int nonLocalVariable = 0; nonLocalVariable &amp;lt; 3; nonLocalVariable++) // Outside the scope of function print.
    {
        int copyOfCurrentValue = nonLocalVariable; // nonLocalVariable: 0, 1, 2.
        // When nonLocalVariable changes, copyOfIntermediateState does not change.
        Func&amp;lt;int&amp;gt; function = () =&amp;gt; copyOfCurrentValue; // copyOfCurrentValue: 0, 1, 2.
        functions.Add(function);
    }

    // Now nonLocalVariable is 3. Each copyOfCurrentValue does not change.
    foreach (Func&amp;lt;int&amp;gt; function in functions)
    {
        int result = function();
        Trace.WriteLine(result); // 0, 1, 2.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Hidden reference&lt;/h2&gt;
&lt;p&gt;The closure syntactic sugar enables direct access to non-local variable. This convenience has a price. Closure can also be performance pitfall, because a hidden reference is persisted by the generated DisplayClass’s field. As a result, the non-local variable’s lifetime can be extended by closure. In the last example, copyOfCurrentValue is a temporary variable inside the for loop block, but its value is not gone after each iteration. After 3 iterations, the 3 copyOfCurrentValue values are still persisted by 3 functions, so that later the functions can use each of the values.&lt;/p&gt;
&lt;p&gt;Here is another intuitive example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Closure
{
    private static Func&amp;lt;int&amp;gt; longLifeFunction;

    public static void Reference()
    {
        // https://msdn.microsoft.com/en-us/library/System.Array.aspx
        byte[] shortLifeVariable = new byte[0X7FFFFFC7];
        // Some code...
        longLifeFunction = () =&amp;gt;
        {
            // Some code...
            byte value = shortLifeVariable[0]; // Reference.
            // More code...
            return 0;
        };
        // More code...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If Reference method is called, a closure will be created:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A lambda expression is created, and it persists a reference to its non-local variable shortLifeVariable.&lt;/li&gt;
&lt;li&gt;Then the lambda expression is persisted by Closure class’s static field longLifeFunction&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here shortLifeVariable is no longer a short lifetime temporary variable inside method Reference. Its lifetime is extended to be the same as longLifeFunction, which can be forever. When Reference method finishes executing, the allocated memory for the big byte array cannot be garbage collected. In closure, the reference can be very unapparent and unobvious. Other languages with closure support, like VB, F#, &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;, etc., have the same issue too. Closure must be used with caution.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Features (7) Higher-Order Function</title><link>https://dixin.github.io/posts/understanding-csharp-features-7-higher-order-function/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-7-higher-order-function/</guid><description>\] - \]</description><pubDate>Mon, 18 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;Function as input/output&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Higher-order_function&quot;&gt;Higher-order function&lt;/a&gt; is a function taking one or more function parameters as input, or returning a function as output. The other functions are called first-order functions. (Again, in C#, the term function and the term method are identical.) C# supports higher-order function from the beginning, since a C# function can use almost anything as its input/output, except:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static types, like System.Convert, System.Math, etc., because there cannot be a value (instance) of a static type.&lt;/li&gt;
&lt;li&gt;Special types in .NET framework, like System.Void.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A first-order function can take some data value as input and output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DataType { }

public static DataType FirstOrder(DataType dataValue)
{
    return dataValue;
}

public static void CallFirstOrder()
{
    DataType inputValue = default(DataType);
    DataType outputValue = FirstOrder(inputValue);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get a higher-order function, just replace above DataType/dataValue with a function type/function value. In C#, delegate type can be viewed as function type, and delegate instance can be viewed as function value (instance). So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate void FunctionType();

public static FunctionType HigherOrder(FunctionType functionValue)
{
    return functionValue;
}

public static void CallHigherOrder()
{
    FunctionType inputValue = default(FunctionType);
    FunctionType outputValue = HigherOrder(inputValue);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above HigherOrder becomes a higher-order function takes function as input and output.&lt;/p&gt;
&lt;p&gt;Besides named function, anonymous first-order/higher-order functions can be easily expressed with lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrderFunction
{
    public static void Lambda()
    {
        Action firstOrder1 = () =&amp;gt; { };
        Action&amp;lt;Action&amp;gt; higherOrder1 = action =&amp;gt; action();

        Func&amp;lt;int&amp;gt; firstOrder2 = () =&amp;gt; default(int);
        Func&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt; higherOrder2 = () =&amp;gt; firstOrder2;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Higher-order functions are everywhere in .NET framework, like fore mentioned Sort method of List&amp;lt;T&amp;gt;. It’s signature is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public class List&amp;lt;T&amp;gt;
    {
        public void Sort(Comparison&amp;lt;T&amp;gt; comparison);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its comparison parameter is a function value of Comparison&amp;lt;T&amp;gt; function type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate int Comparison&amp;lt;in T&amp;gt;(T x, T y);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most LINQ query methods are higher-order functions, like Where. Its signature is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its predicate parameter is a function value of function type Func&amp;lt;TSource, bool&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LinqToObjects
{
    public static IEnumerable&amp;lt;int&amp;gt; Positive(IEnumerable&amp;lt;int&amp;gt; source)
    {
        return source.Where(value =&amp;gt; value &amp;gt; 0);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;First-class function&lt;/h2&gt;
&lt;p&gt;So far C# has been demonstrated to have &lt;a href=&quot;https://en.wikipedia.org/wiki/First-class_function&quot;&gt;first class functions&lt;/a&gt;. C# function can be compared to C# object side by side:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;767&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Data (object)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Function (method)&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Type&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Object type: class&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Function type: delegate type&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Value&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Object: class instance&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Function value: delegate instance&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Assignment&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Can be assigned to variable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Can be assigned to variable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Storage&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Can be stored in data structure&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Can be stored in data structure&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Input&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Can be function’s parameter&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Can be higher-order function’s parameter&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Output&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Can be function’s return value&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Can be higher-order function’s return value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Nesting&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Can be nested (e.g. Exception.InnerException)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Can be nested (function in function): anonymous function, lambda expression, closure with non-local variable access&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;87&quot;&amp;gt;Equality&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;236&quot;&amp;gt;Reference equality testable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;442&quot;&amp;gt;Reference equality testable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;They can have type and instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FirstClass
{
    public class ObjectType
    {
        public ObjectType InnerObject { get; set; }
    }

    public delegate void FunctionType();

    public static void ObjectInstance()
    {
        ObjectType objectValue = new ObjectType();
    }

    public static void FunctionInstance()
    {
        FunctionType functionValue1 = FunctionInstance; // Named function.
        FunctionType functionValue2 = () =&amp;gt; { }; // Anonymous function.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can be stored in data structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FirstClass
{
    public static ObjectType objectField = new ObjectType();

    public static FunctionType functionField1 = FunctionInstance; // Named function.

    public static FunctionType functionField2 = () =&amp;gt; { }; // Anonymous function.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can be function parameter and return value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FirstClass
{
    public static ObjectType InputOutputObject(ObjectType objectValue) =&amp;gt; objectValue;

    public static FunctionType InputOutputFunction(FunctionType functionValue) =&amp;gt; functionValue;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can be nested:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FirstClass
{
    public static void NestedObject()
    {
        ObjectType outerObject = new ObjectType()
        {
            InnerObject = new ObjectType()
        };
    }

    public static void NestedFunction()
    {
        object nonLocalVariable = new object();
        FunctionType outerFunction = () =&amp;gt;
            {
                object outerLocalVariable = nonLocalVariable;
                FunctionType innerFunction = () =&amp;gt;
                    {
                        object innerLocalVariable = nonLocalVariable;
                    };
            };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are reference equality testable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class FirstClass
{
    public static void ObjectEquality()
    {
        ObjectType objectValue1;
        ObjectType objectValue2;
        objectValue1 = objectValue2 = new ObjectType();
        bool areEqual1 = objectValue1 == objectValue2; // true.

        ObjectType objectValue3 = null;
        bool areEqual2 = objectValue2 == objectValue3; // false.
    }

    public static void FunctionEquality()
    {
        FunctionType functionValue1;
        FunctionType functionValue2;
        functionValue1 = functionValue2 = () =&amp;gt; { };
        bool areEqual1 = functionValue1 == functionValue2; // true.

        FunctionType functionValue3 = null;
        bool areEqual2 = functionValue2 == functionValue3; // false.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, C# treats functions as &lt;a href=&quot;https://en.wikipedia.org/wiki/First-class_citizen&quot;&gt;first-class citizen&lt;/a&gt;, just like C# objects.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (1) IQueryable&lt;T&gt; and Remote Query</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-1-iqueryable-t-and-remote-query/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-1-iqueryable-t-and-remote-query/</guid><description>The previous chapters discussed LINQ to Objects, LINQ to XML (objects), and Parallel LINQ (to Objects). All of these APIs query in memory objects managed by .NET. This chapter discusses Entity Framewo</description><pubDate>Sat, 16 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;&lt;strong&gt;LINQ via C# series&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;&lt;strong&gt;Entity Framework Core series&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;&lt;strong&gt;Entity Framework series&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-1-remote-query&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-1-remote-query&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous chapters discussed LINQ to Objects, LINQ to XML (objects), and Parallel LINQ (to Objects). All of these APIs query in memory objects managed by .NET. This chapter discusses Entity Framework, a Microsoft library providing a different kind of LINQ technology, LINQ to Entities. LINQ to Entities can access and query relational data managed by different kinds of databases, e.g.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server and Azure SQL Database (aka SQL Azure)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://download.oracle.com/oll/obe/EntityFrameworkOBE/EntityFrameworkOBE.htm&quot;&gt;Oracle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html&quot;&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.devart.com/dotconnect/postgresql/articles/tutorial_ef.html&quot;&gt;PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. This tutorial uses Microsoft &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh510202.aspx&quot;&gt;SQL Server LocalDB&lt;/a&gt; with the Microsoft AdventureWorks sample database as the data source. SQL Server LocalDB is a free, lightweight SQL Server &lt;a href=&quot;http://download.microsoft.com/download/D/7/D/D7D64E12-C8E5-4A8C-A104-C945C188FA99/SQL_Server_2014_Datasheet.pdf&quot;&gt;edition&lt;/a&gt;. It is &lt;a href=&quot;https://blogs.msdn.microsoft.com/sqlexpress/2011/07/12/introducing-localdb-an-improved-sql-express/&quot;&gt;extremely easy to install/use, but with rich programmability&lt;/a&gt;. Please follow these step to setup:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-in/download/details.aspx?id=52679&quot;&gt;Download SQL Server LocalDB&lt;/a&gt;, and use the installer to download SQL Server LocalDB and install. Zero configuration is required for installation. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt238290.aspx&quot;&gt;Download SQL Server Management Tools&lt;/a&gt; and install. &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh213248.aspx&quot;&gt;This includes&lt;/a&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/SQL_Server_Management_Studio&quot;&gt;SQL Server Management Studio&lt;/a&gt;, a free integration environment to manage SQL Server and SQL database.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms181091.aspx&quot;&gt;SQL Server Profiler&lt;/a&gt;, a free trace tool. This tutorial will use it to uncover how Entity Framework works with the SQL data source.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;(Optional) &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt204009.aspx&quot;&gt;Download SQL Server Data Tools&lt;/a&gt; and install. It is a free Visual Studio extension, and enables SQL database management inside Visual Studio.&lt;/li&gt;
&lt;li&gt;Download and install Microsoft SQL Server sample databases AdventureWorks. The &lt;a href=&quot;http://msftdbprodsamples.codeplex.com/&quot;&gt;full database from Microsoft&lt;/a&gt; will be about 205MB, so a compacted and shrunk version of the AdventureWorks database is provided for this tutorial. It is only 34MB, and is available from &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/tree/master/Data&quot;&gt;GitHub&lt;/a&gt;. Just download the &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/blob/master/Data/AdventureWorks_Data.mdf&quot;&gt;AdventureWorks_Data.mdf&lt;/a&gt; file and the &lt;a href=&quot;https://github.com/Dixin/CodeSnippets/blob/master/Data/AdventureWorks_Log.ldf&quot;&gt;AdventureWorks_Log.ldf&lt;/a&gt; file to the same directory.&lt;/li&gt;
&lt;li&gt;Install Entity Framework library to code project:&lt;pre&gt;&lt;code&gt;Install-Package EntityFramework
&lt;/code&gt;&lt;/pre&gt;
By default, 2 assemblies will be added to the references: EntityFramework.dll and EntityFramework.SqlServer.dll. Entity Framework implements a provider model to support different kinds of databases, so EntityFramework.dll has the general functionalities for all the databases, and EntityFramewwork.SqlServer.dll implements SQL database specific functionalities.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Remote query vs. local query&lt;/h2&gt;
&lt;p&gt;LINQ to Objects and Parallel LINQ query .NET objects in current .NET process’s local memory, these queries are called local queries. LINQ to XML queries XML data source, which are .NET XML objects in local memory as well, so LINQ to XML queries are also local queries. As demonstrated at the beginning of this tutorial, LINQ can also query data in another domain, like tweets in Twitter, rows in database tables, etc. Apparently, these data source are not .NET objects directly available in local memory. These queries are called remote queries.&lt;/p&gt;
&lt;p&gt;A local LINQ to Objects data source is represented by IEnumerable&amp;lt;T&amp;gt;. A remote LINQ data source, like a table in database, is represented by IQueryable&amp;lt;T&amp;gt;. Similar to ParallelQuery&amp;lt;T&amp;gt; discussed in the Parallel LINQ chapter, IQueryable&amp;lt;T&amp;gt; is another parity with IEnumerbale&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;table cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;600&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;Sequential LINQ&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;Parallel LINQ&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;LINQ to Entities&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IEnumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;ParallelQuery&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IQueryable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;ParallelQuery&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IQueryable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IOrderedEnumerable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;OrderedParallelQuery&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;IOrderedQueryable&amp;lt;T&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;Enumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;ParallelEnumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;200&quot;&amp;gt;Queryable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable : IEnumerable
    {
        Expression Expression { get; }

        Type ElementType { get; }

        IQueryProvider Provider { get; }
    }

    public interface IOrderedQueryable : IQueryable, IEnumerable
    {
    }

    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerable, IQueryable
    {
    }

    public interface IOrderedQueryable&amp;lt;out T&amp;gt; : IQueryable&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IOrderedQueryable, IQueryable, IEnumerable
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; has many implementations, like array in mscorlib.dll, Microsoft.Collections.Immutable.ImmutableList&amp;lt;T&amp;gt; in System.Collections.Immutable.dll, etc. Here Entity Framework provides several IQueryable&amp;lt;T&amp;gt; implementations, like System.Data.Entity.Infrastructure.DbQuery&amp;lt;T&amp;gt; and System.Data.Entity.DbSet&amp;lt;T&amp;gt; in EntityFramework.dll, etc. DbQuery&amp;lt;T&amp;gt; and DbSet&amp;lt;T&amp;gt; will be used all over this chapter. Please see the LINQ to Objects chapter for the full implementation/inheritance hierarchy for IEnumerable&amp;lt;T&amp;gt;, ParallelQuery&amp;lt;T&amp;gt;, and IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;Queryable class defines all the extension methods for IQueryable&amp;lt;T&amp;gt;, which are parities with Enumerable class’s methods. For example, here are the Where/Select/Concat methods side by side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

        public static IEnumerable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; selector);

        public static IEnumerable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; first, IEnumerable&amp;lt;TSource&amp;gt; second);

        // More query methods...
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate);

        public static IQueryable&amp;lt;TResult&amp;gt; Select&amp;lt;TSource, TResult&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TResult&amp;gt;&amp;gt; selector);

        public static IQueryable&amp;lt;TSource&amp;gt; Concat&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source1, IQueryable&amp;lt;TSource&amp;gt; source2);

        // More query methods...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And similarly, the ordering methods side by side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class Enumerable
    {
        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);

        public static IOrderedEnumerable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector);
    }

    public static class Queryable
    {
        public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);

        public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenByDescending&amp;lt;TSource, TKey&amp;gt;(
            this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this design, the fluent method chaining and the LINQ query expressions pattern works smoothly for remote LINQ queries.&lt;/p&gt;
&lt;p&gt;Queryable class does not provide the following query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AsEnumerable: it returns an IEnumerable&amp;lt;T&amp;gt; representing a sequence of .NET objects, and this method is already provided by Enumerable in LINQ to Objects&lt;/li&gt;
&lt;li&gt;Empty/Range/Repeat: it does not make sense for .NET to generate a remote data source for further remote queries; the other generation method, DefaultIfEmpty, is available, because DefaultIfEmpty generates from an input IQuerable&amp;lt;T&amp;gt; source.&lt;/li&gt;
&lt;li&gt;Max/Min overloads for .NET primary types: these .NET primitive types may not exist in the remote data source, like a SQL/Oracle/MySQL database, also LINQ to Objects has provided these methods to query these .NET primitive values in local memory.&lt;/li&gt;
&lt;li&gt;ToArray/ToDictionary/ToList/ToLookup: similarly, collection types like array, dictionary, … may not exist in the remote data source, also LINQ to Objects has provided these methods to pull values from data source and convert to .NET collections.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Queryable provides an additional query method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AsQueryable: unlike to AsSequential/AsParallel, AsEnumerable/AsQueryable cannot switch between local LINQ to Objects query and remote LINQ to Entities query. This method will be discussed later.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Function vs. expression tree&lt;/h2&gt;
&lt;p&gt;As discussed in the C# chapter, the major difference is Enumerable query methods accepts functions, and Queryable methods accepts expression trees. Functions are executable .NET code, and expression trees are .NET data objects representing abstract syntax trees, which can be translated to other domain-specific language. In the C# chapter, the expression tree part demonstrated compiling an arithmetic expression tree into IL code at runtime, and execute it dynamically. The same approach can be used to translate an arithmetic expression tree to SQL query and execute it inside SQL Server.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class InfixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;string&amp;gt;
{
    protected override string VisitAdd
        (BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, &quot;+&quot;, expression);

    protected override string VisitConstant
        (ConstantExpression constant, LambdaExpression expression) =&amp;gt; constant.Value.ToString();

    protected override string VisitDivide
        (BinaryExpression divide, LambdaExpression expression) =&amp;gt; this.VisitBinary(divide, &quot;/&quot;, expression);

    protected override string VisitMultiply
        (BinaryExpression multiply, LambdaExpression expression) =&amp;gt; this.VisitBinary(multiply, &quot;*&quot;, expression);

    protected override string VisitParameter
        (ParameterExpression parameter, LambdaExpression expression) =&amp;gt; $&quot;@{parameter.Name}&quot;;

    protected override string VisitSubtract
        (BinaryExpression subtract, LambdaExpression expression) =&amp;gt; this.VisitBinary(subtract, &quot;-&quot;, expression);

    private string VisitBinary
        (BinaryExpression binary, string @operator, LambdaExpression expression) =&amp;gt;
            $&quot;({this.VisitNode(binary.Left, expression)} {@operator} {this.VisitNode(binary.Right, expression)})&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please see the expression tree part in the C# chapter for the definition of BinaryArithmeticExpressionVisitor&amp;lt;T&amp;gt;. Above InfixVisitor can traverse an arithmetic expression tree, and output infix expression string, which can work in SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void Translate()
    {
        InfixVisitor infixVisitor = new InfixVisitor();
        Expression&amp;lt;Func&amp;lt;double, double, double&amp;gt;&amp;gt; expression1 = (a, b) =&amp;gt; a * a + b * b;
        string infixExpression1 = infixVisitor.VisitBody(expression1);
        Trace.WriteLine(infixExpression1); // ((@a * @a) + (@b * @b))

        Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression2 =
            (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
        string infixExpression2 = infixVisitor.VisitBody(expression2);
        Trace.WriteLine(infixExpression2); // (((@a + @b) - ((@c * @d) / 2)) + (@e * 3))
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice @ is prepended to parameter name, so that the result expression string can be used in SQL query as SELECT expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class BinaryArithmeticTranslator
{
    [SuppressMessage(&quot;Microsoft.Security&quot;, &quot;CA2100:Review SQL queries for security vulnerabilities&quot;)]
    internal static double ExecuteSql(
        string connection,
        string arithmeticExpression,
        IEnumerable&amp;lt;KeyValuePair&amp;lt;string, double&amp;gt;&amp;gt; parameters)
    {
        using (SqlConnection sqlConnection = new SqlConnection(connection))
        using (SqlCommand command = new SqlCommand($&quot;SELECT {arithmeticExpression}&quot;, sqlConnection))
        {
            sqlConnection.Open();
            parameters.ForEach(parameter =&amp;gt; command.Parameters.AddWithValue(parameter.Key, parameter.Value));
            return (double)command.ExecuteScalar();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following Sql method can accept an arithmetic expression tree, and emit a dynamic method the at runtime. When the returned dynamic method is called, the arithmetic expression tree will be translated to SQL query, and executed in SQL&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class BinaryArithmeticTranslator
{
    private static readonly InfixVisitor InfixVisitor = new InfixVisitor();

    public static TDelegate Sql&amp;lt;TDelegate&amp;gt;(
        Expression&amp;lt;TDelegate&amp;gt; expression, string connection = ConnectionStrings.LocalDb)
        where TDelegate : class
    {
        DynamicMethod dynamicMethod = new DynamicMethod(
            string.Empty,
            expression.ReturnType,
            expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
            typeof(BinaryArithmeticTranslator).Module);
        EmitIL(dynamicMethod.GetILGenerator(), InfixVisitor.VisitBody(expression), expression, connection);
        return dynamicMethod.CreateDelegate(typeof(TDelegate)) as TDelegate;
    }

    private static void EmitIL&amp;lt;TDelegate&amp;gt;(ILGenerator ilGenerator, string infixExpression, Expression&amp;lt;TDelegate&amp;gt; expression, string connection)
    {
        // Dictionary&amp;lt;string, double&amp;gt; dictionary = new Dictionary&amp;lt;string, double&amp;gt;();
        ilGenerator.DeclareLocal(typeof(Dictionary&amp;lt;string, double&amp;gt;));
        ilGenerator.Emit(
            OpCodes.Newobj,
            typeof(Dictionary&amp;lt;string, double&amp;gt;).GetConstructor(Array.Empty&amp;lt;Type&amp;gt;()));
        ilGenerator.Emit(OpCodes.Stloc_0);

        for (int index = 0; index &amp;lt; expression.Parameters.Count; index++)
        {
            // dictionary.Add($&quot;@{expression.Parameters[i].Name}&quot;, args[i]);
            ilGenerator.Emit(OpCodes.Ldloc_0); // dictionary.
            ilGenerator.Emit(OpCodes.Ldstr, $&quot;@{expression.Parameters[index].Name}&quot;);
            ilGenerator.Emit(OpCodes.Ldarg_S, index);
            ilGenerator.Emit(
                OpCodes.Callvirt,
                typeof(Dictionary&amp;lt;string, double&amp;gt;).GetMethod(
                    nameof(Dictionary&amp;lt;string, double&amp;gt;.Add),
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod));
        }

        // BinaryArithmeticTanslator.ExecuteSql(connection, expression, dictionary);
        ilGenerator.Emit(OpCodes.Ldstr, connection);
        ilGenerator.Emit(OpCodes.Ldstr, infixExpression);
        ilGenerator.Emit(OpCodes.Ldloc_0);
        ilGenerator.Emit(
            OpCodes.Call,
            typeof(BinaryArithmeticTranslator).GetMethod(
                nameof(ExecuteSql),
                BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod));

        // Returns the result of ExecuteSql.
        ilGenerator.Emit(OpCodes.Ret);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a connection string is not provided to Sql method, it takes a default connection string of SQL Server LocalDB:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ConnectionStrings
{
    internal const string LocalDb = @&quot;Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True;Connect Timeout=30&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how to use Sql method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Execute()
{
    Expression&amp;lt;Func&amp;lt;double, double, double&amp;gt;&amp;gt; expression1 = (a, b) =&amp;gt; a * a + b * b;
    Func&amp;lt;double, double, double&amp;gt; local1 = expression1.Compile();
    Trace.WriteLine(local1(1, 2)); // 5
    Func&amp;lt;double, double, double&amp;gt; remote1 = BinaryArithmeticTranslator.Sql(expression1);
    Trace.WriteLine(remote1(1, 2)); // 5

    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; expression2 =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
    Func&amp;lt;double, double, double, double, double, double&amp;gt; local2 = expression2.Compile();
    Trace.WriteLine(local2(1, 2, 3, 4, 5)); // 12
    Func&amp;lt;double, double, double, double, double, double&amp;gt; remote2 = BinaryArithmeticTranslator.Sql(expression2);
    Trace.WriteLine(remote2(1, 2, 3, 4, 5)); // 12
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, the Expression&amp;lt;TDelegate&amp;gt;.Compile method emits a method that executes the arithmetic computation locally in CLR. In contrast, BinaryArithmeticTranslator.Sql emits a method that calls ExecuteSql and executes the arithmetic computation remotely in a SQL Server.&lt;/p&gt;
&lt;h2&gt;Trace SQL query execution&lt;/h2&gt;
&lt;p&gt;It would be nice if the actual SQL query execution can be observed. SQL Server provides a free tool SQL Server Profiler for this. FOr this tutorial, a little bit configuration is needed. Start SQL Server Profiler, Go to File =&amp;gt; Templates =&amp;gt; New Template. In the General tab, type a trace template name:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the Events Selection tab, select a few events to trace:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stored Procedures&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RPC: Completed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RPC: Starting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TSQL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SQL: BatchCompleted&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SQL: BatchStarting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transactions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Begin Tran completed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Begin Tran starting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Commit Tran completed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Commit Tran starting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Rollback Tran completed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TM: Rollback Tran starting&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click Save to save this trace template.&lt;/p&gt;
&lt;p&gt;Another optional configuration is font. The default font is &lt;a href=&quot;https://en.wikipedia.org/wiki/Lucida#Lucida_Console&quot;&gt;Lucida Console&lt;/a&gt;. It can be changed to Visual Studio’s font (&lt;a href=&quot;https://en.wikipedia.org/wiki/Consolas&quot;&gt;Consolas&lt;/a&gt; by default) for visual consistency.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_16.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To start tracing, Click File =&amp;gt; New Trace, specify Server name as (LocalDB)\MSSQLLocalDB, which is the same as the Data Source value in above connection string:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click Connect, the Trace Properties dialog pops up. Select the trace template just created:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click Run, the trace is started. Now, execute above code that calls BinaryArithmeticTranslator.Sql, the following events are traced:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_22.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_10.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Entity-Framework-1_13528/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the executed SQL commands prove that the arithmetic expressions are executed remotely in SQL Server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT ((@a * @a) + (@b * @b))&apos;,N&apos;@a float,@b float&apos;,@a=1,@b=2

exec sp_executesql N&apos;SELECT (((@a + @b) - ((@c * @d) / 2)) + (@e * 3))&apos;,N&apos;@a float,@b float,@c float,@d float,@e float&apos;,@a=1,@b=2,@c=3,@d=4,@e=5
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>End-to-end: Setup continuous integration/continuous delivery for ASP.NET Core + SQL database with GitHub, AppVeyor and Azure</title><link>https://dixin.github.io/posts/setup-continuous-integration-continuous-delivery-for-asp-net-core-sql-database-with-github-appveyor-and-azure/</link><guid isPermaLink="true">https://dixin.github.io/posts/setup-continuous-integration-continuous-delivery-for-asp-net-core-sql-database-with-github-appveyor-and-azure/</guid><description>I have a web project “Chinese Etymology ()” for searching Chinese character’s etymologies and ancient Chinese characters. It is developed with Microsoft tec</description><pubDate>Thu, 14 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have a web project “Chinese Etymology (&lt;a href=&quot;http://hanziyuan.net&quot;&gt;http://hanziyuan.net&lt;/a&gt;)” for searching Chinese character’s etymologies and ancient Chinese characters. It is developed with Microsoft tech stack – ASP.NET Core + SQL database. It is open source on GitHub. Its database is deployed to Azure SQL Database, and the website is deployed to Azure App Service. I will use this project to demonstrate the end-to-end workflow and setup for continuous integration/continuous delivery with AppVeyor. After these steps, when you commit code and push to your repository&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;your code will be built automatically.&lt;/li&gt;
&lt;li&gt;tests will run automatically, connecting a staging SQL database with secured connection string info.&lt;/li&gt;
&lt;li&gt;your release build will be deployed to a staging environment on Azure automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;AppVeyor&lt;/h2&gt;
&lt;p&gt;AppVeyor is a CI solution for Windows. It is free for open source projects. I used it quite a while for traditional .NET + SQL Server projects. It is extremely friendly to Microsoft technologies.&lt;/p&gt;
&lt;p&gt;To use AppVeyor with code in GitHub, just go to &lt;a href=&quot;https://appveyor.com&quot;&gt;https://appveyor.com&lt;/a&gt;, log in with GitHub account. it also supports BitBucket and VSTS (Visual Studio Team Services). Then follow the UI to connect your GitHub repository. Then you need to place a appveyor.yml configuration file at the root of your repository. You can follow the &lt;a href=&quot;https://www.appveyor.com/docs/appveyor-yml/&quot;&gt;appveyor.yml reference&lt;/a&gt; and create the file manually, and validate it with &lt;a href=&quot;https://ci.appveyor.com/tools/validate-yaml&quot;&gt;a validator provided by AppVeyor&lt;/a&gt;. Or, you can go to your AppVeyor project, click “Settings”, follow te nice UI to fill in the customization, and then export a appveyor.yml file.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AppVeyor has a &lt;a href=&quot;https://www.appveyor.com/docs/build-configuration/&quot;&gt;Build Configuration&lt;/a&gt; document, showing its entire pipeline.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;init&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clone&lt;/strong&gt; repository into clone folder
&lt;ul&gt;
&lt;li&gt;Checkout build commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd&lt;/code&gt; to clone folder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Restore build cache&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;install&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;Patch &lt;code&gt;AssemblyInfo&lt;/code&gt; and &lt;code&gt;.csproj&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Modify &lt;code&gt;hosts&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Start services&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;before_build&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;Run msbuild&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;after_build&lt;/code&gt; scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;before_test&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;Discover and run tests&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;after_test&lt;/code&gt; scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;build_success&lt;/code&gt; webhooks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Package&lt;/strong&gt; artifacts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;before_deploy&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;Run all configured deployments&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;after_deploy&lt;/code&gt; scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finalize&lt;/strong&gt; successful builds:
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;deployment_success&lt;/code&gt; webhooks&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;on_success&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;Save build cache&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finalize&lt;/strong&gt; failed builds:
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;build_failure&lt;/code&gt; webhooks&lt;/li&gt;
&lt;li&gt;Optionally save build cache&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;deployment_failure&lt;/code&gt; webhooks&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;on_failure&lt;/code&gt; scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finalize&lt;/strong&gt; both successful and failed builds:
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;on_finish&lt;/code&gt; scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Initialize environment&lt;/h2&gt;
&lt;p&gt;My project is built with ASP.NET Core 2.0, so I used the build worker image “Visual Studio 2017”, and turned on .NET Core patching:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet_csproj:
  patch: true
  file: &apos;**\*.csproj&apos;
  version: &apos;{version}&apos;
  package_version: &apos;{version}&apos;
  assembly_version: &apos;{version}&apos;
  file_version: &apos;{version}&apos;
  informational_version: &apos;{version}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also used WebPack for the website UI, so I need install Node.js and NPM:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;install:
- ps: &amp;gt;-
    Install-Product node 8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, AppVeyor runs msbuild to build the solution. So before build, dotnet restore is needed to install all the NuGet packages. npm install is also needed to install all the NPM packages.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;before_build:
- cmd: &amp;gt;-
    dotnet restore
cd ./src/Etymology.Web

    npm install

    cd ../..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is good to build.&lt;/p&gt;
&lt;h2&gt;Run tests&lt;/h2&gt;
&lt;p&gt;I am using MSTest framework. After build, the tests will be automatically discovered:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_16.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Connect to Azure SQL database with secure variables&lt;/h3&gt;
&lt;p&gt;My tests needs to connect to Azure SQL database to run. In this case, we can hide the secretes in connection string with secure variables. The following is the settings file containing the connection string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;ConnectionStrings&quot;: {
    &quot;Etymology&quot;: &quot;Server=tcp:{server}.database.windows.net,1433;Initial Catalog={database};Persist Security Info=False;User ID={user};Password={password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file is committed to repository and exposed to public. Now encrypt the real values in AppVeyor with &lt;a href=&quot;https://ci.appveyor.com/tools/encrypt&quot;&gt;its encryption tool&lt;/a&gt; or UI:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now these encrypted secretes can go to appveyor.yml and expose to public, along with other &lt;a href=&quot;https://www.appveyor.com/docs/environment-variables/&quot;&gt;environment variables&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  Server:
    secure: TvXoVEeYYNoo2cXBZTeGuQ==
  Database:
    secure: VoBmaLf7l0+NV1kGgG+wPg==
  User:
    secure: UzHGGTiu63CYQPT9rPKhJA==
  Password:
    secure: si1rZXqiINGCaeQU0Oh7hg==
  APPVEYOR_RDP_PASSWORD:
    secure: aii6TuA5V1pzlqRiUOXyTQ==
  ASPNETCORE_ENVIRONMENT: Staging
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In AppVeyor, these secure variables can be access just like othernormal environment variables. So before build, just replace the connection string with decrypted values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;install:
- ps: &amp;gt;-
    Install-Product node 8
$file = &quot;$($env:appveyor_build_folder)\src\Etymology.Web\Server\settings.$($env:ASPNETCORE_ENVIRONMENT).json&quot;

    (Get-Content $file).Replace(&quot;{server}&quot;, $env:Server).Replace(&quot;{database}&quot;, $env:Database).Replace(&quot;{user}&quot;, $env:User).Replace(&quot;{password}&quot;, $env:Password) | Set-Content $file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the settings file has the real connection string info.&lt;/p&gt;
&lt;p&gt;On the Azure side, go to the SQL database’s server, in the firewall settings, whitelist &lt;a href=&quot;https://www.appveyor.com/docs/build-environment/#ip-addresses&quot;&gt;all AppVeyor build worker IP addresses&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Connect to on-premise SQL Server database&lt;/h3&gt;
&lt;p&gt;What if on-premise SQL Server is used? I have an .NET Framework project using .mdf and ldf files with SQL Server LocalDB. In AppVeyor, I just enable SQL Server, attach the .mdf and ldf files, and update the connection string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services: mssql2016
before_test:
- ps: &amp;gt;-
    $server = &quot;(local)\SQL2016&quot;

    $database = &quot;AdventureWorks&quot;
# Replace the db connection with the local instance.

    $configPath = &quot;$($env:appveyor_build_folder)\EntityFramework.Functions.Tests\bin\$($env:CONFIGURATION)\EntityFramework.Functions.Tests.dll.config&quot;

    $config = (gc $configPath) -as [xml]

    $config.SelectSingleNode(&apos;//connectionStrings/add[@name=&quot;EntityFramework.Functions.Tests.Properties.Settings.AdventureWorksConnectionString&quot;]&apos;).connectionString = &quot;Server=$server; Database=$database; Trusted_connection=true&quot;

    $config.Save($configPath)
# Attach mdf to local instance.

    $databaseDirectory = &quot;$($env:appveyor_build_folder)\Data&quot;

    $mdfPath = join-path $databaseDirectory &quot;AdventureWorks_Data.mdf&quot;

    $ldfPath = join-path $databaseDirectory &quot;AdventureWorks_Log.ldf&quot;

    sqlcmd -S &quot;$server&quot; -Q &quot;Use [master]; CREATE DATABASE [$database] ON (FILENAME = &apos;$mdfPath&apos;),(FILENAME = &apos;$ldfPath&apos;) FOR ATTACH&quot;

    sqlcmd -S &quot;$server&quot; -Q &quot;Use [$database]; EXEC sys.sp_configure @configname = N&apos;clr enabled&apos;, @configvalue = 1;&quot;

    sqlcmd -S &quot;$server&quot; -Q &quot;Use [$database]; RECONFIGURE;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Deploy to Azure&lt;/h2&gt;
&lt;p&gt;First got to Azure, create a App Service on Azure. If you do not have an Azure account/subscription, you can go to Dev Essentials and get a free one. Here I created a App Service of free pricing tier from &lt;a href=&quot;https://portal.azure.com&quot;&gt;https://portal.azure.com&lt;/a&gt;. Since my code detects the environment, I also used the portal to add environment variable “ASPNETCORE_ENVIRONMENT”, and set it to “Staging”.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also create a user name/password for deployment:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now go to AppVeyor.By default, AppVeyor calls msbuild to build the solution, which is good for .NET Core projects. For my ASP.NET Core projects, I run the “dotnet publish” after running tests to export all binaries and resources (HTML, CSS, JavaScript, images, settings) to a Publish/{BuildConfiguration} directory.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since only the release build needs to be deployed, create an artifact “PublishRelease”, which can be viewed as an alias pointing to the Publish/Release directory.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_14.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then enable packaging for xcopy deployment:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And specify the Azure deployment credential user name and password created just now, as well as the above artifact to deploy:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_8.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The YAML will be like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;build:
  publish_wap_xcopy: true
  parallel: true
  verbosity: detailed
after_test:
- ps: dotnet publish ./src/Etymology.Web/Etymology.Web.csproj -c $env:CONFIGURATION -o ../../Publish/$env:CONFIGURATION
artifacts:
- path: ./Publish/Release
  name: PublishRelease
deploy:
- provider: AzureAppServiceZipDeploy
  appservice_environment: false
  website: etymologystaging
  username: dixinyan
  password:
    secure: aii6TuA5V1pzlqRiUOXyTQ==
  artifact: PublishRelease
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Debug build will not be deployed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[00:11:22] Collecting artifacts... [00:11:23] No artifacts found matching &apos;Publish\Release&apos; path [00:11:23] Deploying using AzureAppServiceZipDeploy provider [00:11:23] No Zip artifacts were found. Only Zip artifacts can be published as Azure App Service Zip Push Deploy. Make sure you have specified correct artifacts filter. [00:11:23] If you are using AppVeyor Web Application packaging, please ensure that you selected &apos;Package Web Applications for XCopy deployment&apos; (&apos;publish_wap_xcopy: true&apos; in YAML). [00:11:23] Build success&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And the Release build will be deployed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[00:10:36] Collecting artifacts... [00:10:36] Found artifact &apos;Publish\Release&apos; matching &apos;Publish\Release&apos; path [00:10:36] Uploading artifacts... [00:10:36] [00:10:40] [1/1] PublishRelease...Zipping to PublishRelease.zip [00:10:40] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...1% [00:10:40] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...10% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...20% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...30% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...40% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...50% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...60% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...70% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...80% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...90% [00:10:41] [1/1] Publish\PublishRelease.zip (19,221,277 bytes)...100% [00:10:41] Deploying using AzureAppServiceZipDeploy provider [00:10:58] Deploying &quot;PublishRelease.zip&quot; to &quot;*****staging&quot; site...OK [00:10:59] Build success&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Remote desktop debugging&lt;/h2&gt;
&lt;p&gt;AppVeyor also supports debugging with remote desktop. To enable this, add a secure variable “APPVEYOR_RDP_PASSWORD”, which will be your remote desktop password. Then add the following command:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Continuous-Integration-with-GitHub-AppVe_2A0D/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It will print the connection info at the very beginning of the build console:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[00:00:00] Build started [00:00:00] iex ((new-object net.webclient).DownloadString(&apos;&lt;a href=&quot;https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1&apos;))&quot;&gt;https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1&apos;))&lt;/a&gt; [00:00:03] Remote Desktop connection details: [00:00:03] Server: 67.225.139.254:33923 [00:00:03] Username: appveyor&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You may get an authentication error due to CredSSP encryption oracle remediation:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_6.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/dbe535fb50d4_1579/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If so, please follow &lt;a href=&quot;/posts/remote-desktop-connection-authentication-error-due-to-credssp-encryption-oracle-remediation&quot;&gt;another post of mine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The full appveyor.yml can be viewed on GitHub: &lt;a href=&quot;https://github.com/Dixin/Etymology/blob/master/appveyor.yml&quot;&gt;https://github.com/Dixin/Etymology/blob/master/appveyor.yml&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Easy Ways to Test SQL Server/SQL Azure Connection</title><link>https://dixin.github.io/posts/easy-ways-to-test-sql-server-sql-azure-connection/</link><guid isPermaLink="true">https://dixin.github.io/posts/easy-ways-to-test-sql-server-sql-azure-connection/</guid><description>It is incredibly easy to test the SQL Server/Azure SQL Database connectivity or firewall settings from Windows, even without SSMS ([SQL Server Management Studio](https://en.wikipedia.org/wiki/SQL_Serv</description><pubDate>Mon, 11 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It is incredibly easy to test the SQL Server/Azure SQL Database connectivity or firewall settings from Windows, even without SSMS (&lt;a href=&quot;https://en.wikipedia.org/wiki/SQL_Server_Management_Studio&quot;&gt;SQL Server Management Studio&lt;/a&gt;) or coding.&lt;/p&gt;
&lt;h2&gt;Test with ODBC Data Source&lt;/h2&gt;
&lt;p&gt;In Windows, press the Win key, type “data source”, press enter to open the &lt;a href=&quot;https://en.wikipedia.org/wiki/Open_Database_Connectivity&quot;&gt;ODBC Data Sources&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_10.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click “Add” to add a data source:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_12.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Select SQL Server:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_18.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fill in the server name of SQL Server/SQL Azure server name:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_20.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and credentials:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_24.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_11.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click all the way to finish, the following dialog pops up:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_26.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_12.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now click “Test Data Source” to test it:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_30.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_14.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Microsoft SQL Server ODBC Driver Version 10.00.10586&lt;/p&gt;
&lt;p&gt;Running connectivity tests...&lt;/p&gt;
&lt;p&gt;Attempting connection Connection established Verifying option settings Disconnecting from server&lt;/p&gt;
&lt;p&gt;TESTS COMPLETED SUCCESSFULLY!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Test with UDL (Universal data link)&lt;/h2&gt;
&lt;p&gt;It can be even easier to test with &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Data_Access_Components#Universal_data_link&quot;&gt;UDL (Universal data link)&lt;/a&gt;. In Windows, create an arbitrary file:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_36.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_17.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rename its extension name to .udl:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_38.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_18.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Double click it, and fill in the connection info:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_40.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_19.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click “Test Connection”, it is done:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_42.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/3587b12d222c_11751/image_thumb_20.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Detect Chinese Character in Unicode String</title><link>https://dixin.github.io/posts/detect-chinese-character-in-unicode-string/</link><guid isPermaLink="true">https://dixin.github.io/posts/detect-chinese-character-in-unicode-string/</guid><description>Recently, when trying to convert some directory/file names between Chinese and English, it is necessary to detect if a Unicode string contains Chinese characters. Unfortunately, Chinese language detec</description><pubDate>Sun, 10 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, when trying to convert some directory/file names between Chinese and English, it is necessary to detect if a Unicode string contains Chinese characters. Unfortunately, Chinese language detection, or language detection, is &lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20120111-00/?p=8603&quot;&gt;not easy&lt;/a&gt;. There are several options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://msdn.microsoft.com/en-us/goglobal/dd156834.aspx#ELS8&quot;&gt;API&lt;/a&gt; of &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/dd319066.aspx&quot;&gt;Microsoft Language Detection&lt;/a&gt; in &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/dd317839.aspx&quot;&gt;Extended Linguistic Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff512411.aspx&quot;&gt;Detect API&lt;/a&gt; of &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff512423.aspx&quot;&gt;Microsoft Translator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft has a sample &lt;a href=&quot;http://research.microsoft.com/en-us/downloads/5a84b263-41d6-4ce1-a186-8e3f76efe2e5/&quot;&gt;C# package for language identification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Take the character range of East Asia languages (&lt;a href=&quot;http://www.unicode.org/charts/PDF/U4E00.pdf&quot;&gt;CJK Unified Ideographs (Han)&lt;/a&gt;, where &lt;a href=&quot;http://www.unicode.org/faq/han_cjk.html&quot;&gt;CJK&lt;/a&gt; means Chinese-Japanese-Korean) from the &lt;a href=&quot;http://www.unicode.org/charts/&quot;&gt;Unicode charts&lt;/a&gt;, and detect whether each character is in the range.&lt;/li&gt;
&lt;li&gt;Use Google Chrome’s &lt;a href=&quot;https://github.com/mikemccand/chromium-compact-language-detector&quot;&gt;language detector&lt;/a&gt;, since Chrome is &lt;a href=&quot;http://src.chromium.org/viewvc/chrome/trunk/src/third_party/cld/&quot;&gt;open source&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are all practical, but it would be nice if there is a &lt;a href=&quot;https://en.wikipedia.org/wiki/KISS_principle&quot;&gt;simple stupid&lt;/a&gt; solution. Actually .NET has an infamous enum &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.globalization.unicodecategory.aspx&quot;&gt;System.Globalization.UnicodeCategory&lt;/a&gt;, it has 29 members:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UppercaseLetter&lt;/li&gt;
&lt;li&gt;LowercaseLetter&lt;/li&gt;
&lt;li&gt;OpenPunctuation&lt;/li&gt;
&lt;li&gt;ClosePunctuation&lt;/li&gt;
&lt;li&gt;MathSymbol&lt;/li&gt;
&lt;li&gt;OtherLetter&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And there are 2 APIs accepting a char and returning the char’s UnicodeCategory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;char.GetUnicodeCategory&lt;/li&gt;
&lt;li&gt;CharUnicodeInfo.GetUnicodeCategory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, generally, the following extension method detects if a string contains char in the specified UnicodeCategory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool Any(this string value, UnicodeCategory category) =&amp;gt;
    !string.IsNullOrWhiteSpace(value)
    &amp;amp;&amp;amp; value.Any(@char =&amp;gt; char.GetUnicodeCategory(@char) == category);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chinese characters are categorized into OtherLetter, so the Chinese detection problem can becomes OtherLetter detection.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool HasOtherLetter(this string value) =&amp;gt; value.Any(UnicodeCategory.OtherLetter);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The detection is easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool hasOtherLetter = text.HasOtherLetter();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is not totally accurate for Chinese language, but it works very well to distinguish English string and Chinese string.&lt;/p&gt;
</content:encoded></item><item><title>Entity Framework and LINQ to Entities (7) Data Changes</title><link>https://dixin.github.io/posts/entity-framework-and-linq-to-entities-7-data-changes/</link><guid isPermaLink="true">https://dixin.github.io/posts/entity-framework-and-linq-to-entities-7-data-changes/</guid><description>Besides LINQ to Entities queries, Entity Framework also provides rich APIs for data changes.</description><pubDate>Sun, 10 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework%20Core&quot;&gt;Entity Framework Core series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;[&lt;a href=&quot;/archive/?tag=Entity%20Framework&quot;&gt;Entity Framework series&lt;/a&gt;]&lt;/h2&gt;
&lt;h2&gt;&lt;strong&gt;EF Core version of this article:&lt;/strong&gt; &lt;a href=&quot;/posts/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&quot;&gt;&lt;strong&gt;https://weblogs.asp.net/dixin/entity-framework-core-and-linq-to-entities-7-data-changes-and-transactions&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Besides LINQ to Entities queries, Entity Framework also provides rich APIs for data changes.&lt;/p&gt;
&lt;h2&gt;Repository pattern and unit of work pattern&lt;/h2&gt;
&lt;p&gt;In Entity Framework, DbSet&amp;lt;T&amp;gt; implements &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff649690.aspx&quot;&gt;repository pattern&lt;/a&gt;. Repositories centralizes data access for applications, and mediates between the data source layer/tier and the business layers/tiers. A DbSet&amp;lt;T&amp;gt; object can be mapped to a database table, which is a repository for data &lt;a href=&quot;https://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD (create, read, update and delete)&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    public interface DbSet&amp;lt;TEntity&amp;gt; : DbQuery&amp;lt;TEntity&amp;gt;, IQueryable&amp;lt;TEntity&amp;gt; // Other interfaces.
        where TEntity : class
    {
        public virtual TEntity Add(TEntity entity);

        public virtual IEnumerable&amp;lt;TEntity&amp;gt; AddRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        public virtual TEntity Find(params object[] keyValues);

        public virtual TEntity Remove(TEntity entity);

        public virtual IEnumerable&amp;lt;TEntity&amp;gt; RemoveRange(IEnumerable&amp;lt;TEntity&amp;gt; entities);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IQueryable&amp;lt;T&amp;gt; is implemented so that data can be read. Find is also provided to read data by primary keys. After reading, the retrieved data can be changed. Add and AddRange adds data to be created in the repository. Remove and RemoveRange remove data to be deleted in the repository.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot;&gt;unit of work&lt;/a&gt; is a collection of data operations that should succeed or fail as a unit. DbContext implements unit of work pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity
{
    using System.Data.Entity.Infrastructure;

    public class DbContext : IDisposable // Other interfaces.
    {
        public DbChangeTracker ChangeTracker { get; }

        public void Dispose();

        public virtual int SaveChanges();

        public virtual DbSet Set(Type entityType);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the mapping of database, DbContext’s Set method and its derived class’ mapping properties provide the access to repositories for data operations, it can also track the data changes from these data operations, and save all changes to database as a unit.&lt;/p&gt;
&lt;h2&gt;Track entities and changes&lt;/h2&gt;
&lt;p&gt;DbContext.ChangeTracker property returns a System.Data.Entity.Infrastructure.DbCangeTracker object, which can track entities for the source DbContext object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure
{
    public class DbChangeTracker
    {
        public void DetectChanges();

        public IEnumerable&amp;lt;DbEntityEntry&amp;gt; Entries();

        public IEnumerable&amp;lt;DbEntityEntry&amp;lt;TEntity&amp;gt;&amp;gt; Entries&amp;lt;TEntity&amp;gt;() where TEntity : class;

        public bool HasChanges();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The non generic Entries method returns the tracking information for all tracked entities. Each entity’s tracking information is represented by a System.Data.Entity.Infrastructure.DbEntityEntry object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure
{
    public class DbEntityEntry
    {
        public DbPropertyValues CurrentValues { get; }

        public object Entity { get; }

        public DbPropertyValues OriginalValues { get; }

        public EntityState State { get; set; }

        public DbPropertyValues GetDatabaseValues();

        public DbPropertyEntry Property(string propertyName);

        public void Reload();

        public DbEntityEntry&amp;lt;TEntity&amp;gt; Cast&amp;lt;TEntity&amp;gt;() where TEntity : class;

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbEntityEntry provides rich APIs for entity’s state management:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Entity property above returns the tracked entity&lt;/li&gt;
&lt;li&gt;State returns the entity’s tracking state: Detached, Unchanged, Added, Deleted, or Modified.&lt;/li&gt;
&lt;li&gt;OriginalValues returns the tracked entity’s original property values&lt;/li&gt;
&lt;li&gt;CurrentValues returns the tracked entity’s current property values.&lt;/li&gt;
&lt;li&gt;GetDatabaseValues instantly execute a SQL query, and reads entity’s property values from database, without impacting current entity, or any tracking information including State, OriginalValues, CurrentValues.&lt;/li&gt;
&lt;li&gt;Property returns the specified property’s tracking information.&lt;/li&gt;
&lt;li&gt;Reload also executes a SELECT statement to read the database values, then it refreshes the entity’s property values, and all tracking information including State, OriginalValues, CurrentValues.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;the generic Entries method is a filtered version, it only returns the tracking information for entities of the specified type. It returns a sequence of generic DbEntityEntry&amp;lt;TEntity&amp;gt; objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Entity.Infrastructure
{
    public class DbEntityEntry&amp;lt;TEntity&amp;gt; where TEntity : class
    {
        public DbPropertyValues CurrentValues { get; }

        public TEntity Entity { get; }

        public DbPropertyValues OriginalValues { get; }

        public EntityState State { get; set; }

        public DbPropertyValues GetDatabaseValues();

        public DbPropertyEntry Property(string propertyName);

        public void Reload();

        public static implicit operator DbEntityEntry(DbEntityEntry&amp;lt;TEntity&amp;gt; entry);

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DbEntityEntry&amp;lt;TEntity&amp;gt; is similar to DbEntityEntry for entity tracking and state management. DbEntityEntry can be converted to DbEntityEntry&amp;lt;TEntity&amp;gt; by calling DbEntityEntry.Cast, and DbEntityEntry&amp;lt;TEntity&amp;gt; can be implicitly converted to DbEntityEntry.&lt;/p&gt;
&lt;p&gt;As fore mentioned in lazy load part, for a known entity, its tracking information can also be retrieved by calling DbContext.Entry. DbEntityEntry and DbEntityEntry&amp;lt;TEntity&amp;gt; also provides a few other methods, like Reference and Collection, which can be used for explicit lazy loading.&lt;/p&gt;
&lt;h3&gt;Track entities&lt;/h3&gt;
&lt;p&gt;By default, DbContext tracks all entities read from its repositories. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Tracking
{
    internal static void EntitiesFromSameDbContext()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            Product productById = adventureWorks.Products
                .Single(product =&amp;gt; product.ProductID == 999);
            Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1

            Product productByName = adventureWorks.Products
                .Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
            Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1
            Trace.WriteLine(object.ReferenceEquals(productById, productByName)); // True
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The single productById entity from first LINQ to Entities query is tracked by DbContext. Later, the second query results a single productByName entity too. Entity Framework figures out productById and productByName both map to the same data row of the same table, so productById and productByName reference to the same entity in memory.&lt;/p&gt;
&lt;p&gt;If data from repositories are not entities mapping to table rows, they cannot be tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void ObjectsFromSameDbContext()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        var productById = adventureWorks.Products
            .Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
            .Single(product =&amp;gt; product.ProductID == 999);
        var productByName = adventureWorks.Products
            .Select(product =&amp;gt; new { ProductID = product.ProductID, Name = product.Name })
            .Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 0
        Trace.WriteLine(object.ReferenceEquals(productById, productByName)); // False
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here data is queries from repositories, and anonymous type objects are constructed on the fly. Entity Framework cannot decide if 2 arbitrary objects semantically represent the same piece of data. This time productById and productByName are independent from each other.&lt;/p&gt;
&lt;p&gt;The tracking is at DbContext level. Entities from different DbContext objects belong to different units of work, and do not interfere each other:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EntitiesFromDbContexts()
{
    Product productById;
    Product productByName;
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        productById = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999);
    }
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        productByName = adventureWorks.Products.Single(product =&amp;gt; product.Name == &quot;Road-750 Black, 52&quot;);
    }
    Trace.WriteLine(object.ReferenceEquals(productById, productByName)); // False.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Track entity changes and property changes&lt;/h3&gt;
&lt;p&gt;The following example CRUDs some data in the product repository, and examine all the tracking:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void EntityChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        Product toCreate = new Product() { Name = nameof(toCreate), ListPrice = 1 };
        adventureWorks.Products.Add(toCreate); // Create entity.
        Product read = adventureWorks.Products.Single(product =&amp;gt; product.ProductID == 999); // Read entity.
        IQueryable&amp;lt;Product&amp;gt; toUpdate = adventureWorks.Products
            .Where(product =&amp;gt; product.Name.Contains(&quot;HL&quot;));
        toUpdate.ForEach(product =&amp;gt; product.ListPrice += 100); // Update entities.
        IQueryable&amp;lt;Product&amp;gt; toDelete = adventureWorks.Products
            .Where(product =&amp;gt; product.Name.Contains(&quot;ML&quot;));
        adventureWorks.Products.RemoveRange(toDelete); // Delete entities.

        Trace.WriteLine(adventureWorks.ChangeTracker.HasChanges()); // True
        adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
        {
            Product changed = tracking.Entity;
            switch (tracking.State)
            {
                case EntityState.Added:
                case EntityState.Deleted:
                case EntityState.Unchanged:
                    Trace.WriteLine($&quot;{tracking.State}: ({changed.ProductID}, {changed.Name}, {changed.ListPrice})&quot;);
                    break;
                case EntityState.Modified:
                    Product original = tracking.OriginalValues.ToObject() as Product;
                    Trace.WriteLine(
                        $&quot;{tracking.State}: ({original.ProductID}, {original.Name}, {original.ListPrice}) =&amp;gt; ({changed.ProductID}, {changed.Name}, {changed.ListPrice})&quot;);
                    break;
            }
        });
        // Added: (0, toCreate, 1)
        // Modified: (951, HL Crankset, 404.9900) =&amp;gt; (951, HL Crankset, 504.9900)
        // Modified: (996, HL Bottom Bracket, 121.4900) =&amp;gt; (996, HL Bottom Bracket, 221.4900)
        // Deleted: (950, ML Crankset, 256.4900)
        // Deleted: (995, ML Bottom Bracket, 101.2400)
        // Unchanged: (999, Road-750 Black, 52, 539.9900)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an entity is not read from a DbContext object’s repositories, then it has nothing to do with that unit of work, and apparently is not tracked by that DbContext object. DbSet&amp;lt;T&amp;gt; provides an Attach method to place an entity to the repository, and the DbContext tracks the entity as the Unchanged state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Attach()
{
    Product onTheFly = new Product() { ProductID = 950, Name = &quot;ML Crankset&quot;, ListPrice = 539.99M };
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 0

        adventureWorks.Products.Attach(onTheFly);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State); // Unchanged
        onTheFly.Name = &quot;After attaching&quot;;
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().Single().State); // Modified
        adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt; Trace.WriteLine(
            $&quot;{tracking.State}: {tracking.OriginalValues[nameof(Product.Name)]} =&amp;gt; {tracking.CurrentValues[nameof(Product.Name)]}&quot;));
        // Modified: ML Crankset =&amp;gt; After attaching
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Track association changes&lt;/h3&gt;
&lt;p&gt;The association of entities is also tracked. Remember Product’s foreign key ProductSubcategoryID is nullable. The following example reads a subcategory and its products, then delete the association. As a result, each navigation property is cleared to empty collection or null. And essentially, each product’s ProductSubcategoryID is changed to null, which is tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AssociationChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories
            .Include(entity =&amp;gt; entity.Products).Single(entity =&amp;gt; entity.ProductSubcategoryID == 8);
        Trace.WriteLine(subcategory.Products.Count); // 2
        Trace.WriteLine(subcategory.Products
            .All(product =&amp;gt; product.ProductSubcategory == subcategory)); // True

        subcategory.Products.Clear();
        // Equivalent to: subcategory.Products.ForEach(product =&amp;gt; product.ProductSubcategory = null);
        Trace.WriteLine(subcategory.Products.Count); // 0
        Trace.WriteLine(subcategory.Products
            .All(product =&amp;gt; product.ProductSubcategory == null)); // True
        adventureWorks.ChangeTracker.Entries&amp;lt;Product&amp;gt;().ForEach(tracking =&amp;gt;
            {
                Product original = tracking.OriginalValues.ToObject() as Product;
                Product changed = tracking.Entity;
                Trace.WriteLine(
                    $&quot;{tracking.State}: ({original.ProductID}, {original.Name}, {original.ProductSubcategoryID}) =&amp;gt; ({changed.ProductID}, {changed.Name}, {changed.ProductSubcategoryID})&quot;);
            });
        // Modified: (950, ML Crankset, 8) =&amp;gt; (950, ML Crankset, )
        // Modified: (951, HL Crankset, 8) =&amp;gt; (951, HL Crankset, )
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Disable tracking&lt;/h3&gt;
&lt;p&gt;DbContext’s default behavior is to track all changes automatically. This can be turned off. To disable tracking for specific entities read from repository, Entity Framework provides a AsNoTracking extension method for IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void AsNoTracking()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        Product untracked = adventureWorks.Products.AsNoTracking().First();
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 0
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tracking can also be disabled at the DbContext scope. If needed, changes and be manually tracked by calling DbChangeTracker.DetectChanges method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DetectChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.Configuration.AutoDetectChangesEnabled = false;
        Product product = adventureWorks.Products.First();
        product.ListPrice += 100;
        Trace.WriteLine(adventureWorks.ChangeTracker.HasChanges()); // False
        adventureWorks.ChangeTracker.DetectChanges();
        Trace.WriteLine(adventureWorks.ChangeTracker.HasChanges()); // True
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Change data&lt;/h2&gt;
&lt;p&gt;To change the data in the database, just create a DbContext object, change the data in its repositories, and call DbContext.SaveChanges method to submit the tracked changes to the remote database as a unit of work.&lt;/p&gt;
&lt;h3&gt;Create&lt;/h3&gt;
&lt;p&gt;To create new entities to the repository, call DbSet&amp;lt;T&amp;gt;.Add or DbSet&amp;lt;T&amp;gt;.AddRange. The following example creates 2 new associated entities, and add to repositories:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class Changes
{
    internal static ProductCategory Create()
    {
        using (AdventureWorks adventureWorks = new AdventureWorks())
        {
            ProductCategory category = new ProductCategory() { Name = nameof(ProductCategory) };
            ProductSubcategory subcategory = new ProductSubcategory() { Name = nameof(ProductSubcategory) };
            adventureWorks.ProductSubcategories.Add(subcategory);
            subcategory.ProductCategory = category;
            // Equivalent to: category.ProductSubcategories.Add(subcategory);
            Trace.WriteLine(adventureWorks.ChangeTracker.Entries()
                .Count(tracking =&amp;gt; tracking.State == EntityState.Added)); // 2
            Trace.WriteLine(category.ProductCategoryID); // 0
            Trace.WriteLine(subcategory.ProductCategoryID); // 0
            Trace.WriteLine(subcategory.ProductSubcategoryID); // 0

            Trace.WriteLine(adventureWorks.SaveChanges()); // 2
            Trace.WriteLine(adventureWorks.ChangeTracker.Entries()
                .Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged)); // 0
            Trace.WriteLine(category.ProductCategoryID); // 25
            Trace.WriteLine(subcategory.ProductCategoryID); // 25
            Trace.WriteLine(subcategory.ProductSubcategoryID); // 50
            return category;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here DbSet&amp;lt;T&amp;gt;.Add is called once with 1 subcategory entity. Internally, Add triggers change detection, and tracks this subcategory as Added state. Since this subcategory is associated with another category entity, the associated category is also tracked, as the same Added state. So in total there are 2 entity changes tracked. When DbContext.SaveChanges is called, Entity Framework translates these 2 changes to 2 SQL INSERT statements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION
    exec sp_executesql N&apos;INSERT [Production].[ProductCategory]([Name])
    VALUES (@0)
    SELECT [ProductCategoryID]
    FROM [Production].[ProductCategory]
    WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductCategoryID] = scope_identity()&apos;,N&apos;@0 nvarchar(50)&apos;,@0=N&apos;ProductCategory&apos;

    exec sp_executesql N&apos;INSERT [Production].[ProductSubcategory]([Name], [ProductCategoryID])
    VALUES (@0, @1)
    SELECT [ProductSubcategoryID]
    FROM [Production].[ProductSubcategory]
    WHERE @@ROWCOUNT &amp;gt; 0 AND [ProductSubcategoryID] = scope_identity()&apos;,N&apos;@0 nvarchar(50),@1 int&apos;,@0=N&apos;ProductSubcategory&apos;,@1=25
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The [Production].[ProductCategory] and [Production].[ProductSubcategory] tables’ primary key is an identity column, which is generated by database. So the new category’s ProductCategoryID and the new subcategory’s ProductSubcategory properties are ignored in the translated INSERT statements. After the each new row is created, a SELECT statement calls SCOPE_IDENTITY metadata function to read the last generated identity value, which is the primary key of the inserted row. As a result, since there are 2 row changes in total, SaveChanges returns 2, And the 2 changes are submitted in a transaction, so that all changes can succeed or fail as a unit.&lt;/p&gt;
&lt;p&gt;DbSet&amp;lt;T&amp;gt;.AddRange can be called with multiple entities. AddRange only triggers change detection once for all the entities, so it can have better performance than multiple Add calls,&lt;/p&gt;
&lt;h3&gt;Update&lt;/h3&gt;
&lt;p&gt;To update entities in the repositories, just modify the entities’ properties. The following example updates a subcategory entity’s Name property, and ProductCategory navigation property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Update()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories
            .Single(entity =&amp;gt; entity.Name == &quot;Bikes&quot;);
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories
            .Single(entity =&amp;gt; entity.Name == nameof(ProductSubcategory));
        Trace.WriteLine(
            $&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;);
        // (48, ProductSubcategory, 25)

        subcategory.Name = &quot;Update&quot;; // Update property.
        subcategory.ProductCategory = category; // Update association (foreign key).
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries()
            .Count(tracking =&amp;gt; tracking.State != EntityState.Unchanged)); // 1
        Trace.WriteLine(
            $&quot;({subcategory.ProductSubcategoryID}, {subcategory.Name}, {subcategory.ProductCategoryID})&quot;);
        // (48, Update, 1)

        Trace.WriteLine(adventureWorks.SaveChanges()); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The changes are translated to a UPDATE statement to update a column and a foreign key of specified row, and the row is located by the primary key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (2) 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE N&apos;Bikes&apos; = [Extent1].[Name]

SELECT TOP (2) 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID]
    FROM [Production].[ProductSubcategory] AS [Extent1]
    WHERE N&apos;ProductSubcategory&apos; = [Extent1].[Name]

BEGIN TRANSACTION
    exec sp_executesql N&apos;UPDATE [Production].[ProductSubcategory]
    SET [Name] = @0, [ProductCategoryID] = @1
    WHERE ([ProductSubcategoryID] = @2)
    &apos;,N&apos;@0 nvarchar(50),@1 int,@2 int&apos;,@0=N&apos;Update&apos;,@1=1,@2=50
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example first read the entities, then update. Since the row to update is located by primary key, if the primary key is known, then it can be used directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UpdateWithoutRead(int categoryId)
{
    ProductCategory category = new ProductCategory()
        {
            ProductCategoryID = categoryId,
            Name = Guid.NewGuid().ToString()
        };
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.ProductCategories.Attach(category);
        DbEntityEntry&amp;lt;ProductCategory&amp;gt; tracking = adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;()
            .Single();
        Trace.WriteLine(tracking.State); // Unchanged
        tracking.State = EntityState.Modified;
        Trace.WriteLine(adventureWorks.SaveChanges()); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a category entity is constructed on the fly, with specified primary key and updated Name. To track and save the changes, ii is attached to the repository. As fore mentioned, the attached entity is tracked as Unchanged state, so just manually set its state to Modified.. This time, only one UPDATE statement is translated and executed, without SELECT:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION
    exec sp_executesql N&apos;UPDATE [Production].[ProductCategory]
    SET [Name] = @0
    WHERE ([ProductCategoryID] = @1)
    &apos;,N&apos;@0 nvarchar(50),@1 int&apos;,@0=N&apos;f20d6c0c-1e92-4060-8a5d-72c41062b1be&apos;,@1=25
BEGIN TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When there is no change to save, SaveChanges returns 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void SaveNoChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories.Find(1);
        string originalName = category.Name;
        category.Name = Guid.NewGuid().ToString(); // Update property value.
        category.Name = originalName; // Update property back to original value.
        Trace.WriteLine(adventureWorks.ChangeTracker.HasChanges()); // False
        Trace.WriteLine(adventureWorks.SaveChanges()); // 0
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find queries category entity by primary key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT TOP (2) 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The category’s Name is updated, then updated back to original value. When calling SaveChanges, there is no change tracked or detected, so it does not execute UPDATE statement or any other SQL.&lt;/p&gt;
&lt;h3&gt;Delete&lt;/h3&gt;
&lt;p&gt;To delete entities from the repositories, call DbSet&amp;lt;T&amp;gt;.Remove or DbSet&amp;lt;T&amp;gt;.RemoveRange. The following example read an entity then delete it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void Delete()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductSubcategory subcategory = adventureWorks.ProductSubcategories
            .OrderByDescending(entity =&amp;gt; entity.ProductSubcategoryID).First();
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State); // Unchanged

        adventureWorks.ProductSubcategories.Remove(subcategory);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;ProductSubcategory&amp;gt;().Single().State); // Deleted
        Trace.WriteLine(adventureWorks.SaveChanges()); // 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Calling DbSet&amp;lt;T&amp;gt;.Add also triggers change detection, so the subcategory is tracked as Deleted state. When SaveChanges is called, the entity deletion is translated to a DELETE statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID]
    FROM [Production].[ProductSubcategory] AS [Extent1]
    ORDER BY [Extent1].[ProductSubcategoryID] DESC

BEGIN TRANSACTION
    exec sp_executesql N&apos;DELETE [Production].[ProductSubcategory]
    WHERE ([ProductSubcategoryID] = @0)&apos;,N&apos;@0 int&apos;,@0=50
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The row to delete is also located with primary key. So again, when primary key is known, reading entity can be skipped:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeleteWithoutRead(int categoryId)
{
    ProductCategory category = new ProductCategory() { ProductCategoryID = categoryId };
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        adventureWorks.ProductCategories.Attach(category);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State); // Unchanged

        adventureWorks.ProductCategories.Remove(category);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries&amp;lt;ProductCategory&amp;gt;().Single().State); // Deleted
        Trace.WriteLine(adventureWorks.SaveChanges()); // 1.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When constructing the entity on the fly, only the primary key is provided. This is enough to locate the row and delete it. This example only translate and execute a DELETE statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION
    exec sp_executesql N&apos;DELETE [Production].[ProductCategory]
    WHERE ([ProductCategoryID] = @0)&apos;,N&apos;@0 int&apos;,@0=25
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example delete an category entity which is associated with subcategory entities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeleteWithAssociation()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories.Find(1);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 1

        adventureWorks.ProductCategories.Remove(category);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries()
            .Count(tracking =&amp;gt; tracking.State == EntityState.Deleted)); // 1
        Trace.WriteLine(adventureWorks.SaveChanges());
        // System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
        // ---&amp;gt; System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details.
        // ---&amp;gt; System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint &quot;FK_ProductSubcategory_ProductCategory_ProductCategoryID&quot;. The conflict occurred in database &quot;D:\DIXIN\ONEDRIVE\WORKS\DRAFTS\CODESNIPPETS\DATA\ADVENTUREWORKS_DATA.MDF&quot;, table &quot;Production.ProductSubcategory&quot;, column &apos;ProductCategoryID&apos;.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SaveChanges fails, because the specified entity to delete is referenced by other entities.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT TOP (2) 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

BEGIN TRANSACTION
    exec sp_executesql N&apos;DELETE [Production].[ProductCategory]
    WHERE ([ProductCategoryID] = @0)&apos;,N&apos;@0 int&apos;,@0=1036
ROLLBACK TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a category can be deleted along with its subcategories:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void DeleteAllAssociated()
{
    Create(); // Create category &quot;ProductCategory&quot; and its subcategory &quot;ProductSubcategory&quot;.
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory category = adventureWorks.ProductCategories
            .Single(entity =&amp;gt; entity.Name == nameof(ProductCategory));
        ProductSubcategory subcategory = category.ProductSubcategories.Single();
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries().Count()); // 2

        adventureWorks.ProductCategories.Remove(category);
        // Optional: adventureWorks.ProductSubcategories.Remove(subcategory);
        Trace.WriteLine(adventureWorks.ChangeTracker.Entries()
            .Count(tracking =&amp;gt; tracking.State == EntityState.Deleted)); // 2
        Trace.WriteLine(adventureWorks.SaveChanges()); // 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, DbSet&amp;lt;T&amp;gt;.Remove is only called once with 1 entity, but Entity Framework detects 2 entities to delete, because of the association. Now the deletion is translated to 2 DELETE statements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (2) 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID], 
    [Extent1].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [Extent1]
    WHERE N&apos;ProductCategory&apos; = [Extent1].[Name]

exec sp_executesql N&apos;SELECT 
    [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[ProductCategoryID] AS [ProductCategoryID]
    FROM [Production].[ProductSubcategory] AS [Extent1]
    WHERE [Extent1].[ProductCategoryID] = @EntityKeyValue1&apos;,N&apos;@EntityKeyValue1 int&apos;,@EntityKeyValue1=26

BEGIN TRANSACTION
    exec sp_executesql N&apos;DELETE [Production].[ProductSubcategory]
    WHERE ([ProductSubcategoryID] = @0)&apos;,N&apos;@0 int&apos;,@0=51

    exec sp_executesql N&apos;DELETE [Production].[ProductCategory]
    WHERE ([ProductCategoryID] = @0)&apos;,N&apos;@0 int&apos;,@0=26
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice Entity Framework also translates and executes the deletion in the right order. The sub entity is deleted before the entity.&lt;/p&gt;
&lt;p&gt;Untracked changes cannot to be translated or executed. The following example tries to delete a untracked entity from the repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void UntrackedChanges()
{
    using (AdventureWorks adventureWorks = new AdventureWorks())
    {
        ProductCategory untracked = adventureWorks.ProductCategories.AsNoTracking().First();
        adventureWorks.ProductCategories.Remove(untracked);
        Trace.WriteLine(adventureWorks.SaveChanges());
        // InvalidOperationException: The object cannot be deleted because it was not found in the ObjectStateManager.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the only translated and executed SQL is the First query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) 
    [c].[ProductCategoryID] AS [ProductCategoryID], 
    [c].[Name] AS [Name]
    FROM [Production].[ProductCategory] AS [c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entity read from repository is untracked, so SaveChanges cannot translate or execute SQL, and throws InvalidOperationException.&lt;/p&gt;
</content:encoded></item><item><title>Installing Android 6 Marshmallow on Nexus 7</title><link>https://dixin.github.io/posts/installing-android-6-marshmallow-on-nexus-7/</link><guid isPermaLink="true">https://dixin.github.io/posts/installing-android-6-marshmallow-on-nexus-7/</guid><description>I got a ) in 2013. In 2014 it was upgraded to , and then became way slower</description><pubDate>Thu, 22 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I got a &lt;a href=&quot;https://en.wikipedia.org/wiki/Nexus_7_(2013)&quot;&gt;Nexus 7&lt;/a&gt; in 2013. In 2014 it was upgraded to &lt;a href=&quot;https://en.wikipedia.org/wiki/Android_Lollipop&quot;&gt;Android 5.0 Lollipop&lt;/a&gt;, and then became way slower. This month, Google released &lt;a href=&quot;https://developers.google.com/android/nexus/images&quot;&gt;Android 6.0.0 factory images - build MRA58K&lt;/a&gt;, Nexus 7 2013 included. So maybe it is time to refresh the device.&lt;/p&gt;
&lt;p&gt;Here are the steps of installing from &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_10&quot;&gt;Windows 10&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Prepare Nexus&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Settings/Developer options, enable Debug with USB.&lt;/li&gt;
&lt;li&gt;In Settings/Storage, change connection mode to Camera (PTP).&lt;/li&gt;
&lt;li&gt;Connect device to PC.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download USB driver, adb tool (&lt;a href=&quot;http://developer.android.com/tools/help/adb.html&quot;&gt;Android debug bridge&lt;/a&gt;), and fastboot tool. There are 2 ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Download &lt;a href=&quot;http://developer.android.com/sdk/index.html&quot;&gt;Android SDK&lt;/a&gt;, and install. After that, run SDK Manager, download adb, USB driver, and fastboot. &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt; The USB driver won’t automatically installed. It can be installed manually from Device Manager. When it is done shows up: &lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/image_4.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The much faster way is to install &lt;a href=&quot;http://forum.xda-developers.com/showthread.php?t=2317790&quot;&gt;Minimal ADB and Fastboot&lt;/a&gt;, and download &lt;a href=&quot;http://developer.android.com/sdk/win-usb.html#download&quot;&gt;USB driver directly&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When this step is done, “adb devices” command should list the device:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;List of devices attached 0a3d6f90 device&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unlock bootloader. Use “adb reboot bootloader” command to reboot device, then unlock it with “fastboot oem unlock”:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;... (bootloader) Unlocking bootloader... (bootloader) erasing userdata... (bootloader) erasing userdata done (bootloader) erasing cache... (bootloader) erasing cache done (bootloader) Unlocking bootloader done! OKAY [ 77.208s] finished. total time: 77.208s&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On Nexus, use the volume up/down and power buttons to confirm unlock.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the factory images from the &lt;a href=&quot;https://developers.google.com/android/nexus/images&quot;&gt;official links&lt;/a&gt;, and extract the files. There will be only 6 files, including a flash-all.bat. Run it. Then it’s done&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nexus reboots automatically. It rebooted forever for the first time. I had to hold the power button to turn it off. Then it cannot be turned on. A little scary. I held the power button for 30 seconds, it lit up.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the 2 years old Nexus with Marshmallow:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/Screenshot_20151022-003913_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/Screenshot_20151022-003913_thumb.png&quot; alt=&quot;Screenshot_20151022-003913&quot; title=&quot;Screenshot_20151022-003913&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/Screenshot_20151022-003352_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Installing_13E2D/Screenshot_20151022-003352_thumb.png&quot; alt=&quot;Screenshot_20151022-003352&quot; title=&quot;Screenshot_20151022-003352&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Attach SQL Server 2000 database to SQL Server 2014</title><link>https://dixin.github.io/posts/attach-sql-server-2000-database-to-sql-server-2014/</link><guid isPermaLink="true">https://dixin.github.io/posts/attach-sql-server-2000-database-to-sql-server-2014/</guid><description>In the , the  is used. It</description><pubDate>Fri, 10 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb399398.aspx&quot;&gt;MSDN introduction for LINQ to SQL&lt;/a&gt;, the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb399411.aspx&quot;&gt;Northwind sample database&lt;/a&gt; is used. It is a 15 years old database for SQL Server 2000. After &lt;a href=&quot;http://go.microsoft.com/fwlink?linkid=64296&quot;&gt;downloading&lt;/a&gt; the database files, it cannot be &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff851969(v=vs.110).aspx&quot;&gt;attached&lt;/a&gt; to the latest SQL Server 2014 or 2016. trying to do so results an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Database &apos;Northwind&apos; cannot be upgraded because its non-release version (539) is not supported by this version of SQL Server. You cannot open a database that is incompatible with this version of sqlservr.exe. You must re-create the database.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reason is, only the previous 2 version is supported to a SQL Server. For SQL Server 2014, this means only SQL Server 2008/2008R2 and 2012 database can be attached/restored. Northwind is a SQL Server 2000 database (version 539) so it does not work. There are 2 options to resolve this problem.&lt;/p&gt;
&lt;h2&gt;Use SQL Server 2008&lt;/h2&gt;
&lt;p&gt;Since SQL Server 2000/2005 database is supported in SQL Server 2008. The Northwind database can be &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms176061.aspx&quot;&gt;attached&lt;/a&gt; to a SQL Server 2008:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USE master;
GO
CREATE DATABASE [Northwind] ON PRIMARY 
    (FILENAME = N&apos;D:\SqlServer\SQL Server 2000 Sample Databases\NORTHWND.MDF&apos;)
LOG ON 
    (FILENAME = N&apos;D:\SqlServer\SQL Server 2000 Sample Databases\NORTHWND.LDF&apos;)
FOR ATTACH;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or just:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USE master;
GO
CREATE DATABASE [Northwind] ON 
    (FILENAME = N&apos;D:\SqlServer\SQL Server 2000 Sample Databases\NORTHWND.MDF&apos;), 
    (FILENAME = N&apos;D:\SqlServer\SQL Server 2000 Sample Databases\NORTHWND.LDF&apos;) 
FOR ATTACH;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The database version will be upgraded from 539 to 655:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converting database &apos;Northwind&apos; from version 539 to the current version 655. Database &apos;Northwind&apos; running the upgrade step from version 539 to version 551. Database &apos;Northwind&apos; running the upgrade step from version 551 to version 552. Database &apos;Northwind&apos; running the upgrade step from version 552 to version 611. Database &apos;Northwind&apos; running the upgrade step from version 611 to version 621. Database &apos;Northwind&apos; running the upgrade step from version 621 to version 622. Database &apos;Northwind&apos; running the upgrade step from version 622 to version 625. Database &apos;Northwind&apos; running the upgrade step from version 625 to version 626. Database &apos;Northwind&apos; running the upgrade step from version 626 to version 627. Database &apos;Northwind&apos; running the upgrade step from version 627 to version 628. Database &apos;Northwind&apos; running the upgrade step from version 628 to version 629. Database &apos;Northwind&apos; running the upgrade step from version 629 to version 630. Database &apos;Northwind&apos; running the upgrade step from version 630 to version 631. Database &apos;Northwind&apos; running the upgrade step from version 631 to version 632. Database &apos;Northwind&apos; running the upgrade step from version 632 to version 633. Database &apos;Northwind&apos; running the upgrade step from version 633 to version 634. Database &apos;Northwind&apos; running the upgrade step from version 634 to version 635. Database &apos;Northwind&apos; running the upgrade step from version 635 to version 636. Database &apos;Northwind&apos; running the upgrade step from version 636 to version 637. Database &apos;Northwind&apos; running the upgrade step from version 637 to version 638. Database &apos;Northwind&apos; running the upgrade step from version 638 to version 639. Database &apos;Northwind&apos; running the upgrade step from version 639 to version 640. Database &apos;Northwind&apos; running the upgrade step from version 640 to version 641. Database &apos;Northwind&apos; running the upgrade step from version 641 to version 642. Database &apos;Northwind&apos; running the upgrade step from version 642 to version 643. Database &apos;Northwind&apos; running the upgrade step from version 643 to version 644. Database &apos;Northwind&apos; running the upgrade step from version 644 to version 645. Database &apos;Northwind&apos; running the upgrade step from version 645 to version 646. Database &apos;Northwind&apos; running the upgrade step from version 646 to version 647. Database &apos;Northwind&apos; running the upgrade step from version 647 to version 648. Database &apos;Northwind&apos; running the upgrade step from version 648 to version 649. Database &apos;Northwind&apos; running the upgrade step from version 649 to version 650. Database &apos;Northwind&apos; running the upgrade step from version 650 to version 651. Database &apos;Northwind&apos; running the upgrade step from version 651 to version 652. Database &apos;Northwind&apos; running the upgrade step from version 652 to version 653. Database &apos;Northwind&apos; running the upgrade step from version 653 to version 654. Database &apos;Northwind&apos; running the upgrade step from version 654 to version 655.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then call &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms188031.aspx&quot;&gt;sp_detach_db&lt;/a&gt; to detach from SQL Server 2008:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USE master;
GO
EXEC sp_detach_db @dbname = N&apos;Northwind&apos;, @skipchecks = N&apos;true&apos;;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now NORTHWND.MDF can be attached to SQL Server 2014 successfully:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converting database &apos;Northwind&apos; from version 655 to the current version 782. Database &apos;Northwind&apos; running the upgrade step from version 655 to version 668. Database &apos;Northwind&apos; running the upgrade step from version 668 to version 669. Database &apos;Northwind&apos; running the upgrade step from version 669 to version 670. Database &apos;Northwind&apos; running the upgrade step from version 670 to version 671. Database &apos;Northwind&apos; running the upgrade step from version 671 to version 672. Database &apos;Northwind&apos; running the upgrade step from version 672 to version 673. Database &apos;Northwind&apos; running the upgrade step from version 673 to version 674. Database &apos;Northwind&apos; running the upgrade step from version 674 to version 675. Database &apos;Northwind&apos; running the upgrade step from version 675 to version 676. Database &apos;Northwind&apos; running the upgrade step from version 676 to version 677. Database &apos;Northwind&apos; running the upgrade step from version 677 to version 679. Database &apos;Northwind&apos; running the upgrade step from version 679 to version 680. Database &apos;Northwind&apos; running the upgrade step from version 680 to version 681. Database &apos;Northwind&apos; running the upgrade step from version 681 to version 682. Database &apos;Northwind&apos; running the upgrade step from version 682 to version 683. Database &apos;Northwind&apos; running the upgrade step from version 683 to version 684. Database &apos;Northwind&apos; running the upgrade step from version 684 to version 685. Database &apos;Northwind&apos; running the upgrade step from version 685 to version 686. Database &apos;Northwind&apos; running the upgrade step from version 686 to version 687. Database &apos;Northwind&apos; running the upgrade step from version 687 to version 688. Database &apos;Northwind&apos; running the upgrade step from version 688 to version 689. Database &apos;Northwind&apos; running the upgrade step from version 689 to version 690. Database &apos;Northwind&apos; running the upgrade step from version 690 to version 691. Database &apos;Northwind&apos; running the upgrade step from version 691 to version 692. Database &apos;Northwind&apos; running the upgrade step from version 692 to version 693. Database &apos;Northwind&apos; running the upgrade step from version 693 to version 694. Database &apos;Northwind&apos; running the upgrade step from version 694 to version 695. Database &apos;Northwind&apos; running the upgrade step from version 695 to version 696. Database &apos;Northwind&apos; running the upgrade step from version 696 to version 697. Database &apos;Northwind&apos; running the upgrade step from version 697 to version 698. Database &apos;Northwind&apos; running the upgrade step from version 698 to version 699. Database &apos;Northwind&apos; running the upgrade step from version 699 to version 700. Database &apos;Northwind&apos; running the upgrade step from version 700 to version 701. Database &apos;Northwind&apos; running the upgrade step from version 701 to version 702. Database &apos;Northwind&apos; running the upgrade step from version 702 to version 703. Database &apos;Northwind&apos; running the upgrade step from version 703 to version 704. Database &apos;Northwind&apos; running the upgrade step from version 704 to version 705. Database &apos;Northwind&apos; running the upgrade step from version 705 to version 706. Database &apos;Northwind&apos; running the upgrade step from version 706 to version 770. Database &apos;Northwind&apos; running the upgrade step from version 770 to version 771. Database &apos;Northwind&apos; running the upgrade step from version 771 to version 772. Database &apos;Northwind&apos; running the upgrade step from version 772 to version 773. Database &apos;Northwind&apos; running the upgrade step from version 773 to version 774. Database &apos;Northwind&apos; running the upgrade step from version 774 to version 775. Database &apos;Northwind&apos; running the upgrade step from version 775 to version 776. Database &apos;Northwind&apos; running the upgrade step from version 776 to version 777. Database &apos;Northwind&apos; running the upgrade step from version 777 to version 778. Database &apos;Northwind&apos; running the upgrade step from version 778 to version 779. Database &apos;Northwind&apos; running the upgrade step from version 779 to version 780. Database &apos;Northwind&apos; running the upgrade step from version 780 to version 781. Database &apos;Northwind&apos; running the upgrade step from version 781 to version 782.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Finally, Northwind database is upgraded from version 539 to 782.&lt;/p&gt;
&lt;h2&gt;Execute instnwnd.sql&lt;/h2&gt;
&lt;p&gt;The downloaded sample database files also includes an instnwnd.sql installation script. &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/8b6y4c7s.aspx&quot;&gt;Executing the script&lt;/a&gt; in SQL Server 2014 also results an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Could not find stored procedure &apos;sp_dboption&apos;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms187310.aspx&quot;&gt;sp_dboption&lt;/a&gt; is used at line 24 and 25:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_dboption &apos;Northwind&apos;,&apos;trunc. log on chkpt.&apos;,&apos;true&apos;
exec sp_dboption &apos;Northwind&apos;,&apos;select into/bulkcopy&apos;,&apos;true&apos;
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is deprecated since SQL Server 2012. In SQL Server 2012/2014, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb522682.aspx&quot;&gt;ALTER DATABASE&lt;/a&gt; should be used. These 2 lines are equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- exec sp_dboption &apos;Northwind&apos;,&apos;trunc. log on chkpt.&apos;,&apos;true&apos;
ALTER DATABASE Northwind SET RECOVERY SIMPLE
-- exec sp_dboption &apos;Northwind&apos;,&apos;select into/bulkcopy&apos;,&apos;true&apos;
ALTER DATABASE Northwind SET RECOVERY BULK_LOGGED
GO
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the replacement, instnwnd.sql can execute successfully.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# async / await (3) Runtime Context</title><link>https://dixin.github.io/posts/understanding-c-sharp-async-await-3-runtime-context/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-c-sharp-async-await-3-runtime-context/</guid><description>Understanding C# async / await:</description><pubDate>Thu, 01 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# async / await:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;Understanding C# async / await (1) Compilation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;&gt;Understanding C# async / await (2) Awaitable-Awaiter Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# async / await (3) Runtime Context&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;Part 1&lt;/a&gt; explained the compilation of await:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In a async method with await keyword, all the code are compiled into a state machine’s MoveNext() method.&lt;/li&gt;
&lt;li&gt;When this async method is called, the state machine is started. Along with the change of the state, MoveNext() will be called in a callback-like style.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
{
    HelperMethods.Before();
    int resultOfAwait1 = await MethodAsync(arg0, arg1);
    HelperMethods.Continuation1(resultOfAwait1);
    int resultOfAwait2 = await MethodAsync(arg2, arg3);
    HelperMethods.Continuation2(resultOfAwait2);
    int resultToReturn = resultOfAwait1 + resultOfAwait2;
    return resultToReturn;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To demonstrate the callback-like mechanism, part 1 simply used Task.ContinueWith():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
{
    TaskCompletionSource&amp;lt;int&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;int&amp;gt;(); try {

    // Original code begins.
    HelperMethods.Before();
    // int resultOfAwait1 = await MethodAsync(arg0, arg1);
    MethodAsync(arg0, arg1).ContinueWith(await1 =&amp;gt; { try { int resultOfAwait1 = await1.Result;
    HelperMethods.Continuation1(resultOfAwait1);
    // int resultOfAwait2 = await MethodAsync(arg2, arg3);
    MethodAsync(arg2, arg3).ContinueWith(await2 =&amp;gt; { try { int resultOfAwait2 = await2.Result;
    HelperMethods.Continuation2(resultOfAwait2);
    int resultToReturn = resultOfAwait1 + resultOfAwait2;
    // return resultToReturn;
    taskCompletionSource.SetResult(resultToReturn);
    // Original code ends.

    } catch (Exception exception) { taskCompletionSource.SetException(exception); }});
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }});
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }
    return taskCompletionSource.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, the await infrastructure is &lt;a href=&quot;http://tfwiki.net/wiki/The_Transformers:_More_than_Meets_the_Eye&quot;&gt;more than meets the eye&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Threading issue&lt;/h2&gt;
&lt;p&gt;A simple experiment can be done with a tiny WPF application. It has a window with a TextBox and a Button:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Window x:Class=&quot;WpfAsync.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title=&quot;MainWindow&quot; Height=&quot;350&quot; Width=&quot;525&quot;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBox x:Name=&quot;TextBox&quot; HorizontalAlignment=&quot;Left&quot; Height=&quot;274&quot; Margin=&quot;10,10,0,0&quot; TextWrapping=&quot;Wrap&quot; Text=&quot;TextBox&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;497&quot;/&amp;gt;
        &amp;lt;Button x:Name=&quot;Button&quot; Content=&quot;Button&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;432,289,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;75&quot;/&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the code-behind is straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace WpfAsync
{
    using System.Net;

    public partial class MainWindow
    {
        public MainWindow()
        {
            this.InitializeComponent();
            this.Button.Click += async (sender, e) =&amp;gt;
            {
                string html = await new WebClient().DownloadStringTaskAsync(&quot;https://weblogs.asp.net/dixin&quot;);
                this.TextBox.Text = html;
            };
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the Button is clicked, a string will be downloaded asynchronously. When the download is completed, the string will be displayed in the TextBox.&lt;/p&gt;
&lt;p&gt;Of course this code works. But if it is rewritten in callback style with Task.ContinueWith():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.Button.Click += (sender, e) =&amp;gt;
{
    // string html = await new WebClient().DownloadStringTaskAsync(&quot;https://weblogs.asp.net/dixin&quot;);
    new WebClient().DownloadStringTaskAsync(&quot;https://weblogs.asp.net/dixin&quot;).ContinueWith(await =&amp;gt; { string html = await.Result;
    this.TextBox.Text = html; });
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;running the rewritten code, the continuation (this.TextBox.Text = html;) may throw an InvalidOperationException:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The calling thread cannot access this object because a different thread owns it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reason is, when the callback code is scheduled to a non-UI thread in the thread pool, it cannot access the UI controls, like changing TextBox’s Text property. In the first async/await version, the await infrastructure resolves the cross-thread issue, majorly by &lt;a href=&quot;http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx&quot;&gt;marshaling the continuation code back to the initially captured ExecutionContext and SynchronizationContext&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Marshal to ExecutionContext&lt;/h2&gt;
&lt;p&gt;When reschedule a bunch of code to thread pool - potentially on another thread - await’s state machine invocation mechanism transfers initial calling thread’s ExecutionContext to each next call of MoveNext(). As &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.executioncontext.aspx&quot;&gt;MSDN explained&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ExecutionContext class provides a single container for all information relevant to a logical thread of execution. This includes security context, call context, and synchronization context.&lt;/p&gt;
&lt;p&gt;The ExecutionContext class provides the functionality for user code to capture and transfer this context across user-defined asynchronous points. The common language runtime ensures that the ExecutionContext is consistently transferred across runtime-defined asynchronous points within the managed process.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the public API to capture current thread’s ExecutionContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.GetCompletionAction()
ExecutionContext executionContext = ExecutionContext.Capture();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this extension method demonstrates how to invoke a function with a specified ExecutionContext (typically, captured from another thread):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class FuncExtensions
{
    public static TResult InvokeWith&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function, ExecutionContext executionContext)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(function != null);

        if (executionContext == null)
        {
            return function();
        }

        TResult result = default(TResult);
        // See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
        ExecutionContext.Run(executionContext, _ =&amp;gt; result = function(), null);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Marshal to SynchronizationContext&lt;/h2&gt;
&lt;p&gt;The await’s infrastructure also takes care of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx&quot;&gt;SynchronizationContext&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The SynchronizationContext class is a base class that provides a free-threaded context with no synchronization.&lt;/p&gt;
&lt;p&gt;The purpose of the synchronization model implemented by this class is to allow the internal asynchronous/synchronous operations of the common language runtime to behave properly with different synchronization models.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In different environment, &lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/gg598924.aspx&quot;&gt;SynchronizationContext has different implementations&lt;/a&gt;. In .NET there are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WPF: System.Windows.Threading.&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchersynchronizationcontext.aspx&quot;&gt;DispatcherSynchronizationContext&lt;/a&gt; (the case of this article)&lt;/li&gt;
&lt;li&gt;WinForms: System.Windows.Forms.&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.forms.windowsformssynchronizationcontext.aspx&quot;&gt;WindowsFormsSynchronizationContext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WinRT: System.Threading.WinRTSynchronizationContext&lt;/li&gt;
&lt;li&gt;ASP.NET: System.Web.&lt;a href=&quot;http://referencesource.microsoft.com/#System.Web/AspNetSynchronizationContext.cs&quot;&gt;AspNetSynchronizationContext&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Similar to ExecutionContext, the state machine invocation mechanism captures the initial SynchronizationContext, and post each call of MoveNext() to that SynchronizationContext.&lt;/p&gt;
&lt;p&gt;This is the public API to capture current thread’s SynchronizationContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()
// See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
SynchronizationContext synchronizationContext = SynchronizationContext.Current;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this extension method demonstrates how to invoke a function with a specified SynchronizationContext and ExecutionContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class FuncExtensions
{
    public static Task&amp;lt;TResult&amp;gt; InvokeWith&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function, SynchronizationContext synchronizationContext, ExecutionContext executionContext)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(function != null);

        TaskCompletionSource&amp;lt;TResult&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;TResult&amp;gt;();
        try
        {
            if (synchronizationContext == null)
            {
                TResult result = function.InvokeWith(executionContext);
                taskCompletionSource.SetResult(result);
            }
            else
            {
                // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()
                synchronizationContext.OperationStarted();
                // See: System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction()
                synchronizationContext.Post(_ =&amp;gt;
                {
                    try
                    {
                        TResult result = function.InvokeWith(executionContext);
                        // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.NotifySynchronizationContextOfCompletion()
                        synchronizationContext.OperationCompleted();
                        taskCompletionSource.SetResult(result);
                    }
                    catch (Exception exception)
                    {
                        taskCompletionSource.SetException(exception);
                    }
                }, null);
            }
        }
        catch (Exception exception)
        {
            taskCompletionSource.SetException(exception);
        }

        return taskCompletionSource.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the version for action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ActionExtensions
{
    public static Task InvokeWith(this Action action, SynchronizationContext synchronizationContext, ExecutionContext executionContext)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(action != null);

        return new Func&amp;lt;object&amp;gt;(() =&amp;gt;
        {
            action();
            return null;
        }).InvokeWith(synchronizationContext, executionContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Callback with ExecutionContext and SynchronizationContext&lt;/h2&gt;
&lt;p&gt;With the above extension methods, some enhanced methods can be created for Task.ContinueWith() callback mechanism. Here it is called ContinueWithContext() because it &lt;a href=&quot;http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx&quot;&gt;takes care of ExecutionContext and SynchronizationContext&lt;/a&gt; for ContinueWith(). This version is to continue with function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class TaskExtensions
{
    public static Task&amp;lt;TNewResult&amp;gt; ContinueWithContext&amp;lt;TResult, TNewResult&amp;gt;(this Task&amp;lt;TResult&amp;gt; task, Func&amp;lt;Task&amp;lt;TResult&amp;gt;, TNewResult&amp;gt; continuation)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(task != null);
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(continuation != null);

        // See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.GetCompletionAction()
        ExecutionContext executionContext = ExecutionContext.Capture();
        // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()
        // See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
        SynchronizationContext synchronizationContext = SynchronizationContext.Current;
        return task.ContinueWith(t =&amp;gt;
                new Func&amp;lt;TNewResult&amp;gt;(() =&amp;gt; continuation(t)).InvokeWith(synchronizationContext, executionContext))
            .Unwrap();
    }

    public static Task&amp;lt;TNewResult&amp;gt; ContinueWithContext&amp;lt;TNewResult&amp;gt;(this Task task, Func&amp;lt;Task, TNewResult&amp;gt; continuation)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(task != null);
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(continuation != null);

        // See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.GetCompletionAction()
        ExecutionContext executionContext = ExecutionContext.Capture();
        // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()
        // See: System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
        SynchronizationContext synchronizationContext = SynchronizationContext.Current;
        return task.ContinueWith(t =&amp;gt; 
                new Func&amp;lt;TNewResult&amp;gt;(() =&amp;gt; continuation(t)).InvokeWith(synchronizationContext, executionContext))
            .Unwrap();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the version to continue with action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class TaskExtensions
{
    public static Task ContinueWithContext&amp;lt;TResult&amp;gt;(this Task&amp;lt;TResult&amp;gt; task, Action&amp;lt;Task&amp;lt;TResult&amp;gt;&amp;gt; continuation)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(task != null);
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(continuation != null);

        return task.ContinueWithContext(new Func&amp;lt;Task&amp;lt;TResult&amp;gt;, object&amp;gt;(t =&amp;gt;
        {
            continuation(t);
            return null;
        }));
    }

    public static Task ContinueWithContext(this Task task, Action&amp;lt;Task&amp;gt; continuation)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(task != null);
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(continuation != null);

        return task.ContinueWithContext(new Func&amp;lt;Task, object&amp;gt;(t =&amp;gt;
        {
            continuation(t);
            return null;
        }));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the above WPF code can be easily fixed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.Button.Click += (sender, e) =&amp;gt;
{
    // string html = await new WebClient().DownloadStringTaskAsync(&quot;https://weblogs.asp.net/dixin&quot;);
    new WebClient().DownloadStringTaskAsync(&quot;https://weblogs.asp.net/dixin&quot;).ContinueWithContext(await =&amp;gt; { string html = await.Result;
    this.TextBox.Text = html; });
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just replace ContinueWith() with ContinueWithContext(), the continuation (this.TextBox.Text = html;) works.&lt;/p&gt;
&lt;h3&gt;Use Task.ConfigureAwait()&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.configureawait.aspx&quot;&gt;Task.ConfigureAwait()&lt;/a&gt; is another interesting API provided by .NET:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When calling Task.ConfigureAwait(continueOnCapturedContext: true), the initial ExecutionContext and SynchronizationContext will both be captured for the continuation code, which is the default behavior explained above.&lt;/li&gt;
&lt;li&gt;When calling Task.ConfigureAwait(continueOnCapturedContext: false), only the initial ExecutionContext is captured for the continuation code:, not the initial SynchronizationContext.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, in the above WPF application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.Button.Click += async (sender, e) =&amp;gt;
{
    await Task.Run(() =&amp;gt; { }).ConfigureAwait(false);
    this.TextBox.Text = string.Empty; // Will not work.
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This continuation code will throw the same InvalidOperationException as above Task.ContinueWith() version:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The calling thread cannot access this object because a different thread owns it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;&gt;At compile time&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complier decides an object is awaitable if
&lt;ul&gt;
&lt;li&gt;It has a GetAwaiter() method (instance method or extension method);&lt;/li&gt;
&lt;li&gt;Its GetAwaiter() method returns an awaiter. Complier decides an object is an awaiter if:
&lt;ul&gt;
&lt;li&gt;It implements INotifyCompletion or ICriticalNotifyCompletion interface;&lt;/li&gt;
&lt;li&gt;It has an IsCompleted poroperty, which has a getter and returns a Boolean;&lt;/li&gt;
&lt;li&gt;it has a GetResult() method, which returns void, or a result.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;During compilation&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The async decorator is gone&lt;/li&gt;
&lt;li&gt;The await keyword is gone too. The entire async method body is compiled into a state machine with a MoveNext() method&lt;/li&gt;
&lt;li&gt;This MoveNext() method can be called multiple times in a callback style, and each call can be scheduled to different thread in thread pool.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At runtime:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The await’s initial ExecutionContext is always captured, and its continuation code is marshaled to this captured ExecutionContext.&lt;/li&gt;
&lt;li&gt;The await’s initial SynchronizationContext is captured by default, and its continuation code is marshaled to this captured SynchronizationContext, unless explicitly supressed like calling Task.ConfigureAwait(false).&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Understanding C# async / await (2) The Awaitable-Awaiter Pattern</title><link>https://dixin.github.io/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern/</guid><description>Understanding C# async / await:</description><pubDate>Sat, 29 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# async / await:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;Understanding C# async / await (1) Compilation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# async / await (2) Awaitable-Awaiter Pattern&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-3-runtime-context&quot;&gt;Understanding C# async / await (3) Runtime Context&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What is awaitable&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-1-compilation&quot;&gt;Part 1&lt;/a&gt; shows that any Task is awaitable. Actually there are other awaitable types. Here is an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Task&amp;lt;int&amp;gt; task = new Task&amp;lt;int&amp;gt;(() =&amp;gt; 0);
int result = await task.ConfigureAwait(false); // Returns a ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The returned ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt; struct is awaitable. And it is not Task at all:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt;
{
    private readonly ConfiguredTaskAwaiter m_configuredTaskAwaiter;

    internal ConfiguredTaskAwaitable(Task&amp;lt;TResult&amp;gt; task, bool continueOnCapturedContext)
    {
        this.m_configuredTaskAwaiter = new ConfiguredTaskAwaiter(task, continueOnCapturedContext);
    }

    public ConfiguredTaskAwaiter GetAwaiter()
    {
        return this.m_configuredTaskAwaiter;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has one GetAwaiter() method. Actually in &lt;a href=&quot;/posts/understanding-c-async-await-1-compilation&quot;&gt;part 1&lt;/a&gt; we have seen that Task has GetAwaiter() method too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Task
{
    public TaskAwaiter GetAwaiter()
    {
        return new TaskAwaiter(this);
    }
}

public class Task&amp;lt;TResult&amp;gt; : Task
{
    public new TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter()
    {
        return new TaskAwaiter&amp;lt;TResult&amp;gt;(this);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Task.Yield() is another example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;await Task.Yield(); // Returns a YieldAwaitable.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The returned YieldAwaitable is not Task either:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct YieldAwaitable
{
    public YieldAwaiter GetAwaiter()
    {
        return default(YieldAwaiter);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, it just has one GetAwaiter() method. This article will look at what is awaitable.&lt;/p&gt;
&lt;h2&gt;The awaitable-awaiter pattern&lt;/h2&gt;
&lt;p&gt;By observing different awaitable / awaiter types, we can tell that an object is awaitable if&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It has a GetAwaiter() method (instance method or extension method);&lt;/li&gt;
&lt;li&gt;Its GetAwaiter() method returns an awaiter. An object is an awaiter if:
&lt;ul&gt;
&lt;li&gt;It implements INotifyCompletion or ICriticalNotifyCompletion interface;&lt;/li&gt;
&lt;li&gt;It has an IsCompleted, which has a getter and returns a Boolean;&lt;/li&gt;
&lt;li&gt;it has a GetResult() method, which returns void, or a result.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So apparently this awaitable-awaiter pattern is very similar to &lt;a href=&quot;/posts/understanding-linq-to-objects-4-iterator-pattern&quot;&gt;the iteratable-iterator pattern&lt;/a&gt;. Here is the interface definitions of iteratable / iterator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

public interface IEnumerator
{
    object Current { get; }

    bool MoveNext();

    void Reset();
}

public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
{
    IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
}

public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
{
    T Current { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In case the out keyword does not sound familiar, please find detailed explanation in another article &lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The “missing” IAwaitable / IAwaiter interfaces&lt;/h2&gt;
&lt;p&gt;Similar to IEnumerable and IEnumerator interfaces, awaitable / awaiter can be visualized by IAwaitable / IAwaiter interfaces too. This is the non-generic version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IAwaitable
{
    IAwaiter GetAwaiter();
}

public interface IAwaiter : INotifyCompletion // or ICriticalNotifyCompletion
{
    // INotifyCompletion has one method: void OnCompleted(Action continuation);

    // ICriticalNotifyCompletion implements INotifyCompletion,
    // also has this method: void UnsafeOnCompleted(Action continuation);

    bool IsCompleted { get; }

    void GetResult();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice GetResult() returns void here. Task.GetAwaiter() / TaskAwaiter.GetResult() is of such case.&lt;/p&gt;
&lt;p&gt;And here comes the generic version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IAwaitable&amp;lt;out TResult&amp;gt;
{
    IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter();
}

public interface IAwaiter&amp;lt;out TResult&amp;gt; : INotifyCompletion // or ICriticalNotifyCompletion
{
    bool IsCompleted { get; }

    TResult GetResult();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the only difference is, GetResult() return a result. Task&amp;lt;TResult&amp;gt;.GetAwaiter() / TaskAwaiter&amp;lt;TResult&amp;gt;.GetResult() is of this case.&lt;/p&gt;
&lt;p&gt;Please notice .NET core does not define these IAwaitable / IAwaiter interfaces at all. IAwaitable interface will constraint GetAwaiter() to be instance method. Actually C# supports both GetAwaiter() instance method and GetAwaiter() extension method.&lt;/p&gt;
&lt;p&gt;Here these interfaces are used only for better visualizing what is awaitable / awaiter. Now, if looking at above ConfiguredTaskAwaitable / ConfiguredTaskAwaiter, YieldAwaitable / YieldAwaiter, Task / TaskAwaiter pairs again, they all “implicitly” implement these “missing” IAwaitable / IAwaiter interfaces. The rest part of this article will show how to implement awaitable / awaiter.&lt;/p&gt;
&lt;h2&gt;Await any function / action&lt;/h2&gt;
&lt;p&gt;In C# await cannot be used with lambda. This code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = await (() =&amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will cause a compiler error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cannot await &apos;lambda expression&apos;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is easy to understand because this &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;lambda expression&lt;/a&gt; (() =&amp;gt; 0) &lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;may be a function or a expression tree&lt;/a&gt;. Obviously we mean function here, and we can tell compiler in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = await new Func&amp;lt;int&amp;gt;(() =&amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It causes an different error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cannot await &apos;System.Func&amp;lt;int&amp;gt;&apos;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OK, now the compiler is complaining the type instead of syntax. With the understanding of the awaitable / awaiter pattern, Func&amp;lt;TResult&amp;gt; type can be easily made into awaitable.&lt;/p&gt;
&lt;h3&gt;GetAwaiter() instance method, using IAwaitable and IAwaiter interfaces&lt;/h3&gt;
&lt;p&gt;First, similar to above ConfiguredTaskAwaitable&amp;lt;TResult&amp;gt;, a FuncAwaitable&amp;lt;TResult&amp;gt; can be implemented to wrap Func&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal struct FuncAwaitable&amp;lt;TResult&amp;gt; : IAwaitable&amp;lt;TResult&amp;gt;
{
    private readonly Func&amp;lt;TResult&amp;gt; function;

    public FuncAwaitable(Func&amp;lt;TResult&amp;gt; function)
    {
        this.function = function;
    }

    public IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter()
    {
        return new FuncAwaiter&amp;lt;TResult&amp;gt;(this.function);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;FuncAwaitable&amp;lt;TResult&amp;gt; wrapper is used to implement IAwaitable&amp;lt;TResult&amp;gt;, so it has one instance method, GetAwaiter(), which returns a IAwaiter&amp;lt;TResult&amp;gt;, which wraps that Func&amp;lt;TResult&amp;gt; too. FuncAwaiter&amp;lt;TResult&amp;gt; is used to implement IAwaiter&amp;lt;TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct FuncAwaiter&amp;lt;TResult&amp;gt; : IAwaiter&amp;lt;TResult&amp;gt;
{
    private readonly Task&amp;lt;TResult&amp;gt; task;

    public FuncAwaiter(Func&amp;lt;TResult&amp;gt; function)
    {
        this.task = new Task&amp;lt;TResult&amp;gt;(function);
        this.task.Start();
    }

    bool IAwaiter&amp;lt;TResult&amp;gt;.IsCompleted
    {
        get
        {
            return this.task.IsCompleted;
        }
    }

    TResult IAwaiter&amp;lt;TResult&amp;gt;.GetResult()
    {
        return this.task.Result;
    }

    void INotifyCompletion.OnCompleted(Action continuation)
    {
        new Task(continuation).Start();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now a function can be awaited in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = await new FuncAwaitable&amp;lt;int&amp;gt;(() =&amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GetAwaiter() extension method, without IAwaitable interfaces&lt;/h3&gt;
&lt;p&gt;As IAwaitable shows, all that an awaitable needs is just a GetAwaiter() method. In above code, FuncAwaitable&amp;lt;TResult&amp;gt; is created as a wrapper of Func&amp;lt;TResult&amp;gt; and implements IAwaitable&amp;lt;TResult&amp;gt;, so that there is a GetAwaiter() instance method. If a GetAwaiter() extension method can be defined for Func&amp;lt;TResult&amp;gt;, then FuncAwaitable&amp;lt;TResult&amp;gt; is no longer needed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class FuncExtensions
{
    public static IAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function)
    {
        return new FuncAwaiter&amp;lt;TResult&amp;gt;(function);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So a Func&amp;lt;TResult&amp;gt; function can be directly awaited:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = await new Func&amp;lt;int&amp;gt;(() =&amp;gt; 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use the built-in awaitable and awaiter: Task and TaskAwaiter&lt;/h3&gt;
&lt;p&gt;Remember the most frequently used awaitable / awaiter - Task / TaskAwaiter. With Task / TaskAwaiter, FuncAwaitable / FuncAwaiter are no longer needed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class FuncExtensions
{
    public static TaskAwaiter&amp;lt;TResult&amp;gt; GetAwaiter&amp;lt;TResult&amp;gt;(this Func&amp;lt;TResult&amp;gt; function)
    {
        Task&amp;lt;TResult&amp;gt; task = new Task&amp;lt;TResult&amp;gt;(function);
        task.Start();
        return task.GetAwaiter(); // Returns a TaskAwaiter&amp;lt;TResult&amp;gt;.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, with this extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ActionExtensions
{
    public static TaskAwaiter GetAwaiter(this Action action)
    {
        Task task = new Task(action);
        task.Start();
        return task.GetAwaiter(); // Returns a TaskAwaiter.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;an action can be awaited as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;await new Action(() =&amp;gt; { });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now any function / action can be awaited:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;await new Action(() =&amp;gt; HelperMethods.IO()); // or: await new Action(HelperMethods.IO);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If function / action has parameter(s), closure can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int arg0 = 0;
int arg1 = 1;
int result = await new Action(() =&amp;gt; HelperMethods.IO(arg0, arg1));
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use Task.Run()&lt;/h3&gt;
&lt;p&gt;The above code is used to demonstrate how awaitable / awaiter can be implemented. As it is common scenario to await a function / action, .NET provides a built-in API: Task.Run(). Their implementations are similar to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Task
{
    public static Task Run(Action action)
    {
        // The implementation is similar to:
        Task task = new Task(action);
        task.Start();
        return task;
    }

    public static Task&amp;lt;TResult&amp;gt; Run&amp;lt;TResult&amp;gt;(Func&amp;lt;TResult&amp;gt; function)
    {
        // The implementation is similar to:
        Task&amp;lt;TResult&amp;gt; task = new Task&amp;lt;TResult&amp;gt;(function);
        task.Start();
        return task;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In reality, this is how to await a function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int result = await Task.Run(() =&amp;gt; HelperMethods.IO(arg0, arg1));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and await a action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;await Task.Run(HelperMethods.IO);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Await IObservable&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd990377.aspx&quot;&gt;IObservable&amp;lt;T&amp;gt;&lt;/a&gt; and &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh211887.aspx&quot;&gt;IConnectableObservable&amp;lt;T&amp;gt;&lt;/a&gt; become awaitable too, if a reference is added for &lt;a href=&quot;http://www.nuget.org/packages/Rx-Linq/&quot;&gt;System.Reactive.Linq.dll&lt;/a&gt;, a part of &lt;a href=&quot;https://msdn.microsoft.com/en-us/data/gg577609.aspx&quot;&gt;Rx (Reactive Extensions)&lt;/a&gt;. In this library, the GetAwaiter() extension methods are provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Observable
{
    public static AsyncSubject&amp;lt;TSource&amp;gt; GetAwaiter&amp;lt;TSource&amp;gt;(this IObservable&amp;lt;TSource&amp;gt; source);

    public static AsyncSubject&amp;lt;TSource&amp;gt; GetAwaiter&amp;lt;TSource&amp;gt;(this IConnectableObservable&amp;lt;TSource&amp;gt; source);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each method returns a AsyncSubject&amp;lt;T&amp;gt;, which is an awaiter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public sealed class AsyncSubject&amp;lt;T&amp;gt; : INotifyCompletion, ISubject&amp;lt;T&amp;gt;, ISubject&amp;lt;T, T&amp;gt;, IObserver&amp;lt;T&amp;gt;, IObservable&amp;lt;T&amp;gt;, IDisposable
{
    public bool IsCompleted { get; }
    
    public void OnCompleted();

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that can be used with the await keyword. Take IObservable&amp;lt;T&amp;gt; as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static async Task AwaitObservable1()
{
    IObservable&amp;lt;int&amp;gt; observable = Observable.Range(0, 3).Do(Console.WriteLine);
    await observable;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This outputs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;0 1 2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static async Task&amp;lt;string&amp;gt; AwaitObservable2()
{
    IObservable&amp;lt;string&amp;gt; observable = new string[]
        {
            &quot;https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-1-compilation&quot;,
            &quot;https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;,
            &quot;https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-3-runtime-context&quot;,
        }
        .ToObservable&amp;lt;string&amp;gt;()
        .SelectMany(async url =&amp;gt; await new WebClient().DownloadStringTaskAsync(url))
        .Select(StringExtensions.GetTitleFromHtml)
        .Do(Console.WriteLine);

    return await observable;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where the GetTitleFromHtml is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string GetTitleFromHtml(this string html)
{
    Match match = new Regex(
        @&quot;.*&amp;lt;head&amp;gt;.*&amp;lt;title&amp;gt;(.*)&amp;lt;/title&amp;gt;.*&amp;lt;/head&amp;gt;.*&quot;,
        RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(html);
    return match.Success ? match.Groups[1].Value : null;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing above AwaitObservable2 method will output the title of each page:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dixin&apos;s Blog - Understanding C# async / await (1) Compilation Dixin&apos;s Blog - Understanding C# async / await (3) Runtime Context Dixin&apos;s Blog - Understanding C# async / await (2) The Awaitable-Awaiter Pattern&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is exactly what’s between &amp;lt;tile&amp;gt; and &amp;lt;/title&amp;gt;.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# async / await (1) Compilation</title><link>https://dixin.github.io/posts/understanding-c-sharp-async-await-1-compilation/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-c-sharp-async-await-1-compilation/</guid><description>Understanding C# async / await:</description><pubDate>Sat, 03 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# async / await:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understanding C# async / await (1) Compilation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;&gt;Understanding C# async / await (2) Awaitable-Awaiter Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-c-sharp-async-await-3-runtime-context&quot;&gt;Understanding C# async / await (3) Runtime Context&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx&quot;&gt;async / await keywords are in C#.&lt;/a&gt; Just like &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd233250.aspx&quot;&gt;the async and ! in F#&lt;/a&gt;, this new C# feature provides great convenience. There are many nice documents talking about how to use async / await in specific scenarios, like &lt;a href=&quot;http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45&quot;&gt;using async methods in ASP.NET 4.5&lt;/a&gt; and &lt;a href=&quot;http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4&quot;&gt;in ASP.NET MVC 4&lt;/a&gt;, etc. This article will look at the real code working behind the syntax sugar.&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh156513.aspx&quot;&gt;MSDN stated&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The async modifier indicates that the method, lambda expression, or anonymous method that it modifies is asynchronous.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also since &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;lambda expression / anonymous method will be compiled to normal method&lt;/a&gt;, this article will focus on normal async method.&lt;/p&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;p&gt;First of all, Some helper methods need to be made up.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class HelperMethods
{
    private static void IO()
    {
        using (WebClient client = new WebClient())
        {
            Enumerable.Repeat(&quot;http://weblogs.asp.net/dixin&quot;, 10).Select(client.DownloadString).ToArray();
        }
    }

    internal static int Method(int arg0, int arg1)
    {
        int result = arg0 + arg1;
        IO(); // Do some long running IO.
        return result;
    }

    internal static Task&amp;lt;int&amp;gt; MethodTask(int arg0, int arg1)
    {
        Task&amp;lt;int&amp;gt; task = new Task&amp;lt;int&amp;gt;(() =&amp;gt; Method(arg0, arg1));
        task.Start(); // Hot task (started task) should always be returned.
        return task;
    }

    internal static void Before()
    {
    }

    internal static void Continuation1(int arg)
    {
    }

    internal static void Continuation2(int arg)
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Method() is a long running method doing some IO. Then MethodTask() wraps it into a Task and return that Task. Nothing special here.&lt;/p&gt;
&lt;h2&gt;Await something in async method&lt;/h2&gt;
&lt;p&gt;Since MethodTask() returns Task, let’s try to await it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class AsyncMethods
{
    internal static async Task&amp;lt;int&amp;gt; MethodAsync(int arg0, int arg1)
    {
        int result = await HelperMethods.MethodTask(arg0, arg1);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because the await keyword is used in the body, the async keyword must be put on the method. Now the first async method is here. According to the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_NamingConvention&quot;&gt;naming convenience&lt;/a&gt;, it has postfix Async. Of course as an async method, itself can be awaited. So here comes a CallMethodAsync() to call MethodAsync():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class AsyncMethods
{
    internal static async Task&amp;lt;int&amp;gt; CallMethodAsync(int arg0, int arg1)
    {
        int result = await MethodAsync(arg0, arg1);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After compilation, MethodAsync() and CallMethodAsync() will have the same logic. This is the code of MethodAsyc():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class CompiledAsyncMethods
{
    [DebuggerStepThrough]
    [AsyncStateMachine(typeof(MethodAsyncStateMachine))] // async
    internal static /*async*/ Task&amp;lt;int&amp;gt; MethodAsync(int arg0, int arg1)
    {
        MethodAsyncStateMachine methodAsyncStateMachine = new MethodAsyncStateMachine()
            {
                Arg0 = arg0,
                Arg1 = arg1,
                Builder = AsyncTaskMethodBuilder&amp;lt;int&amp;gt;.Create(),
                State = -1
            };
        methodAsyncStateMachine.Builder.Start(ref methodAsyncStateMachine);
        return methodAsyncStateMachine.Builder.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The async keyword is gone. It only creates and starts a state machine MethodAsyncStateMachine, and all actual logic are moved to that state machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
internal struct MethodAsyncStateMachine : IAsyncStateMachine
{
    public int State;
    public AsyncTaskMethodBuilder&amp;lt;int&amp;gt; Builder;
    public int Arg0;
    public int Arg1;
    public int Result;
    private TaskAwaiter&amp;lt;int&amp;gt; awaitor;

    void IAsyncStateMachine.MoveNext()
    {
        try
        {
            if (this.State != 0)
            {
                this.awaitor = HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter();
                if (!this.awaitor.IsCompleted)
                {
                    this.State = 0;
                    this.Builder.AwaitUnsafeOnCompleted(ref this.awaitor, ref this);
                    return;
                }
            }
            else
            {
                this.State = -1;
            }

            this.Result = this.awaitor.GetResult();
        }
        catch (Exception exception)
        {
            this.State = -2;
            this.Builder.SetException(exception);
            return;
        }

        this.State = -2;
        this.Builder.SetResult(this.Result);
    }

    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0)
    {
        this.Builder.SetStateMachine(param0);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated code has been cleaned up so it is readable and can be compiled. Several things can be observed here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The async modifier is gone, which shows, unlike other modifiers (e.g. static), there is no such IL/CLR level “async” stuff. It becomes a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.asyncstatemachineattribute.aspx&quot;&gt;AsyncStateMachineAttribute&lt;/a&gt;. This is similar to &lt;a href=&quot;/posts/understanding-csharp-3-0-features-5-extension-method&quot;&gt;the compilation of extension method&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The generated state machine is very similar to &lt;a href=&quot;/posts/understanding-linq-to-objects-5-implementing-iterator&quot;&gt;the state machine of C# yield syntax sugar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The local variables (arg0, arg1, result) are compiled as the fields of the state machine.&lt;/li&gt;
&lt;li&gt;The real code (await HelperMethods.MethodTask(arg0, arg1)) is compiled into MoveNext() as: HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter().&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CallMethodAsync() will create and start its own state machine CallMethodAsyncStateMachine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class CompiledAsyncMethods
{
    [DebuggerStepThrough]
    [AsyncStateMachine(typeof(CallMethodAsyncStateMachine))] // async
    internal static /*async*/ Task&amp;lt;int&amp;gt; CallMethodAsync(int arg0, int arg1)
    {
        CallMethodAsyncStateMachine callMethodAsyncStateMachine = new CallMethodAsyncStateMachine()
            {
                Arg0 = arg0,
                Arg1 = arg1,
                Builder = AsyncTaskMethodBuilder&amp;lt;int&amp;gt;.Create(),
                State = -1
            };
        callMethodAsyncStateMachine.Builder.Start(ref callMethodAsyncStateMachine);
        return callMethodAsyncStateMachine.Builder.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CallMethodAsyncStateMachine has the same logic as MethodAsyncStateMachine above. The detail of the state machine will be discussed soon. Now it is clear that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;async /await is a C# level syntax sugar.&lt;/li&gt;
&lt;li&gt;There is no difference between awaiting a async method or awaiting a normal method. Any method returning Task will be awaitable, or – to be precise – Task objects can be awaited. What can be &lt;a href=&quot;/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;&gt;awaitable will be explained in part 2&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;State machine and continuation&lt;/h2&gt;
&lt;p&gt;To demonstrate more details in the state machine, a more complex method can be created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class AsyncMethods
{
    internal static async Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
    {
        HelperMethods.Before();
        int resultOfAwait1 = await MethodAsync(arg0, arg1);
        HelperMethods.Continuation1(resultOfAwait1);
        int resultOfAwait2 = await MethodAsync(arg2, arg3);
        HelperMethods.Continuation2(resultOfAwait2);
        int resultToReturn = resultOfAwait1 + resultOfAwait2;
        return resultToReturn;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are multiple awaits.&lt;/li&gt;
&lt;li&gt;There are code before the awaits, and continuation code after each await&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After compilation, this multi-await method becomes the same as above single-await methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class CompiledAsyncMethods
{
    [DebuggerStepThrough]
    [AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async
    internal static /*async*/ Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
    {
        MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine()
            {
                Arg0 = arg0,
                Arg1 = arg1,
                Arg2 = arg2,
                Arg3 = arg3,
                Builder = AsyncTaskMethodBuilder&amp;lt;int&amp;gt;.Create(),
                State = -1
            };
        multiCallMethodAsyncStateMachine.Builder.Start(ref multiCallMethodAsyncStateMachine);
        return multiCallMethodAsyncStateMachine.Builder.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also creates and starts one single state machine, MultiCallMethodAsyncStateMachine, with more logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine
{
    public int State;
    public AsyncTaskMethodBuilder&amp;lt;int&amp;gt; Builder;
    public int Arg0;
    public int Arg1;
    public int Arg2;
    public int Arg3;
    public int ResultOfAwait1;
    public int ResultOfAwait2;
    public int ResultToReturn;
    private TaskAwaiter&amp;lt;int&amp;gt; awaiter;

    void IAsyncStateMachine.MoveNext()
    {
        try
        {
            switch (this.State)
            {
                case -1:
                    HelperMethods.Before();
                    this.awaiter = AsyncMethods.MethodAsync(this.Arg0, this.Arg1).GetAwaiter();
                    if (!this.awaiter.IsCompleted)
                    {
                        this.State = 0;
                        this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
                    }
                    break;
                case 0:
                    this.ResultOfAwait1 = this.awaiter.GetResult();
                    HelperMethods.Continuation1(this.ResultOfAwait1);
                    this.awaiter = AsyncMethods.MethodAsync(this.Arg2, this.Arg3).GetAwaiter();
                    if (!this.awaiter.IsCompleted)
                    {
                        this.State = 1;
                        this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this);
                    }
                    break;
                case 1:
                    this.ResultOfAwait2 = this.awaiter.GetResult();
                    HelperMethods.Continuation2(this.ResultOfAwait2);
                    this.ResultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2;
                    this.State = -2;
                    this.Builder.SetResult(this.ResultToReturn);
                    break;
            }
        }
        catch (Exception exception)
        {
            this.State = -2;
            this.Builder.SetException(exception);
        }
    }

    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        this.Builder.SetStateMachine(stateMachine);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code is already cleaned up, but there are still a lot of things. To &lt;a href=&quot;http://en.wikipedia.org/wiki/KISS_principle&quot;&gt;keep it simple stupid&lt;/a&gt;, the state machine can be rewritten as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine
{
    // State:
    // -1: Begin
    //  0: 1st await is done
    //  1: 2nd await is done
    //     ...
    // -2: End
    public int State;
    public TaskCompletionSource&amp;lt;int&amp;gt; ResultToReturn; // int resultToReturn ...
    public int Arg0; // int Arg0
    public int Arg1; // int arg1
    public int Arg2; // int arg2
    public int Arg3; // int arg3
    public int ResultOfAwait1; // int resultOfAwait1 ...
    public int ResultOfAwait2; // int resultOfAwait2 ...
    private Task&amp;lt;int&amp;gt; currentTaskToAwait;

    /// &amp;lt;summary&amp;gt;
    /// Moves the state machine to its next state.
    /// &amp;lt;/summary&amp;gt;
    void IAsyncStateMachine.MoveNext()
    {
        try
        {
            switch (this.State)
            {
                IAsyncStateMachine that = this; // Cannot use &quot;this&quot; in lambda so create a local copy. 
                // Orginal code is splitted by &quot;case&quot;s:
                // case -1:
                //      HelperMethods.Before();
                //      MethodAsync(Arg0, arg1);
                // case 0:
                //      int resultOfAwait1 = await ...
                //      HelperMethods.Continuation1(resultOfAwait1);
                //      MethodAsync(arg2, arg3);
                // case 1:
                //      int resultOfAwait2 = await ...
                //      HelperMethods.Continuation2(resultOfAwait2);
                //      int resultToReturn = resultOfAwait1 + resultOfAwait2;
                //      return resultToReturn;
                case -1: // -1 is begin.
                    HelperMethods.Before(); // Code before 1st await.
                    this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg0, this.Arg1); // 1st task to await
                    // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 0.
                    this.State = 0;
                    this.currentTaskToAwait.ContinueWith(_ =&amp;gt; that.MoveNext()); // Callback
                    break;
                case 0: // Now 1st await is done.
                    this.ResultOfAwait1 = this.currentTaskToAwait.Result; // Get 1st await&apos;s result.
                    HelperMethods.Continuation1(this.ResultOfAwait1); // Code after 1st await and before 2nd await.
                    this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg2, this.Arg3); // 2nd task to await
                    // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 1.
                    this.State = 1;
                    this.currentTaskToAwait.ContinueWith(_ =&amp;gt; that.MoveNext()); // Callback
                    break;
                case 1: // Now 2nd await is done.
                    this.ResultOfAwait2 = this.currentTaskToAwait.Result; // Get 2nd await&apos;s result.
                    HelperMethods.Continuation2(this.ResultOfAwait2); // Code after 2nd await.
                    int resultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2; // Code after 2nd await.
                    // End with resultToReturn. No more invocation of MoveNext().
                    this.State = -2; // -2 is end.
                    this.ResultToReturn.SetResult(resultToReturn);
                    break;
            }
        }
        catch (Exception exception)
        {
            // End with exception.
            this.State = -2; // -2 is end. Exception will also when the execution of state machine.
            this.ResultToReturn.SetException(exception);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Configures the state machine with a heap-allocated replica.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;stateMachine&quot;&amp;gt;The heap-allocated replica.&amp;lt;/param&amp;gt;
    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        // No core logic.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only Task and TaskCompletionSource are involved in this revised version. And MultiCallMethodAsync() can be also simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[DebuggerStepThrough]
[AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async
internal static /*async*/ Task&amp;lt;int&amp;gt; MultiCallMethodAsync_(int arg0, int arg1, int arg2, int arg3)
{
    MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine()
        {
            Arg0 = arg0,
            Arg1 = arg1,
            Arg2 = arg2,
            Arg3 = arg3,
            ResultToReturn = new TaskCompletionSource&amp;lt;int&amp;gt;(),
            // -1: Begin
            //  0: 1st await is done
            //  1: 2nd await is done
            //     ...
            // -2: End
            State = -1
        };
    (multiCallMethodAsyncStateMachine as IAsyncStateMachine).MoveNext(); // Original code are in this method.
    return multiCallMethodAsyncStateMachine.ResultToReturn.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the entire state machine becomes very clear - it is about callback:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Original code are split into pieces by “await”s, and each piece is put into each “case” in the state machine. Here the 2 awaits split the code into 3 pieces, so there are 3 “case”s.&lt;/li&gt;
&lt;li&gt;The “piece”s are chained by callback, that is done by Builder.AwaitUnsafeOnCompleted(callback), or currentTaskToAwait.ContinueWith(callback) in the simplified code.&lt;/li&gt;
&lt;li&gt;A previous “piece” will end with a Task (which is to be awaited), when the task is done, it will callback the next “piece”.&lt;/li&gt;
&lt;li&gt;The state machine’s state works with the “case”s to ensure the code “piece”s executes one after another.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;It is like callbacks&lt;/h2&gt;
&lt;p&gt;Since it is like callbacks, the simplification can go even further – the entire state machine can be completely replaced by Task.ContinueWith(). Now MultiCallMethodAsync() becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
{
    TaskCompletionSource&amp;lt;int&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;int&amp;gt;();
    try
    {
        HelperMethods.Before();
        MethodAsync(arg0, arg1).ContinueWith(await1 =&amp;gt;
            {
                try
                {
                    int resultOfAwait1 = await1.Result;
                    HelperMethods.Continuation1(resultOfAwait1);
                    MethodAsync(arg2, arg3).ContinueWith(await2 =&amp;gt;
                        {
                            try
                            {
                                int resultOfAwait2 = await2.Result;
                                HelperMethods.Continuation2(resultOfAwait2);
                                int resultToReturn = resultOfAwait1 + resultOfAwait2;
                                taskCompletionSource.SetResult(resultToReturn);
                            }
                            catch (Exception exception)
                            {
                                taskCompletionSource.SetException(exception);
                            }
                        });
                }
                catch (Exception exception)
                {
                    taskCompletionSource.SetException(exception);
                }
            });
    }
    catch (Exception exception)
    {
        taskCompletionSource.SetException(exception);
    }
    return taskCompletionSource.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to compare with the original async / await code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static async Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
{
    HelperMethods.Before();
    int resultOfAwait1 = await MethodAsync(arg0, arg1);
    HelperMethods.Continuation1(resultOfAwait1);
    int resultOfAwait2 = await MethodAsync(arg2, arg3);
    HelperMethods.Continuation2(resultOfAwait2);
    int resultToReturn = resultOfAwait1 + resultOfAwait2;
    return resultToReturn;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the above code can be reformatted for easier reading:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task&amp;lt;int&amp;gt; MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3)
{
    TaskCompletionSource&amp;lt;int&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;int&amp;gt;(); try {

    // Original code begins.
    HelperMethods.Before();
    // int resultOfAwait1 = await MethodAsync(arg0, arg1);
    MethodAsync(arg0, arg1).ContinueWith(await1 =&amp;gt; { try { int resultOfAwait1 = await1.Result;
    HelperMethods.Continuation1(resultOfAwait1);
    // int resultOfAwait2 = await MethodAsync(arg2, arg3);
    MethodAsync(arg2, arg3).ContinueWith(await2 =&amp;gt; { try { int resultOfAwait2 = await2.Result;
    HelperMethods.Continuation2(resultOfAwait2);
    int resultToReturn = resultOfAwait1 + resultOfAwait2;
    // return resultToReturn;
    taskCompletionSource.SetResult(resultToReturn);
    // Original code ends.

    } catch (Exception exception) { taskCompletionSource.SetException(exception); }});
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }});
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }
    return taskCompletionSource.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yeah that is the magic of C# async / await:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Await is literally pretending to wait. In a await expression, a Task object will be return immediately so that calling thread is not blocked. The continuation code is compiled as that Task’s callback code.&lt;/li&gt;
&lt;li&gt;When that task is done, continuation code will execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the above callback code has a context handling issue at runtime, which will be explained and fixed in &lt;a href=&quot;/posts/understanding-c-sharp-async-await-3-runtime-context&quot;&gt;part 3&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Use Task.Yeild()&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.yield.aspx&quot;&gt;Task.Yeild()&lt;/a&gt; is an interesting built-in API:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use await Task.Yield(); in an asynchronous method to force the method to complete asynchronously.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void NoYeild()
{
    HelperMethods.Before();
    HelperMethods.Continuation(0);
    // Returns after HelperMethods.Continuation(0) finishes execution.
}

internal static async Task YeildAsync()
{
    HelperMethods.Before();
    await Task.Yield(); // Returns without waiting for continuation code to execute.
    HelperMethods.Continuation(0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here await Task.Yield(); indicates to compile the following HelperMethods.Continuation(0); like a callback. So, similarly, it can be rewritten as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task YeildAsync()
{
    TaskCompletionSource&amp;lt;object&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;object&amp;gt;();
    try
    {
        HelperMethods.Before();
        Task yeild = new Task(() =&amp;gt; { });
        yeild.Start();
        yeild.ContinueWith(await =&amp;gt;
            {
                try
                {
                    HelperMethods.Continuation(0);
                    taskCompletionSource.SetResult(null);
                }
                catch (Exception exception)
                {
                    taskCompletionSource.SetException(exception);
                }
            });
    }
    catch (Exception exception)
    {
        taskCompletionSource.SetException(exception);
    }

    return taskCompletionSource.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here TaskCompletionSource&amp;lt;object&amp;gt; is used, since &lt;a href=&quot;https://social.msdn.microsoft.com/Forums/vstudio/en-US/f6ee1462-d3ef-40ed-801a-76bdfaf01e1e/feedback-taskcompletionsourcet-used-with-task?forum=parallelextensions&quot;&gt;.NET does not provided a non-generic TaskCompletionSource class&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, this can be reformatted to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static Task YeildAsync()
{
    TaskCompletionSource&amp;lt;object&amp;gt; taskCompletionSource = new TaskCompletionSource&amp;lt;object&amp;gt;(); try {

    // Original code begins.
    HelperMethods.Before();
    // await Task.Yeild();
    Task yeild = new Task(() =&amp;gt; { }); yeild.Start(); yeild.ContinueWith(await =&amp;gt; { try {
    HelperMethods.Continuation(0);
    // Original code ends.

    taskCompletionSource.SetResult(null);
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }});
    } catch (Exception exception) { taskCompletionSource.SetException(exception); }
    return taskCompletionSource.Task;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In another word, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.yield.aspx&quot;&gt;Task.Yeild()&lt;/a&gt; makes the method returns right there immediately, and schedule its continuation code to CPU asynchromously, which creates a chance for other tasks to be scheduled to CPU first. This is similar concept to the setTimeout() approach in &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var sync = function () {
    before();
    continuation();
    // Returns after continuation finishes execution.
};
var async = function () {
    before();
    setTimeout(continuation, 0);
    // Returns immediately (after setTimeout finishes execution).
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;except JavaScript has a single threading model.&lt;/p&gt;
&lt;p&gt;Again, the above ContinueWith() callback code has the same context handling issue at runtime, which will be explained and fixed in &lt;a href=&quot;/posts/understanding-c-sharp-async-await-3-runtime-context&quot;&gt;part 3&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Recover Outlook 2010 from crash</title><link>https://dixin.github.io/posts/recover-outlook-2010-from-crash/</link><guid isPermaLink="true">https://dixin.github.io/posts/recover-outlook-2010-from-crash/</guid><description>Today my  crashed while I am writing an email. When I restart I got this error:</description><pubDate>Thu, 15 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today my &lt;a href=&quot;http://office.microsoft.com/en-us/outlook/&quot;&gt;Outlook 2010&lt;/a&gt; crashed while I am writing an email. When I restart I got this error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;‘Microsoft Office Outlook’ exited without properly closing your Outlook data file ‘c:\Users\dixinyan\AppData\Local\Microsoft\Outlook\dixinyan@microsoft.com.ost’. ‘Microsoft Office Outlook’ must be restarted. If this error message recurs, contact support for ‘Microsoft Office Outlook’ for assistance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_2DDFDB73.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_thumb_01FF61B7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After clicking OK:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cannot start Microsoft Outlook. Cannot open the Outlook window. The set of folder cannot be opened.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_095B2164.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_thumb_5395B63C.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So that I cannot start my Outlook. I checked the Task Manager and found the outlook.exe is not there. So I have to go to &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb896653&quot;&gt;Process Explorer&lt;/a&gt;, a tool of &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb842062&quot;&gt;Sysinternals&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_2246CBDC.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_thumb_0F259F30.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After terminating UcMapi64.exe, Outlook was back. So the conclusion is: it looks Microsoft &lt;a href=&quot;http://lync.microsoft.com/en-us/Pages/unified-communications.aspx&quot;&gt;Lync 2010&lt;/a&gt; killed Microsoft &lt;a href=&quot;http://office.microsoft.com/en-us/outlook/&quot;&gt;Outlook 2010&lt;/a&gt;!&lt;/p&gt;
</content:encoded></item><item><title>My new car at Microsoft Building 35</title><link>https://dixin.github.io/posts/my-new-car-at-microsoft-building-35/</link><guid isPermaLink="true">https://dixin.github.io/posts/my-new-car-at-microsoft-building-35/</guid><description>I got this from the local dealership. These photos were taken at Microsoft Building 35:</description><pubDate>Mon, 06 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I got this from the local dealership. These photos were taken at Microsoft Building 35:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1174_7C1D4F67.jpg&quot; alt=&quot;DSC_1174&quot; title=&quot;DSC_1174&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1167_7AD8B688.jpg&quot; alt=&quot;DSC_1167&quot; title=&quot;DSC_1167&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1172_15A4DC95.jpg&quot; alt=&quot;DSC_1172&quot; title=&quot;DSC_1172&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1656_1F1D9B0B.jpg&quot; alt=&quot;DSC_1656&quot; title=&quot;DSC_1656&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1658_1DD9022C.jpg&quot; alt=&quot;DSC_1658&quot; title=&quot;DSC_1658&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1676_15E15FCA.jpg&quot; alt=&quot;DSC_1676&quot; title=&quot;DSC_1676&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1680_30AD85D6.jpg&quot; alt=&quot;DSC_1680&quot; title=&quot;DSC_1680&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_2471_4CB0D365.jpg&quot; alt=&quot;DSC_2471&quot; title=&quot;DSC_2471&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1704_4F83F9B4.jpg&quot; alt=&quot;DSC_1704&quot; title=&quot;DSC_1704&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1677_329AD4DF.jpg&quot; alt=&quot;DSC_1677&quot; title=&quot;DSC_1677&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_1697_7DADCFA1.jpg&quot; alt=&quot;DSC_1697&quot; title=&quot;DSC_1697&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (11) Performance</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-11-performance/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-11-performance/</guid><description>\]</description><pubDate>Mon, 31 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;LINQ to SQL has a lot of great features like&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;strong typing&lt;/li&gt;
&lt;li&gt;query compilation&lt;/li&gt;
&lt;li&gt;deferred execution&lt;/li&gt;
&lt;li&gt;declarative paradigm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc., which are very productive. Of course, these cannot be free, and one price is the performance.&lt;/p&gt;
&lt;h2&gt;O/R mapping overhead&lt;/h2&gt;
&lt;p&gt;Because LINQ to SQL is based on O/R mapping, one obvious overhead is, data changing usually requires data retrieving:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void UpdateProductUnitPrice(int id, decimal unitPrice)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        Product product = database.Products.Single(item =&amp;gt; item.ProductID == id); // SELECT...
        product.UnitPrice = unitPrice; // UPDATE...
        database.SubmitChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before updating an entity, that entity has to be retrieved by an extra SELECT query. This is slower than direct data update via ADO.NET:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void UpdateProductUnitPrice(int id, decimal unitPrice)
{
    using (SqlConnection connection = new SqlConnection(
        &quot;Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True&quot;))
    using (SqlCommand command = new SqlCommand(
        @&quot;UPDATE [dbo].[Products] SET [UnitPrice] = @UnitPrice WHERE [ProductID] = @ProductID&quot;,
        connection))
    {
        command.Parameters.Add(&quot;@ProductID&quot;, SqlDbType.Int).Value = id;
        command.Parameters.Add(&quot;@UnitPrice&quot;, SqlDbType.Money).Value = unitPrice;

        connection.Open();
        command.Transaction = connection.BeginTransaction();
        command.ExecuteNonQuery(); // UPDATE...
        command.Transaction.Commit();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above imperative code specifies the “how to do” details with better performance.&lt;/p&gt;
&lt;p&gt;For the same reason, some articles from Internet insist that, when updating data via LINQ to SQL, the above declarative code should be replaced by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void UpdateProductUnitPrice(int id, decimal unitPrice)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        database.ExecuteCommand(
            &quot;UPDATE [dbo].[Products] SET [UnitPrice] = {0} WHERE [ProductID] = {1}&quot;,
            id, 
            unitPrice);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or just create a stored procedure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE PROCEDURE [dbo].[UpdateProductUnitPrice]
(
    @ProductID INT,
    @UnitPrice MONEY
)
AS
BEGIN
    BEGIN TRANSACTION 
    UPDATE [dbo].[Products] SET [UnitPrice] = @UnitPrice WHERE [ProductID] = @ProductID
    COMMIT TRANSACTION
END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and map it as a method of NorthwindDataContext (explained in &lt;a href=&quot;/posts/understanding-linq-to-sql-1-object-relational-mapping&quot;&gt;this post&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void UpdateProductUnitPrice(int id, decimal unitPrice)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        database.UpdateProductUnitPrice(id, unitPrice);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a normal trade off for O/R mapping, a decision has to be made between performance overhead and programming productivity according to the case. In a developer’s perspective, if O/R mapping is chosen, I consistently choose the declarative LINQ code, unless this kind of overhead is unacceptable.&lt;/p&gt;
&lt;h2&gt;Data retrieving overhead&lt;/h2&gt;
&lt;p&gt;After talking about the O/R mapping specific issue. Now look into the LINQ to SQL specific issues, for example, performance in the data retrieving process. The previous post has explained that the SQL translating and executing is complex. Actually, &lt;a href=&quot;http://blogs.msdn.com/b/charlie/archive/2007/08/06/linq-to-sql-pipeline-video-with-luca-bolognese-and-matt-warren.aspx&quot;&gt;the LINQ to SQL pipeline&lt;/a&gt; is similar to the compiler pipeline. It consists of about 15 steps to translate an C# expression tree to SQL statement, which can be categorized as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Convert: Invoke SqlProvider.BuildQuery() to convert the tree of Expression nodes into a tree of SqlNode nodes;&lt;/li&gt;
&lt;li&gt;Bind: Used visitor pattern to figure out the meanings of names according to the mapping info, like a property for a column, etc.;&lt;/li&gt;
&lt;li&gt;Flatten: Figure out the hierarchy of the query;&lt;/li&gt;
&lt;li&gt;Rewrite: for SQL Server 2000, if needed&lt;/li&gt;
&lt;li&gt;Reduce: Remove the unnecessary information from the tree.&lt;/li&gt;
&lt;li&gt;Parameterize
&lt;ul&gt;
&lt;li&gt;Format: Generate the SQL statement string;&lt;/li&gt;
&lt;li&gt;Parameterize: Figure out the parameters, for example, a reference to a local variable should be a parameter in SQL;&lt;/li&gt;
&lt;li&gt;Materialize: Executes the reader and convert the result back into typed objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;So for each data retrieving, even for data retrieving which looks simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static Product[] RetrieveProducts(int productId)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        return database.Products.Where(product =&amp;gt; product.ProductID == productId)
                                .ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LINQ to SQL goes through above steps to translate and execute the query. Fortunately, there is a built-in way to cache the translated query.&lt;/p&gt;
&lt;h3&gt;Compiled query&lt;/h3&gt;
&lt;p&gt;When such a LINQ to SQL query is executed repeatedly, The CompiledQuery can be used to translate query for one time, and execute for multiple times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class CompiledQueries
{
    private static readonly Func&amp;lt;NorthwindDataContext, int, Product[]&amp;gt; _retrieveProducts = 
        CompiledQuery.Compile((NorthwindDataContext database, int productId) =&amp;gt;
            database.Products.Where(product =&amp;gt; product.ProductID == productId).ToArray());

    internal static Product[] RetrieveProducts(
        this NorthwindDataContext database, int productId)
    {
        return _retrieveProducts(database, productId);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The new version of RetrieveProducts() gets better performance, because only when _retrieveProducts is first time invoked, it internally invokes SqlProvider.Compile() to translate the query expression. And it also uses lock to make sure translating once in multi-threading scenarios.&lt;/p&gt;
&lt;h3&gt;Static SQL / stored procedures without translating&lt;/h3&gt;
&lt;p&gt;Another way to avoid the translating overhead is to use static SQL or stored procedures, just as the above examples. Because this is a functional programming series, this article not dive into. For the details, &lt;a href=&quot;http://en.wikipedia.org/wiki/Scott_Guthrie&quot;&gt;Scott Guthrie&lt;/a&gt; already has some excellent articles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx&quot;&gt;LINQ to SQL (Part 6: Retrieving Data Using Stored Procedures)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://weblogs.asp.net/scottgu/archive/2007/08/23/linq-to-sql-part-7-updating-our-database-using-stored-procedures.aspx&quot;&gt;LINQ to SQL (Part 7: Updating our Database using Stored Procedures)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://weblogs.asp.net/scottgu/archive/2007/08/27/linq-to-sql-part-8-executing-custom-sql-expressions.aspx&quot;&gt;LINQ to SQL (Part 8: Executing Custom SQL Expressions)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Data changing overhead&lt;/h2&gt;
&lt;p&gt;By looking into the data updating process, it also needs a lot of work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Begins transaction&lt;/li&gt;
&lt;li&gt;Processes the changes (ChangeProcessor)
&lt;ul&gt;
&lt;li&gt;Walks through the objects to identify the changes&lt;/li&gt;
&lt;li&gt;Determines the order of the changes&lt;/li&gt;
&lt;li&gt;Executes the changings
&lt;ul&gt;
&lt;li&gt;LINQ queries may be needed to execute the changings, like the first example in this article, an object needs to be retrieved before changed, then the above whole process of data retrieving will be went through&lt;/li&gt;
&lt;li&gt;If there is user customization, it will be executed, for example, a table’s INSERT / UPDATE / DELETE can be customized in the O/R designer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_6DCBF16A.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It is important to keep these overhead in mind.&lt;/p&gt;
&lt;h3&gt;Bulk deleting / updating&lt;/h3&gt;
&lt;p&gt;Another thing to be aware is the bulk deleting:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void DeleteProducts(int categoryId)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        database.Products.DeleteAllOnSubmit(
            database.Products.Where(product =&amp;gt; product.CategoryID == categoryId));
        database.SubmitChanges();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The expected SQL should be like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION 
exec sp_executesql N&apos;DELETE FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=9
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hoverer, as fore mentioned, the actual SQL is to retrieving the entities, and then delete them one by one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Retrieves the entities to be deleted:
exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=9

-- Deletes the retrieved entities one by one:
BEGIN TRANSACTION 
exec sp_executesql N&apos;DELETE FROM [dbo].[Products] WHERE ([ProductID] = @p0) AND ([ProductName] = @p1) AND ([SupplierID] IS NULL) AND ([CategoryID] = @p2) AND ([QuantityPerUnit] IS NULL) AND ([UnitPrice] = @p3) AND ([UnitsInStock] = @p4) AND ([UnitsOnOrder] = @p5) AND ([ReorderLevel] = @p6) AND (NOT ([Discontinued] = 1))&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 int,@p3 money,@p4 smallint,@p5 smallint,@p6 smallint&apos;,@p0=78,@p1=N&apos;Optimus Prime&apos;,@p2=9,@p3=$0.0000,@p4=0,@p5=0,@p6=0
exec sp_executesql N&apos;DELETE FROM [dbo].[Products] WHERE ([ProductID] = @p0) AND ([ProductName] = @p1) AND ([SupplierID] IS NULL) AND ([CategoryID] = @p2) AND ([QuantityPerUnit] IS NULL) AND ([UnitPrice] = @p3) AND ([UnitsInStock] = @p4) AND ([UnitsOnOrder] = @p5) AND ([ReorderLevel] = @p6) AND (NOT ([Discontinued] = 1))&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 int,@p3 money,@p4 smallint,@p5 smallint,@p6 smallint&apos;,@p0=79,@p1=N&apos;Bumble Bee&apos;,@p2=9,@p3=$0.0000,@p4=0,@p5=0,@p6=0
-- ...
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the same to the bulk updating. This is really not effective and need to be aware. Here is already some solutions from the Internet, like &lt;a href=&quot;http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx&quot;&gt;this one&lt;/a&gt;. The idea is wrap the above SELECT statement into a INNER JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;DELETE [dbo].[Products] FROM [dbo].[Products] AS [j0] 
INNER JOIN (   
SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0) AS [j1] 
ON ([j0].[ProductID] = [j1].[[Products])&apos;, -- The Primary Key
N&apos;@p0 int&apos;,@p0=9
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Query plan overhead&lt;/h2&gt;
&lt;p&gt;The last thing is about the SQL Server &lt;a href=&quot;http://en.wikipedia.org/wiki/Query_plan&quot;&gt;query plan&lt;/a&gt;. Before .NET 4.0, LINQ to SQL has an issue (not sure if it is a bug). LINQ to SQL internally uses ADO.NET, but it does not set the SqlParameter.Size for a variable-length argument, like argument of NVARCHAR type, etc. So for two queries with the same SQL but different argument length:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    database.Products.Where(product =&amp;gt; product.ProductName == &quot;A&quot;)
        .Select(product =&amp;gt; product.ProductID).ToArray();

    // The same SQL and argument type, different argument length.
    database.Products.Where(product =&amp;gt; product.ProductName == &quot;AA&quot;)
        .Select(product =&amp;gt; product.ProductID).ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pay attention to the argument length in the translated SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] = @p0&apos;,N&apos;@p0 nvarchar(1)&apos;,@p0=N&apos;A&apos;

exec sp_executesql N&apos;SELECT [t0].[ProductID]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] = @p0&apos;,N&apos;@p0 nvarchar(2)&apos;,@p0=N&apos;AA&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the overhead: The first query’s query plan cache is not reused by the second one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT sys.syscacheobjects.cacheobjtype, sys.dm_exec_cached_plans.usecounts, sys.syscacheobjects.[sql] FROM sys.syscacheobjects
INNER JOIN sys.dm_exec_cached_plans
ON sys.syscacheobjects.bucketid = sys.dm_exec_cached_plans.bucketid;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_539DF983.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;They actually use different query plans. Again, pay attention to the argument length in the [sql] column (@p0 nvarchar(2) / @p0 nvarchar(1)).&lt;/p&gt;
&lt;p&gt;Fortunately, in .NET 4.0 this is fixed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class SqlTypeSystem
{
    private abstract class ProviderBase : TypeSystemProvider
    {
        protected int? GetLargestDeclarableSize(SqlType declaredType)
        {
            SqlDbType sqlDbType = declaredType.SqlDbType;
            if (sqlDbType &amp;lt;= SqlDbType.Image)
            {
                switch (sqlDbType)
                {
                    case SqlDbType.Binary:
                    case SqlDbType.Image:
                        return 8000;
                }

                return null;
            }

            if (sqlDbType == SqlDbType.NVarChar)
            {
                return 4000; // Max length for NVARCHAR.
            }

            if (sqlDbType != SqlDbType.VarChar)
            {
                return null;
            }

            return 8000;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this above example, the translated SQL becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] = @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;A&apos;

exec sp_executesql N&apos;SELECT [t0].[ProductID]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] = @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;AA&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that they reuses the same query plan cache:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_0660D825.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now the [usecounts] column is 2.&lt;/p&gt;
</content:encoded></item><item><title>A DirectoryCatalog class for Silverlight MEF (Managed Extensibility Framework)</title><link>https://dixin.github.io/posts/a-directorycatalog-for-silverlight-mef-managed-extensibility-framework/</link><guid isPermaLink="true">https://dixin.github.io/posts/a-directorycatalog-for-silverlight-mef-managed-extensibility-framework/</guid><description>In the MEF (Managed Extension Framework) for .NET, there are useful ComposablePartCatalog implementations in System.ComponentModel.Composition.dll, like:</description><pubDate>Sat, 29 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the MEF (Managed Extension Framework) for .NET, there are useful ComposablePartCatalog implementations in System.ComponentModel.Composition.dll, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.ComponentModel.Composition.Hosting.AggregateCatalog&lt;/li&gt;
&lt;li&gt;System.ComponentModel.Composition.Hosting.AssemblyCatalog&lt;/li&gt;
&lt;li&gt;System.ComponentModel.Composition.Hosting.DirectoryCatalog&lt;/li&gt;
&lt;li&gt;System.ComponentModel.Composition.Hosting.TypeCatalog&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While in Silverlight, there is a extra System.ComponentModel.Composition.Hosting.DeploymentCatalog. As a wrapper of AssemblyCatalog, it can load all assemblies in a XAP file in the web server side. Unfortunately, in silverlight there is no DirectoryCatalog to load a folder.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#background&quot;&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#retrieve-file-list-from-a-directory&quot;&gt;Retrieve file list from a directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#download-the-directorys-xap-file-list&quot;&gt;Download the directory&apos;s XAP file list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#download-all-xap-files&quot;&gt;Download all XAP files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#exception-handling&quot;&gt;Exception handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;There are scenarios that Silverlight application may need to load all XAP files in a folder in the web server side, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the Silverlight application is extensible and supports plug-ins, there would be something like a Plugins folder in the web server, and each pluin would be an individual XAP file in the folder. In this scenario, after the application is loaded and started up, it would like to load all XAP files in Plugins folder.&lt;/li&gt;
&lt;li&gt;If the aplication supports themes, there would be something like a Themes folder, and each theme would be an individual XAP file too. The application would also need to load all XAP files in Themes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is useful if we have a DirectoryCatalog:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DirectoryCatalog catalog = new DirectoryCatalog(&quot;/Plugins&quot;);
catalog.DownloadCompleted += (sender, e) =&amp;gt; { };
catalog.DownloadAsync();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously, the implementation of DirectoryCatalog is easy. It is just a collection of DeploymentCatalog class.&lt;/p&gt;
&lt;h2&gt;Retrieve file list from a directory&lt;/h2&gt;
&lt;p&gt;Of course, to retrieve file list from a web folder, the folder&apos;s &apos;Directory Browsing&apos; feature must be enabled:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_71CB93DF.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So when the folder is requested, it responses a list of its files and folders:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_227E9B8B.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is nothing but a simple HTML page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;localhost - /Folder/&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;localhost - /Folder/&amp;lt;/h1&amp;gt;
        &amp;lt;hr&amp;gt;
        &amp;lt;pre&amp;gt;
            &amp;lt;a href=&quot;/&quot;&amp;gt;[To Parent Directory]&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
            &amp;lt;br&amp;gt;
            1/3/2011  7:22 PM   185 &amp;lt;a href=&quot;/Folder/File.txt&quot;&amp;gt;File.txt&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
            1/3/2011  7:22 PM   &amp;amp;lt;dir&amp;amp;gt; &amp;lt;a href=&quot;/Folder/Folder/&quot;&amp;gt;Folder&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
        &amp;lt;/pre&amp;gt;
        &amp;lt;hr&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the ASP.NET Deployment Server of Visual Studio, directory browsing is enabled by default:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_1D2FB4DA.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The HTML &amp;lt;Body&amp;gt; is almost the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;body bgcolor=&quot;white&quot;&amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;i&amp;gt;Directory Listing -- /ClientBin/&amp;lt;/i&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;hr width=&quot;100%&quot; size=&quot;1&quot; color=&quot;silver&quot;&amp;gt;
    &amp;lt;pre&amp;gt;
        &amp;lt;a href=&quot;/&quot;&amp;gt;[To Parent Directory]&amp;lt;/a&amp;gt;
        Thursday, January 27, 2011 11:51 PM 282,538 &amp;lt;a href=&quot;Test.xap&quot;&amp;gt;Test.xap&amp;lt;/a&amp;gt;
        Tuesday, January 04, 2011 02:06 AM  &amp;amp;lt;dir&amp;amp;gt; &amp;lt;a href=&quot;TestFolder/&quot;&amp;gt;TestFolder&amp;lt;/a&amp;gt;
    &amp;lt;/pre&amp;gt;
    &amp;lt;hr width=&quot;100%&quot; size=&quot;1&quot; color=&quot;silver&quot;&amp;gt;
    &amp;lt;b&amp;gt;Version Information:&amp;lt;/b&amp;gt;&amp;amp;nbsp;ASP.NET Development Server 10.0.0.0 
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only difference is, IIS&apos;s links start with slash, but here the links do not.&lt;/p&gt;
&lt;p&gt;Here one way to get the file list is read the href attributes of the links:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pure]
private IEnumerable&amp;lt;Uri&amp;gt; GetFilesFromDirectory(string html)
{
    Contract.Requires(html != null);
    Contract.Ensures(Contract.Result&amp;lt;IEnumerable&amp;lt;Uri&amp;gt;&amp;gt;() != null);

    return new Regex(
                    &quot;&amp;lt;a href=\&quot;(?&amp;lt;uriRelative&amp;gt;[^\&quot;]*)\&quot;&amp;gt;[^&amp;lt;]*&amp;lt;/a&amp;gt;&quot;,
                    RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)
                .Matches(html)
                .OfType&amp;lt;Match&amp;gt;()
                .Where(match =&amp;gt; match.Success)
                .Select(match =&amp;gt; match.Groups[&quot;uriRelative&quot;].Value)
                .Where(uriRelative =&amp;gt; uriRelative.EndsWith(&quot;.xap&quot;, StringComparison.Ordinal))
                .Select(uriRelative =&amp;gt;
                    {
                        Uri baseUri = this.Uri.IsAbsoluteUri
                                            ? this.Uri
                                            : new Uri(Application.Current.Host.Source, this.Uri);
                        uriRelative = uriRelative.StartsWith(&quot;/&quot;, StringComparison.Ordinal)
                                            ? uriRelative
                                            : (baseUri.LocalPath.EndsWith(&quot;/&quot;, StringComparison.Ordinal)
                                                    ? baseUri.LocalPath + uriRelative
                                                    : baseUri.LocalPath + &quot;/&quot; + uriRelative);
                        return new Uri(baseUri, uriRelative);
                    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice the folders&apos; links end with a slash. They are filtered by the second Where() query.&lt;/p&gt;
&lt;p&gt;The above method can find files&apos; URIs from the specified IIS folder, or ASP.NET Deployment Server folder while debugging. To support other formats of file list, a constructor is needed to pass into a customized method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Initializes a new instance of the &amp;lt;see cref=&quot;T:System.ComponentModel.Composition.Hosting.DirectoryCatalog&quot; /&amp;gt; class with &amp;lt;see cref=&quot;T:System.ComponentModel.Composition.Primitives.ComposablePartDefinition&quot; /&amp;gt; objects based on all the XAP files in the specified directory URI.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;uri&quot;&amp;gt;
/// URI to the directory to scan for XAPs to add to the catalog.
/// The URI must be absolute, or relative to &amp;lt;see cref=&quot;P:System.Windows.Interop.SilverlightHost.Source&quot; /&amp;gt;.
/// &amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;getFilesFromDirectory&quot;&amp;gt;
/// The method to find files&apos; URIs in the specified directory.
/// &amp;lt;/param&amp;gt;
public DirectoryCatalog(Uri uri, Func&amp;lt;string, IEnumerable&amp;lt;Uri&amp;gt;&amp;gt; getFilesFromDirectory)
{
    Contract.Requires(uri != null);

    this._uri = uri;
    this._getFilesFromDirectory = getFilesFromDirectory ?? this.GetFilesFromDirectory;
    this._webClient = new Lazy&amp;lt;WebClient&amp;gt;(() =&amp;gt; new WebClient());

    // Initializes other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the getFilesFromDirectory parameter is null, the above GetFilesFromDirectory() method will be used as default.&lt;/p&gt;
&lt;h2&gt;Download the directory&apos;s XAP file list&lt;/h2&gt;
&lt;p&gt;Now a public method can be created to start the downloading:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Begins downloading the XAP files in the directory.
/// &amp;lt;/summary&amp;gt;
public void DownloadAsync()
{
    this.ThrowIfDisposed();

    if (Interlocked.CompareExchange(ref this._state, State.DownloadStarted, State.Created) == 0)
    {
        this._webClient.Value.OpenReadCompleted += this.HandleOpenReadCompleted;
        this._webClient.Value.OpenReadAsync(this.Uri, this);
    }
    else
    {
        this.MutateStateOrThrow(State.DownloadCompleted, State.Initialized);
        this.OnDownloadCompleted(new AsyncCompletedEventArgs(null, false, this));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the HandleOpenReadCompleted() method is invoked when the file list HTML is downloaded.&lt;/p&gt;
&lt;h2&gt;Download all XAP files&lt;/h2&gt;
&lt;p&gt;After retrieving all files&apos; URIs, the next thing becomes even easier. HandleOpenReadCompleted() just uses built in DeploymentCatalog to download the XAPs, and aggregate them into one AggregateCatalog:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void HandleOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    Exception error = e.Error;
    bool cancelled = e.Cancelled;
    if (Interlocked.CompareExchange(ref this._state, State.DownloadCompleted, State.DownloadStarted) !=
        State.DownloadStarted)
    {
        cancelled = true;
    }

    if (error == null &amp;amp;&amp;amp; !cancelled)
    {
        try
        {
            using (StreamReader reader = new StreamReader(e.Result))
            {
                string html = reader.ReadToEnd();
                IEnumerable&amp;lt;Uri&amp;gt; uris = this._getFilesFromDirectory(html);

                Contract.Assume(uris != null);

                IEnumerable&amp;lt;DeploymentCatalog&amp;gt; deploymentCatalogs =
                    uris.Select(uri =&amp;gt; new DeploymentCatalog(uri));
                deploymentCatalogs.ForEach(
                    deploymentCatalog =&amp;gt;
                    {
                        this._aggregateCatalog.Catalogs.Add(deploymentCatalog);
                        deploymentCatalog.DownloadCompleted += this.HandleDownloadCompleted;
                    });
                deploymentCatalogs.ForEach(deploymentCatalog =&amp;gt; deploymentCatalog.DownloadAsync());
            }
        }
        catch (Exception exception)
        {
            error = new InvalidOperationException(Resources.InvalidOperationException_ErrorReadingDirectory, exception);
        }
    }

    // Exception handling.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In HandleDownloadCompleted(), if all XAPs are downloaded without exception, OnDownloadCompleted() callback method will be invoked.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void HandleDownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
    if (Interlocked.Increment(ref this._downloaded) == this._aggregateCatalog.Catalogs.Count)
    {
        this.OnDownloadCompleted(e);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Exception handling&lt;/h2&gt;
&lt;p&gt;Whether this DirectoryCatelog can work only if the directory browsing feature is enabled. It is important to inform caller when directory cannot be browsed for XAP downloading.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void HandleOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    Exception error = e.Error;
    bool cancelled = e.Cancelled;
    if (Interlocked.CompareExchange(ref this._state, State.DownloadCompleted, State.DownloadStarted) !=
        State.DownloadStarted)
    {
        cancelled = true;
    }

    if (error == null &amp;amp;&amp;amp; !cancelled)
    {
        try
        {
            // No exception thrown when browsing directory. Downloads the listed XAPs.
        }
        catch (Exception exception)
        {
            error = new InvalidOperationException(Resources.InvalidOperationException_ErrorReadingDirectory, exception);
        }
    }

    WebException webException = error as WebException;
    if (webException != null)
    {
        HttpWebResponse webResponse = webException.Response as HttpWebResponse;
        if (webResponse != null)
        {
            // Internally, WebClient uses WebRequest.Create() to create the WebRequest object. Here does the same thing.
            WebRequest request = WebRequest.Create(Application.Current.Host.Source);

            Contract.Assume(request != null);

            if (request.CreatorInstance == WebRequestCreator.ClientHttp &amp;amp;&amp;amp;
                // Silverlight is in client HTTP handling, all HTTP status codes are supported.
                webResponse.StatusCode == HttpStatusCode.Forbidden)
            {
                // When directory browsing is disabled, the HTTP status code is 403 (forbidden).
                error = new InvalidOperationException(
                    Resources.InvalidOperationException_ErrorListingDirectory_ClientHttp, webException);
            }
            else if (request.CreatorInstance == WebRequestCreator.BrowserHttp &amp;amp;&amp;amp;
                // Silverlight is in browser HTTP handling, only 200 and 404 are supported.
                webResponse.StatusCode == HttpStatusCode.NotFound)
            {
                // When directory browsing is disabled, the HTTP status code is 404 (not found).
                error = new InvalidOperationException(
                    Resources.InvalidOperationException_ErrorListingDirectory_BrowserHttp, webException);
            }
        }
    }

    this.OnDownloadCompleted(new AsyncCompletedEventArgs(error, cancelled, this));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice Silverlight 3+ application can work in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd920295.aspx&quot;&gt;either client HTTP handling, or browser HTTP handling&lt;/a&gt;. One difference is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In browser HTTP handling, only HTTP status code 200 (OK) and 404 (not OK, including 500, 403, etc.) are supported&lt;/li&gt;
&lt;li&gt;In client HTTP handling, all HTTP status code are supported&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So in above code, exceptions in 2 modes are handled differently.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Here is the whole DirectoryCatelog&apos;s looking:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_263C405B.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Please &lt;a href=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Media/SilverlightMefExtensions.zip&quot;&gt;click here to download the source code&lt;/a&gt;, a simple unit test is included. This is a rough implementation. And, for convenience, some design and coding are just following the built in AggregateCatalog class and Deployment class. Please feel free to modify the code, and please kindly tell me if any issue is found.&lt;/p&gt;
</content:encoded></item><item><title>Microsoft Chinese Spring Festival Celebration (2)</title><link>https://dixin.github.io/posts/microsoft-chinese-spring-festival-celebration-2/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsoft-chinese-spring-festival-celebration-2/</guid><description>, Microsoft :</description><pubDate>Tue, 25 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Qi_Lu&quot;&gt;Qi Lu&lt;/a&gt;, Microsoft &lt;a href=&quot;http://www.microsoft.com/presspass/exec/lu/&quot;&gt;President&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0713_30BF2965.jpg&quot; alt=&quot;DSC_0713&quot; title=&quot;DSC_0713&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Made in Taiwan:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0743_7114CCD2.jpg&quot; alt=&quot;DSC_0743&quot; title=&quot;DSC_0743&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0744_6191BB03.jpg&quot; alt=&quot;DSC_0744&quot; title=&quot;DSC_0744&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0751_0E3A74DD.jpg&quot; alt=&quot;DSC_0751&quot; title=&quot;DSC_0751&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Amazing Microsoft &lt;a href=&quot;http://en.wikipedia.org/wiki/Bing_(search_engine)&quot;&gt;Bing&lt;/a&gt; team:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0784_37CE4010.jpg&quot; alt=&quot;DSC_0784&quot; title=&quot;DSC_0784&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0790_6476F9E9.jpg&quot; alt=&quot;DSC_0790&quot; title=&quot;DSC_0790&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0785_7C2E314F.jpg&quot; alt=&quot;DSC_0785&quot; title=&quot;DSC_0785&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Chinese Kungfu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0808_08BBDE6C.jpg&quot; alt=&quot;DSC_0808&quot; title=&quot;DSC_0808&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0815_0777458D.jpg&quot; alt=&quot;DSC_0815&quot; title=&quot;DSC_0815&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Microsoft rocks:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0840_198F70B9.jpg&quot; alt=&quot;DSC_0840&quot; title=&quot;DSC_0840&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0842_184AD7DA.jpg&quot; alt=&quot;DSC_0842&quot; title=&quot;DSC_0842&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Rap with my soul: I grow up with Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0854_04BD7839.jpg&quot; alt=&quot;DSC_0854&quot; title=&quot;DSC_0854&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0868_04EE13CF.jpg&quot; alt=&quot;DSC_0868&quot; title=&quot;DSC_0868&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0887_5CDB64AF.jpg&quot; alt=&quot;DSC_0887&quot; title=&quot;DSC_0887&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0795_34C8B590.jpg&quot; alt=&quot;DSC_0795&quot; title=&quot;DSC_0795&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0899_73BA362B.jpg&quot; alt=&quot;DSC_0899&quot; title=&quot;DSC_0899&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0901_04BE640F.jpg&quot; alt=&quot;DSC_0901&quot; title=&quot;DSC_0901&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0921_38865A60.jpg&quot; alt=&quot;DSC_0921&quot; title=&quot;DSC_0921&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0924_3D88980F.jpg&quot; alt=&quot;DSC_0924&quot; title=&quot;DSC_0924&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0926_553FCF75.jpg&quot; alt=&quot;DSC_0926&quot; title=&quot;DSC_0926&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Microsoft Chinese Spring Festival Celebration (1)</title><link>https://dixin.github.io/posts/microsoft-chinese-spring-festival-celebration-1/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsoft-chinese-spring-festival-celebration-1/</guid><description>Last night there was a big party in Redmond: . It is organized by  (an employee n</description><pubDate>Mon, 24 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last night there was a big party in Redmond: &lt;a href=&quot;http://www.microsoftchime.org/?q=node/4&quot;&gt;Microsoft Spring Festival Celebration&lt;/a&gt;. It is organized by &lt;a href=&quot;http://www.microsoftchime.org/&quot;&gt;Chime&lt;/a&gt; (an employee network group in Microsoft), and it is also the biggest &lt;a href=&quot;http://en.wikipedia.org/wiki/Chinese_New_Year&quot;&gt;Chinese new year&lt;/a&gt; celebration in Seattle area. Thousands of people attended the party, including &lt;a href=&quot;http://en.wikipedia.org/wiki/Steve_Ballmer&quot;&gt;Steve Ballmer&lt;/a&gt;. I also brought my &lt;a href=&quot;http://en.wikipedia.org/wiki/Nikon_D700&quot;&gt;Nikon D700&lt;/a&gt; there.&lt;/p&gt;
&lt;p&gt;Before the grand celebration show:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0568_501ADF79.jpg&quot; alt=&quot;DSC_0568&quot; title=&quot;DSC_0568&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Greetings from Microsoft:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0546_6EF15357.jpg&quot; alt=&quot;DSC_0546&quot; title=&quot;DSC_0546&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The opening, Chinese movie medley:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0576_18F15180.jpg&quot; alt=&quot;DSC_0576&quot; title=&quot;DSC_0576&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0603_50C395A3.jpg&quot; alt=&quot;DSC_0603&quot; title=&quot;DSC_0603&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0601_6B8FBBAF.jpg&quot; alt=&quot;DSC_0601&quot; title=&quot;DSC_0601&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Microsoft MCs:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0606_34662DB6.jpg&quot; alt=&quot;DSC_0606&quot; title=&quot;DSC_0606&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Talk Show: Microsoft, Welcome to Beijing!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0607_0C537E97.jpg&quot; alt=&quot;DSC_0607&quot; title=&quot;DSC_0607&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bing!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0608_77EDB90B.jpg&quot; alt=&quot;DSC_0608&quot; title=&quot;DSC_0608&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dancing, happy new year:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0611_7DC85CA4.jpg&quot; alt=&quot;DSC_0611&quot; title=&quot;DSC_0611&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0612_4E96710D.jpg&quot; alt=&quot;DSC_0612&quot; title=&quot;DSC_0612&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0616_0668B531.jpg&quot; alt=&quot;DSC_0616&quot; title=&quot;DSC_0616&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0614_0C4358CA.jpg&quot; alt=&quot;DSC_0614&quot; title=&quot;DSC_0614&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0623_79222C1D.jpg&quot; alt=&quot;DSC_0623&quot; title=&quot;DSC_0623&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Greetings to everyone:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0624_6A0B4D43.jpg&quot; alt=&quot;DSC_0624&quot; title=&quot;DSC_0624&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Harry_Shum&quot;&gt;Harry Shum&lt;/a&gt;, Microsoft &lt;a href=&quot;http://www.microsoft.com/presspass/exec/Shum/&quot;&gt;Vice President&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0627_08E1C122.jpg&quot; alt=&quot;DSC_0627&quot; title=&quot;DSC_0627&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next is &lt;a href=&quot;http://en.wikipedia.org/wiki/Steve_Ballmer&quot;&gt;Steve Baller&lt;/a&gt;, Microsoft &lt;a href=&quot;http://www.microsoft.com/presspass/exec/steve/default.aspx&quot;&gt;CEO&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0631_0EBC64BB.jpg&quot; alt=&quot;DSC_0631&quot; title=&quot;DSC_0631&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0632_7FA585E0.jpg&quot; alt=&quot;DSC_0632&quot; title=&quot;DSC_0632&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I have some lucky money for you:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0637_7A569F2F.jpg&quot; alt=&quot;DSC_0637&quot; title=&quot;DSC_0637&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You want this red envelope?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0642_043B909B.jpg&quot; alt=&quot;DSC_0642&quot; title=&quot;DSC_0642&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Come and get it!!!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0643_50FF5731.jpg&quot; alt=&quot;DSC_0643&quot; title=&quot;DSC_0643&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Come on!!!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0644_5AE4489C.jpg&quot; alt=&quot;DSC_0644&quot; title=&quot;DSC_0644&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0654_60BEEC35.jpg&quot; alt=&quot;DSC_0654&quot; title=&quot;DSC_0654&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0656_2D82B2CC.jpg&quot; alt=&quot;DSC_0656&quot; title=&quot;DSC_0656&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0659_6C080072.jpg&quot; alt=&quot;DSC_0659&quot; title=&quot;DSC_0659&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0663_222978C2.jpg&quot; alt=&quot;DSC_0663&quot; title=&quot;DSC_0663&quot; /&gt;&lt;/p&gt;
&lt;p&gt;He was moving so fast, and the photo is blurred:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0684_745BAFFC.jpg&quot; alt=&quot;DSC_0684&quot; title=&quot;DSC_0684&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0685_334D3098.jpg&quot; alt=&quot;DSC_0685&quot; title=&quot;DSC_0685&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I have red envelopes for every one:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0690_0B3A8179.jpg&quot; alt=&quot;DSC_0690&quot; title=&quot;DSC_0690&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Happy Chinese new year!!!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0670_151F72E4.jpg&quot; alt=&quot;DSC_0670&quot; title=&quot;DSC_0670&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That’s me, hiding in the front row :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0682_4E488257.jpg&quot; alt=&quot;DSC_0682&quot; title=&quot;DSC_0682&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click &lt;a href=&quot;/posts/microsoft-chinese-spring-festival-celebration-2&quot;&gt;here to view Part 2&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>The Humor of Silverlight</title><link>https://dixin.github.io/posts/the-humor-of-silverlight/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-humor-of-silverlight/</guid><description>!</description><pubDate>Sat, 11 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_0E82AE99.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This must be kidding.&lt;/p&gt;
</content:encoded></item><item><title>Arrival to Redmond</title><link>https://dixin.github.io/posts/arrival-to-redmond/</link><guid isPermaLink="true">https://dixin.github.io/posts/arrival-to-redmond/</guid><description>In this year, I was rewarded as an ; at the same time, 3 different groups of Microsoft offered me 3 SDE II positions,</description><pubDate>Thu, 28 Oct 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this year, I was rewarded as an &lt;a href=&quot;/posts/microsoft-most-valuable-professional-kit-unboxing&quot;&gt;MVP on C# of Year 2010&lt;/a&gt;; at the same time, 3 different groups of Microsoft offered me 3 SDE II positions, and I made my choice. Now, with the help of Microsoft, I just relocated from China to Redmond.&lt;/p&gt;
&lt;p&gt;2 years ago, when I left Redmond, I decided that &lt;a href=&quot;http://en.wikipedia.org/wiki/I&apos;ll_be_back&quot;&gt;I’ll be back&lt;/a&gt;. Now everything just looks the same as &lt;a href=&quot;/posts/default&quot;&gt;2 years ago&lt;/a&gt;. What a familiar place!&lt;/p&gt;
&lt;p&gt;As a great company, Microsoft also offers me very nice temp housing. It is &lt;a href=&quot;http://maps.google.com/maps/place?hl=en&amp;amp;expIds=17259,23756,24692,24813,24878,24879,26637,27182&amp;amp;sugexp=ldymls&amp;amp;xhr=t&amp;amp;cp=6&amp;amp;newwindow=1&amp;amp;rls=com.microsoft:en-us&amp;amp;wrapid=tljp128822929241300&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;q=timberlawn+apartments&amp;amp;fb=1&amp;amp;gl=us&amp;amp;hq=timberlawn+apartments&amp;amp;hnear=Kirkland,+WA&amp;amp;cid=10746548189430292303&quot;&gt;an apartment&lt;/a&gt; 2-minutes-walk away from my office, and it is free for 60 days!&lt;/p&gt;
&lt;p&gt;The apartment is on the 2nd floor:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0186_336D1E31.jpg&quot; alt=&quot;DSC_0186&quot; title=&quot;DSC_0186&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The living room:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0287_6A66FC6A.jpg&quot; alt=&quot;DSC_0287&quot; title=&quot;DSC_0287&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0292_2F9F5394.jpg&quot; alt=&quot;DSC_0292&quot; title=&quot;DSC_0292&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The dining room:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0283_15831D14.jpg&quot; alt=&quot;DSC_0283&quot; title=&quot;DSC_0283&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The balcony:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0288_5B6FA783.jpg&quot; alt=&quot;DSC_0288&quot; title=&quot;DSC_0288&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The master bedroom:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0293_39379BFD.jpg&quot; alt=&quot;DSC_0293&quot; title=&quot;DSC_0293&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0203_5735A9F1.jpg&quot; alt=&quot;DSC_0203&quot; title=&quot;DSC_0203&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The second bedroom:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0291_18147996.jpg&quot; alt=&quot;DSC_0291&quot; title=&quot;DSC_0291&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0290_0B3A2378.jpg&quot; alt=&quot;DSC_0290&quot; title=&quot;DSC_0290&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The laundry room:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0197_10A8941C.jpg&quot; alt=&quot;DSC_0197&quot; title=&quot;DSC_0197&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The left one is the dryer, and the right one is the washer.&lt;/p&gt;
&lt;p&gt;The utility room:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0196_3A3C5F4F.jpg&quot; alt=&quot;DSC_0196&quot; title=&quot;DSC_0196&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The bathroom is very nice and clean:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0198_11BD7D3B.jpg&quot; alt=&quot;DSC_0198&quot; title=&quot;DSC_0198&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0200_4BCC4A1A.jpg&quot; alt=&quot;DSC_0200&quot; title=&quot;DSC_0200&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The kitchen:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0212_039E8E3E.jpg&quot; alt=&quot;DSC_0212&quot; title=&quot;DSC_0212&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0213_4D4D662E.jpg&quot; alt=&quot;DSC_0213&quot; title=&quot;DSC_0213&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0220_1938C6DB.jpg&quot; alt=&quot;DSC_0220&quot; title=&quot;DSC_0220&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_0297_0BF23DC8.jpg&quot; alt=&quot;DSC_0297&quot; title=&quot;DSC_0297&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Microsoft Most Valuable Professional Kit Unboxing</title><link>https://dixin.github.io/posts/microsoft-most-valuable-professional-kit-unboxing/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsoft-most-valuable-professional-kit-unboxing/</guid><description>I am very happy to receive the  Kit:</description><pubDate>Thu, 28 Oct 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am very happy to receive the &lt;a href=&quot;http://mvp.support.microsoft.com/&quot;&gt;Microsoft Most Valuable Professional&lt;/a&gt; Kit:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/Dixin-MVP.jpg&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20101011115_11AFD12A.jpg&quot; alt=&quot;20101011115&quot; title=&quot;20101011115&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20101011117_448BC9E7.jpg&quot; alt=&quot;20101011117&quot; title=&quot;20101011117&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The box is mailed from Redmond:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8621_289A94EF.jpg&quot; alt=&quot;DSC_8621&quot; title=&quot;DSC_8621&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8623_118C13B3.jpg&quot; alt=&quot;DSC_8623&quot; title=&quot;DSC_8623&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8624_08BC0B67.jpg&quot; alt=&quot;DSC_8624&quot; title=&quot;DSC_8624&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8630_2F41AC29.jpg&quot; alt=&quot;DSC_8630&quot; title=&quot;DSC_8630&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8632_5B5A7596.jpg&quot; alt=&quot;DSC_8632&quot; title=&quot;DSC_8632&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8633_4B6B30D2.jpg&quot; alt=&quot;DSC_8633&quot; title=&quot;DSC_8633&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/DSC_8676_6099367A.jpg&quot; alt=&quot;DSC_8676&quot; title=&quot;DSC_8676&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Ellipses (…) In UI Command Text</title><link>https://dixin.github.io/posts/ellipses-in-ui-command-text/</link><guid isPermaLink="true">https://dixin.github.io/posts/ellipses-in-ui-command-text/</guid><description>Some times, command text is followed by ellipsis (…) or not:</description><pubDate>Sat, 26 Jun 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some times, command text is followed by ellipsis (…) or not:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_6AC3F6C5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For years, many developers told me that ellipses mean a new window or dialog will pop up. For example, here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clicking New / Save / Exit will not pop up new window or dialog;&lt;/li&gt;
&lt;li&gt;Clicking Open… / Save As… / Page Setup… / Print… will pop up new window or dialog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But this is not correct. Take a look at About Notepad.&lt;/p&gt;
&lt;p&gt;Recently, someone argues about this old topic again. I think it is time to copy something from latest &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=e49820cb-954d-45ae-9cb3-1b9e8ea7fe8c&quot;&gt;Windows User Experience Interaction Guidelines&lt;/a&gt;, and save to my blog. So next time when some other people are confused, I can just send a link to them.&lt;/p&gt;
&lt;p&gt;Page 10, Top Guidelines Violations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ellipses mean incompleteness.&lt;/strong&gt; Use ellipses in UI text as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Commands.&lt;/strong&gt; Indicate that a command needs additional information. Don’t use an ellipsis whenever an action displays another window—only when additional information is required. Commands whose implicit verb is to show another window don’t take an ellipsis, such as Advanced, Help, Options, Properties, or Settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Page 236, Menus:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2&gt;Using ellipses&lt;/h2&gt;
&lt;p&gt;While menu commands are used for immediate actions, more information might be needed to perform the action. &lt;strong&gt;Indicate a command that needs additional information (including a confirmation) by adding an ellipsis at the end of the label.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_7CC01485.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this example, the Print... command displays a Print dialog box to gather more information.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proper use of ellipses is important to indicate that users can make further choices before performing the action, or even cancel the action entirely.&lt;/strong&gt; The visual cue offered by an ellipsis allows users to explore your software without fear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This doesn’t mean you should use an ellipsis whenever an action displays another window&lt;/strong&gt;—only when additional information is required to perform the action. For example, the commands About, Advanced, Help, Options, Properties, and Settings must display another window when clicked, but don’t require additional information from the user. Therefore they don’t need ellipses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In case of ambiguity (for example, the command label lacks a verb), decide based on the most likely user action.&lt;/strong&gt; If simply viewing the window is a common action, don’t use an ellipsis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Correct:&lt;/strong&gt; More colors... Version information&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In the first example, users are most likely going to choose a color, so using an ellipses is correct. In the second example, users are most likely going to view the version information, making ellipses unnecessary.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When determining if a menu command needs an ellipsis, don’t use the need to elevate privileges as a factor. Elevation isn’t information needed to perform a command (rather, it’s for permission) and the need to elevate is indicated with the security shield. Labels&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are similar description in the other sections, like Buttons, Toolbars, etc.&lt;/p&gt;
</content:encoded></item><item><title>A Snapshot Of ASP.NET Homepage</title><link>https://dixin.github.io/posts/a-snapshot-of-www-asp-net-homepage/</link><guid isPermaLink="true">https://dixin.github.io/posts/a-snapshot-of-www-asp-net-homepage/</guid><description>First time to appear on  homepage as headline!</description><pubDate>Thu, 10 Jun 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;First time to appear on &lt;a href=&quot;http://www.asp.net/&quot;&gt;www.asp.net&lt;/a&gt; homepage as headline!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/dixin-aspnet.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/dixin-aspnet.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>A ToDynamic() Extension Method For Fluent Reflection</title><link>https://dixin.github.io/posts/a-todynamic-extension-method-for-fluent-reflection/</link><guid isPermaLink="true">https://dixin.github.io/posts/a-todynamic-extension-method-for-fluent-reflection/</guid><description>Recently I needed to demonstrate some code with reflection, but I felt it inconvenient and tedious. To simplify the reflection coding, I created a ToDynamic() extension method. The source code can be</description><pubDate>Mon, 07 Jun 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I needed to demonstrate some code with reflection, but I felt it inconvenient and tedious. To simplify the reflection coding, I created a ToDynamic() extension method. The source code can be downloaded from &lt;a href=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Media/DynamicWrapper.zip&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;One example for complex reflection is in LINQ to SQL. The DataContext class has a property Privider, and this Provider has an Execute() method, which executes the query expression and returns the result. Assume this Execute() needs to be invoked to query SQL Server database, then the following code will be expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    // Constructs the query.
    IQueryable&amp;lt;Product&amp;gt; query = database.Products.Where(product =&amp;gt; product.ProductID &amp;gt; 0)
                                                 .OrderBy(product =&amp;gt; product.ProductName)
                                                 .Take(2);

    // Executes the query. Here reflection is required,
    // because Provider, Execute(), and ReturnValue are not public members. The following code cannot compile.
    IEnumerable&amp;lt;Product&amp;gt; results = database.Provider.Execute(query.Expression).ReturnValue;

    // Processes the results. 
    foreach (Product product in results)
    {
        Console.WriteLine(&quot;{0}, {1}&quot;, product.ProductID, product.ProductName);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, this code cannot compile. And, no one wants to write code like this. Again, this is just an example of complex reflection.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    // Constructs the query.
    IQueryable&amp;lt;Product&amp;gt; query = database.Products.Where(product =&amp;gt; product.ProductID &amp;gt; 0)
                                                 .OrderBy(product =&amp;gt; product.ProductName)
                                                 .Take(2);

    // database.Provider
    PropertyInfo providerProperty = database.GetType().GetProperty(
        &quot;Provider&quot;, BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance);
    object provider = providerProperty.GetValue(database, null);

    // database.Provider.Execute(query.Expression)
    // Here GetMethod() cannot be directly used,
    // because Execute() is a explicitly implemented interface method.
    Assembly assembly = Assembly.Load(&quot;System.Data.Linq&quot;);
    Type providerType = assembly.GetTypes().SingleOrDefault(
        type =&amp;gt; type.FullName == &quot;System.Data.Linq.Provider.IProvider&quot;);
    InterfaceMapping mapping = provider.GetType().GetInterfaceMap(providerType);
    MethodInfo executeMethod = mapping.InterfaceMethods.Single(method =&amp;gt; method.Name == &quot;Execute&quot;);
    IExecuteResult executeResult = 
        executeMethod.Invoke(provider, new object[] { query.Expression }) as IExecuteResult;

    // database.Provider.Execute(query.Expression).ReturnValue
    IEnumerable&amp;lt;Product&amp;gt; results = executeResult.ReturnValue as IEnumerable&amp;lt;Product&amp;gt;;

    // Processes the results.
    foreach (Product product in results)
    {
        Console.WriteLine(&quot;{0}, {1}&quot;, product.ProductID, product.ProductName);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This may be not straight forward enough. So here is a solution implementing fluent reflection with a ToDynamic() extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; results = database.ToDynamic() // Starts fluent reflection. 
                                       .Provider.Execute(query.Expression).ReturnValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C# 4.0 dynamic&lt;/h2&gt;
&lt;p&gt;In this kind of scenarios, it is easy to have dynamic in mind, which enables developer to write whatever code after a dot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    // Constructs the query.
    IQueryable&amp;lt;Product&amp;gt; query = database.Products.Where(product =&amp;gt; product.ProductID &amp;gt; 0)
                                                 .OrderBy(product =&amp;gt; product.ProductName)
                                                 .Take(2);

    // database.Provider
    dynamic dynamicDatabase = database;
    dynamic results = dynamicDatabase.Provider.Execute(query).ReturnValue;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This throws a RuntimeBinderException at runtime:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&apos;System.Data.Linq.DataContext.Provider&apos; is inaccessible due to its protection level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here dynamic is able find the specified member. So the next thing is just writing some custom code to access the found member.&lt;/p&gt;
&lt;h2&gt;.NET 4.0 DynamicObject, and DynamicWrapper&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;Where to put the custom code for dynamic? The answer is DynamicObject’s derived class. I first heard of DynamicObject from &lt;a href=&quot;http://channel9.msdn.com/pdc2008/TL16/&quot;&gt;Anders Hejlsberg&apos;s video in PDC2008&lt;/a&gt;. It is very powerful, providing useful virtual methods to be overridden, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TryGetMember()&lt;/li&gt;
&lt;li&gt;TrySetMember()&lt;/li&gt;
&lt;li&gt;TryInvokeMember()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. (In 2008 they are called GetMember, SetMember, etc., with different signature.)&lt;/p&gt;
&lt;p&gt;For example, if dynamicDatabase is a DynamicObject, then the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamicDatabase.Provider
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will invoke dynamicDatabase.TryGetMember() to do the actual work, where custom code can be put into.&lt;/p&gt;
&lt;p&gt;Now create a type to inherit DynamicObject:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DynamicWrapper&amp;lt;T&amp;gt; : DynamicObject
{
    private readonly bool _isValueType;

    private readonly Type _type;

    private T _value; // Not readonly, for value type scenarios.

    public DynamicWrapper(ref T value) // Uses ref in case of value type.
    {
        if (value == null)
        {
            throw new ArgumentNullException(&quot;value&quot;);
        }

        this._value = value;
        this._type = value.GetType();
        this._isValueType = this._type.IsValueType;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        // Searches in current type&apos;s public and non-public properties.
        PropertyInfo property = this._type.GetTypeProperty(binder.Name);
        if (property != null)
        {
            result = property.GetValue(this._value, null).ToDynamic();
            return true;
        }

        // Searches in explicitly implemented properties for interface.
        MethodInfo method = this._type.GetInterfaceMethod(string.Concat(&quot;get_&quot;, binder.Name), null);
        if (method != null)
        {
            result = method.Invoke(this._value, null).ToDynamic();
            return true;
        }

        // Searches in current type&apos;s public and non-public fields.
        FieldInfo field = this._type.GetTypeField(binder.Name);
        if (field != null)
        {
            result = field.GetValue(this._value).ToDynamic();
            return true;
        }

        // Searches in base type&apos;s public and non-public properties.
        property = this._type.GetBaseProperty(binder.Name);
        if (property != null)
        {
            result = property.GetValue(this._value, null).ToDynamic();
            return true;
        }

        // Searches in base type&apos;s public and non-public fields.
        field = this._type.GetBaseField(binder.Name);
        if (field != null)
        {
            result = field.GetValue(this._value).ToDynamic();
            return true;
        }

        // The specified member is not found.
        result = null;
        return false;
    }

    // Other overridden methods are not listed.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above code, GetTypeProperty(), GetInterfaceMethod(), GetTypeField(), GetBaseProperty(), and GetBaseField() are extension methods for Type class. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class TypeExtensions
{
    internal static FieldInfo GetBaseField(this Type type, string name)
    {
        Type @base = type.BaseType;
        if (@base == null)
        {
            return null;
        }

        return @base.GetTypeField(name) ?? @base.GetBaseField(name);
    }

    internal static PropertyInfo GetBaseProperty(this Type type, string name)
    {
        Type @base = type.BaseType;
        if (@base == null)
        {
            return null;
        }

        return @base.GetTypeProperty(name) ?? @base.GetBaseProperty(name);
    }

    internal static MethodInfo GetInterfaceMethod(this Type type, string name, params object[] args)
    {
        return
            type.GetInterfaces().Select(type.GetInterfaceMap).SelectMany(mapping =&amp;gt; mapping.TargetMethods)
                .FirstOrDefault(
                    method =&amp;gt;
                    method.Name.Split(&apos;.&apos;).Last().Equals(name, StringComparison.Ordinal) &amp;amp;&amp;amp;
                    method.GetParameters().Count() == args.Length &amp;amp;&amp;amp;
                    method.GetParameters().Select(
                        (parameter, index) =&amp;gt;
                        parameter.ParameterType.IsAssignableFrom(args[index].GetType())).Aggregate(
                            true, (a, b) =&amp;gt; a &amp;amp;&amp;amp; b));
    }

    internal static FieldInfo GetTypeField(this Type type, string name)
    {
        return
            type.GetFields(
                BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
                BindingFlags.NonPublic).FirstOrDefault(
                    field =&amp;gt; field.Name.Equals(name, StringComparison.Ordinal));
    }

    internal static PropertyInfo GetTypeProperty(this Type type, string name)
    {
        return
            type.GetProperties(
                BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static |
                BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(
                    property =&amp;gt; property.Name.Equals(name, StringComparison.Ordinal));
    }

    // Other extension methods are not listed.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now, when invoked, TryGetMember() searches the specified member and invoke it. The code can be written like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic dynamicDatabase = new DynamicWrapper&amp;lt;NorthwindDataContext&amp;gt;(ref database);
dynamic dynamicReturnValue = dynamicDatabase.Provider.Execute(query.Expression).ReturnValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This greatly simplified reflection.&lt;/p&gt;
&lt;h2&gt;ToDynamic() and fluent reflection&lt;/h2&gt;
&lt;p&gt;To make it even more straight forward, A ToDynamic() method is provided:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class DynamicWrapperExtensions
{
    public static dynamic ToDynamic&amp;lt;T&amp;gt;(this T value)
    {
        return new DynamicWrapper&amp;lt;T&amp;gt;(ref value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and a ToStatic() method is provided to unwrap the value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DynamicWrapper&amp;lt;T&amp;gt; : DynamicObject
{
    public T ToStatic()
    {
        return this._value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above TryGetMember() method, please notice it does not output the member’s value, but output a wrapped member value (that is, memberValue.ToDynamic()). This is very important to make the reflection fluent.&lt;/p&gt;
&lt;p&gt;Now the code becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; results = database.ToDynamic() // Here starts fluent reflection. 
                                       .Provider.Execute(query.Expression).ReturnValue
                                       .ToStatic(); // Unwraps to get the static value.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the help of TryConvert():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DynamicWrapper&amp;lt;T&amp;gt; : DynamicObject
{
    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        result = this._value;
        return true;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ToStatic() can be omitted:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; results = database.ToDynamic() 
                                       .Provider.Execute(query.Expression).ReturnValue;
                                       // Automatically converts to expected static value.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take a look at the reflection code at the beginning of this post again. Now it is much much simplified!&lt;/p&gt;
&lt;h2&gt;Special scenarios&lt;/h2&gt;
&lt;p&gt;In 90% of the scenarios ToDynamic() is enough. But there are some special scenarios.&lt;/p&gt;
&lt;h3&gt;Access static members&lt;/h3&gt;
&lt;p&gt;Using extension method ToDynamic() for accessing static members does not make sense. Instead, DynamicWrapper&amp;lt;T&amp;gt; has a parameterless constructor to handle these scenarios:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DynamicWrapper&amp;lt;T&amp;gt; : DynamicObject
{
    public DynamicWrapper() // For static.
    {
        this._type = typeof(T);
        this._isValueType = this._type.IsValueType;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reflection code should be like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic wrapper = new DynamicWrapper&amp;lt;StaticClass&amp;gt;();
int value = wrapper._value;
int result = wrapper.PrivateMethod();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So accessing static member is also simple, and fluent of course.&lt;/p&gt;
&lt;h3&gt;Change instances of value types&lt;/h3&gt;
&lt;p&gt;Value type is much more complex. The main problem is, value type is copied when passing to a method as a parameter.&lt;/p&gt;
&lt;p&gt;This is why ref keyword is used for the constructor. That is, if a value type instance is passed to DynamicWrapper&amp;lt;T&amp;gt;, the instance itself will be stored in this._value of DynamicWrapper&amp;lt;T&amp;gt;. Without the ref keyword, when this._value is changed, the value type instance itself does not change.&lt;/p&gt;
&lt;p&gt;Consider FieldInfo.SetValue(). In the value type scenarios, invoking FieldInfo.SetValue(this._value, value) does not change this._value, because it changes the copy of this._value.&lt;/p&gt;
&lt;p&gt;I searched the Web and found a solution for setting the value of field:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class FieldInfoExtensions
{
    internal static void SetValue&amp;lt;T&amp;gt;(this FieldInfo field, ref T obj, object value)
    {
        if (typeof(T).IsValueType)
        {
            field.SetValueDirect(__makeref(obj), value); // For value type. 
        }
        else
        {
            field.SetValue(obj, value); // For reference type.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here __makeref is a undocumented keyword of C#.&lt;/p&gt;
&lt;p&gt;But method invocation has problem. This is the source code of TryInvokeMember():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
    if (binder == null)
    {
        throw new ArgumentNullException(&quot;binder&quot;);
    }

    MethodInfo method = this._type.GetTypeMethod(binder.Name, args) ??
                        this._type.GetInterfaceMethod(binder.Name, args) ??
                        this._type.GetBaseMethod(binder.Name, args);
    if (method != null)
    {
        // Oops!
        // If the returnValue is a struct, it is copied to heap.
        object resultValue = method.Invoke(this._value, args);
        // And result is a wrapper of that copied struct.
        result = new DynamicWrapper&amp;lt;object&amp;gt;(ref resultValue);
        return true;
    }

    result = null;
    return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the returned value is of value type, it will definitely copied, because MethodInfo.Invoke() does return object. If changing the value of the result, the copied struct is changed instead of the original struct. And so is the property and index accessing. They are both actually method invocation. For less confusion, setting property and index are not allowed on struct.&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;The DynamicWrapper&amp;lt;T&amp;gt; provides a simplified solution for reflection programming. It works for normal classes (reference types), accessing both instance and static members.&lt;/p&gt;
&lt;p&gt;In most of the scenarios, just remember to invoke ToDynamic() method, and access whatever you want:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;StaticType result = someValue.ToDynamic()._field.Method().Property[index];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In some special scenarios which requires changing the value of a struct (value type), this DynamicWrapper&amp;lt;T&amp;gt; does not work perfectly. Only changing struct’s field value is supported.&lt;/p&gt;
&lt;p&gt;The source code can be downloaded from &lt;a href=&quot;https://aspblogs.blob.core.windows.net/media/dixin/Media/DynamicWrapper.zip&quot;&gt;here&lt;/a&gt;, including a few unit test code.&lt;/p&gt;
</content:encoded></item><item><title>Back From Microsoft Web Camps Beijing</title><link>https://dixin.github.io/posts/back-from-microsoft-web-camps-beijing/</link><guid isPermaLink="true">https://dixin.github.io/posts/back-from-microsoft-web-camps-beijing/</guid><description>I am just back from , where Web developers in Beijing had a good time for 2 days with 2 fantastic speakers,  a</description><pubDate>Tue, 25 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am just back from &lt;a href=&quot;http://www.webcamps.ms/&quot;&gt;Microsoft Web Camps&lt;/a&gt;, where Web developers in Beijing had a good time for 2 days with 2 fantastic speakers, &lt;a href=&quot;http://www.hanselman.com/&quot;&gt;Scott Hanselman&lt;/a&gt; and &lt;a href=&quot;http://www.jamessenior.com/&quot;&gt;James Senior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webCamps_patch_5743678F.png&quot; alt=&quot;webCamps_patch&quot; title=&quot;webCamps_patch&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On day 1, Scott and James talked about Web Platform Installer, ASP.NET core runtime, ASP.NET MVC, Entity Framework, Visual Studio 2010, … They were humorous and smart, and everyone was excited!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20100521009_188E6A29.jpg&quot; alt=&quot;20100521009&quot; title=&quot;20100521009&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On day 2, developers were organized into teams to build Web applications. At the end of day 2, each team had a chance of presentation. Before ending, I also demonstrated my so-called “&lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;WebOS&lt;/a&gt;”, a tiny but funny Web website &lt;a href=&quot;/posts/introducing-coolwebos-com&quot;&gt;developed with ASP.NET MVC and jQuery&lt;/a&gt;, which looks like an operating system, to show the power of ASP.NET MVC and jQuery. Scott, James and me were joking there, and people cannot help laughing and applauding…&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_7BC4CF46.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_219A3403.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can play with it here: &lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;http://www.coolwebos.com/&lt;/a&gt;, if interested.&lt;/p&gt;
&lt;p&gt;I discussed with Scott and James about Web and ASP.NET, like some &lt;a href=&quot;/posts/anti-forgery-request-recipes-for-asp-net-mvc-and-ajax&quot;&gt;junior ideas&lt;/a&gt; on ASP.NET MVC anti-forgery request, etc. I also helped on some English / Chinese translation. At the end Scott gave me a fabulous gift, which I will post to blog later.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/dixin-and-scott-hanselman.jpg&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/dixin-and-james-senior.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hope Microsoft can have more and more events like this!&lt;/p&gt;
</content:encoded></item><item><title>Anti-Forgery Request Recipes For ASP.NET MVC And AJAX</title><link>https://dixin.github.io/posts/anti-forgery-request-recipes-for-asp-net-mvc-and-ajax/</link><guid isPermaLink="true">https://dixin.github.io/posts/anti-forgery-request-recipes-for-asp-net-mvc-and-ajax/</guid><description>This post discusses solutions for anti-forgery request scenarios in ASP.NET MVC and AJAX:</description><pubDate>Sat, 22 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post discusses solutions for anti-forgery request scenarios in ASP.NET MVC and AJAX:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to enable validation on controller, instead of on each action;&lt;/li&gt;
&lt;li&gt;How to specify non-constant token salt in runtime;&lt;/li&gt;
&lt;li&gt;How to work with the server side validation in AJAX scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Background (Normal scenario of form submitting)&lt;/h2&gt;
&lt;p&gt;To secure websites from &lt;a href=&quot;http://en.wikipedia.org/wiki/Cross-site_request_forgery&quot;&gt;cross-site request forgery&lt;/a&gt; (CSRF, or XSRF) attack, ASP.NET MVC provides an excellent mechanism:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The server prints tokens to cookie and inside the form;&lt;/li&gt;
&lt;li&gt;When the form is submitted to server, token in cookie and token inside the form are sent in the HTTP request;&lt;/li&gt;
&lt;li&gt;Server validates the tokens.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To print tokens to browser, just invoke HtmlHelper.AntiForgeryToken():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;% using (Html.BeginForm())
   { %&amp;gt;
    &amp;lt;%: this.Html.AntiForgeryToken(Constants.AntiForgeryTokenSalt)%&amp;gt;

    &amp;lt;%-- Other fields. --%&amp;gt;

    &amp;lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This invocation generates a token and writes it inside the form:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;form action=&quot;...&quot; method=&quot;post&quot;&amp;gt;
    &amp;lt;input name=&quot;__RequestVerificationToken&quot; type=&quot;hidden&quot; value=&quot;J56khgCvbE3bVcsCSZkNVuH9Cclm9SSIT/ywruFsXEgmV8CL2eW5C/gGsQUf/YuP&quot; /&amp;gt;
 
    &amp;lt;!-- Other fields. --&amp;gt;
 
    &amp;lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and also writes it into the cookie:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;__RequestVerificationToken_Lw__= J56khgCvbE3bVcsCSZkNVuH9Cclm9SSIT/ywruFsXEgmV8CL2eW5C/gGsQUf/YuP&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When the above form is submitted, they are both sent to server.&lt;/p&gt;
&lt;p&gt;In the server side, [ValidateAntiForgeryToken] attribute is used to specify the controllers or actions to validate them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[HttpPost]
[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public ActionResult Action(/* ... */)
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very productive for form scenarios. But recently, when resolving security vulnerabilities for Web products, problems are encountered.&lt;/p&gt;
&lt;h2&gt;Turn on validation on controller (not on each action)&lt;/h2&gt;
&lt;p&gt;The server side problem is, one single [ValidateAntiForgeryToken] attribute is expected to declare on controller, but actually a lot of attributes have be to declared on controller&apos;s each POST actions. Because POST actions are usually much more then controllers, the work would be a little crazy.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;Usually a controller contains both actions for HTTP GET requests and actions for POST, and, usually validations are expected for only HTTP POST requests. So, if the [ValidateAntiForgeryToken] is declared on the controller, the HTTP GET requests become invalid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public class ProductController : Controller // One [ValidateAntiForgeryToken] attribute. 
{
    [HttpGet]
    public ActionResult Index() // Index() cannot work.
    {
        // ...
    }

    [HttpPost]
    public ActionResult PostAction1(/* ... */)
    { 
        // ...
    }

    [HttpPost]
    public ActionResult PostAction2(/* ... */)
    {
        // ...
    }

    // Other actions.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If browser sends an HTTP GET request by clicking a link: http://Site/Product/Index, validation definitely fails, because no token is provided (by http://Site/Product/Index?__RequestVerificationToken=???, for example).&lt;/p&gt;
&lt;p&gt;As a result, many [ValidateAntiForgeryToken] attributes have be distributed to each POST action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductController : Controller // Many [ValidateAntiForgeryToken] attributes.
{
    [HttpGet]
    public ActionResult Index() // Works.
    {
        // ...
    }

    [HttpPost]
    [ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
    public ActionResult PostAction1(/* ... */)
    { 
        // ...
    }

    [HttpPost]
    [ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
    public ActionResult PostAction2(/* ... */)
    {
        // ...
    }

    // Other actions.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would be a little bit crazy, because one Web product can have a lot of POST actions.&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;To avoid a large number of [ValidateAntiForgeryToken] attributes (one for each POST action), the following ValidateAntiForgeryTokenWrapperAttribute wrapper class can be helpful, where HTTP verbs can be specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
    AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenWrapperAttribute : FilterAttribute, IAuthorizationFilter
{
    private readonly ValidateAntiForgeryTokenAttribute _validator;

    private readonly AcceptVerbsAttribute _verbs;

    public ValidateAntiForgeryTokenWrapperAttribute(HttpVerbs verbs)
        : this(verbs, null)
    {
    }

    public ValidateAntiForgeryTokenWrapperAttribute(HttpVerbs verbs, string salt)
    {
        this._verbs = new AcceptVerbsAttribute(verbs);
        this._validator = new ValidateAntiForgeryTokenAttribute()
            {
                Salt = salt
            };
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        string httpMethodOverride = filterContext.HttpContext.Request.GetHttpMethodOverride();
        if (this._verbs.Verbs.Contains(httpMethodOverride, StringComparer.OrdinalIgnoreCase))
        {
            this._validator.OnAuthorization(filterContext);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here only HTTP requests of the specified verbs are validated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ValidateAntiForgeryTokenWrapper(HttpVerbs.Post, Constants.AntiForgeryTokenSalt)]
public class ProductController : Controller
{
    // GET actions are not affected.
    // Only HTTP POST requests are validated.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now one single attribute on a controller turns on validation for all POST actions in that controller.&lt;/p&gt;
&lt;p&gt;It would be nice if HTTP verbs can be specified on the built-in [ValidateAntiForgeryToken] attribute. And, this is very easy to implement.&lt;/p&gt;
&lt;h2&gt;Specify non-constant salt in runtime&lt;/h2&gt;
&lt;p&gt;By default, the salt should be a compile time constant, so it can be used for the [ValidateAntiForgeryToken] or [ValidateAntiForgeryTokenWrapper] attribute.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;One Web product might be sold to many clients. If a constant salt is evaluated in compile time, after the product is built and deployed to many clients, they all have the same salt. Of course, clients do not like this. Even some clients might expect a configurable custom salt. In these scenarios, salt is required to be a runtime value.&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;In the above [ValidateAntiForgeryToken] and [ValidateAntiForgeryTokenWrapper] attributes, the salt is passed through constructor. So one solution is to remove that parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ValidateAntiForgeryTokenWrapperAttribute : FilterAttribute, IAuthorizationFilter
{
    public ValidateAntiForgeryTokenWrapperAttribute(HttpVerbs verbs)
    {
        this._verbs = new AcceptVerbsAttribute(verbs);
        this._validator = new ValidateAntiForgeryTokenAttribute()
            {
                Salt = Configurations.AntiForgeryTokenSalt
            };
    }

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this smells bad because the injected dependency becomes a hard dependency. So the other solution to work around the limitation of attributes, is moving validation code into controller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class AntiForgeryControllerBase : Controller
{
    private readonly ValidateAntiForgeryTokenAttribute _validator;

    private readonly AcceptVerbsAttribute _verbs;

    protected AntiForgeryControllerBase(HttpVerbs verbs, string salt)
    {
        this._verbs = new AcceptVerbsAttribute(verbs);
        this._validator = new ValidateAntiForgeryTokenAttribute()
            {
                Salt = salt
            };
    }

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        string httpMethodOverride = filterContext.HttpContext.Request.GetHttpMethodOverride();
        if (this._verbs.Verbs.Contains(httpMethodOverride, StringComparer.OrdinalIgnoreCase))
        {
            this._validator.OnAuthorization(filterContext);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then just make controller classes inheriting from this AntiForgeryControllerBase class. Now the salt is no long required to be a compile time constant.&lt;/p&gt;
&lt;h2&gt;Submit token via AJAX&lt;/h2&gt;
&lt;p&gt;For browser side, once server side turns on anti-forgery validation for HTTP POST, all AJAX POST requests will fail by default.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;In AJAX scenarios, the HTTP POST request is not sent by form. Take jQuery as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.post(url, {
    productName: &quot;Tofu&quot;,
    categoryId: 1 // Token is not posted.
}, callback);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of AJAX POST requests will always be invalid, because server side code cannot see the token in the posted data.&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;Basically, the tokens must be printed to browser then sent back to server. So first of all, HtmlHelper.AntiForgeryToken() need to be called somewhere. Now the browser has token in both HTML and cookie.&lt;/p&gt;
&lt;p&gt;Then jQuery must find the printed token in the HTML, and append token to the data before sending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.post(url, {
    productName: &quot;Tofu&quot;,
    categoryId: 1,
    __RequestVerificationToken: getToken() // Token is posted.
}, callback);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To be reusable, this can be encapsulated into a tiny jQuery plugin:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&quot;jquery-1.4.2.js&quot; /&amp;gt;

(function ($) {
    $.getAntiForgeryToken = function (tokenWindow, appPath) {
        // HtmlHelper.AntiForgeryToken() must be invoked to print the token.
        tokenWindow = tokenWindow &amp;amp;&amp;amp; typeof tokenWindow === typeof window ? tokenWindow : window;

        appPath = appPath &amp;amp;&amp;amp; typeof appPath === &quot;string&quot; ? &quot;_&quot; + appPath.toString() : &quot;&quot;;
        // The name attribute is either __RequestVerificationToken,
        // or __RequestVerificationToken_{appPath}.
        var tokenName = &quot;__RequestVerificationToken&quot; + appPath;

        // Finds the &amp;lt;input type=&quot;hidden&quot; name={tokenName} value=&quot;...&quot; /&amp;gt; from the specified window.
        // var inputElements = tokenWindow.$(&quot;input[type=&apos;hidden&apos;][name=&apos; + tokenName + &quot;&apos;]&quot;);
        var inputElements = tokenWindow.document.getElementsByTagName(&quot;input&quot;);
        for (var i = 0; i &amp;lt; inputElements.length; i++) {
            var inputElement = inputElements[i];
            if (inputElement.type === &quot;hidden&quot; &amp;amp;&amp;amp; inputElement.name === tokenName) {
                return {
                    name: tokenName,
                    value: inputElement.value
                };
            }
        }
    };

    $.appendAntiForgeryToken = function (data, token) {
        // Converts data if not already a string.
        if (data &amp;amp;&amp;amp; typeof data !== &quot;string&quot;) {
            data = $.param(data);
        }

        // Gets token from current window by default.
        token = token ? token : $.getAntiForgeryToken(); // $.getAntiForgeryToken(window).

        data = data ? data + &quot;&amp;amp;&quot; : &quot;&quot;;
        // If token exists, appends {token.name}={token.value} to data.
        return token ? data + encodeURIComponent(token.name) + &quot;=&quot; + encodeURIComponent(token.value) : data;
    };

    // Wraps $.post(url, data, callback, type) for most common scenarios.
    $.postAntiForgery = function (url, data, callback, type) {
        return $.post(url, $.appendAntiForgeryToken(data), callback, type);
    };

    // Wraps $.ajax(settings).
    $.ajaxAntiForgery = function (settings) {
        // Supports more options than $.ajax(): 
        // settings.token, settings.tokenWindow, settings.appPath.
        var token = settings.token ? settings.token : $.getAntiForgeryToken(settings.tokenWindow, settings.appPath);
        settings.data = $.appendAntiForgeryToken(settings.data, token);
        return $.ajax(settings);
    };
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In most of the scenarios, it is Ok to just replace $.post() invocation with $.postAntiForgery(), and replace $.ajax() with $.ajaxAntiForgery():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.postAntiForgery(url, {
    productName: &quot;Tofu&quot;,
    categoryId: 1
}, callback); // The same usage as $.post(), but token is posted.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There might be some scenarios of custom token, where $.appendAntiForgeryToken() is useful:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data = $.appendAntiForgeryToken(data, token);
// Token is already in data. No need to invoke $.postAntiForgery().
$.post(url, data, callback);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or $.ajaxAntiForgery() can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.ajaxAntiForgery({
    type: &quot;POST&quot;,
    url: url,
    data: {
        productName: &quot;Tofu&quot;,
        categoryId: 1
    },
    success: callback, // The same usage as $.ajax(), supporting more options.
    token: token // Custom token.
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there are special scenarios that the token is not in the current window. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An HTTP POST request can be sent from an iframe, while the token is in the parent window or top window;&lt;/li&gt;
&lt;li&gt;An HTTP POST request can be sent from an popup window or a dialog, while the token is in the opener window;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc. Here, token&apos;s container window can be specified for $.getAntiForgeryToken():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data = $.appendAntiForgeryToken(data, $.getAntiForgeryToken(window.parent));
// Token is already in data. No need to invoke $.postAntiForgery().
$.post(url, data, callback);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or $.ajaxAntiForgery() can be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.ajaxAntiForgery({
    type: &quot;POST&quot;,
    url: url,
    data: {
        productName: &quot;Tofu&quot;,
        categoryId: 1
    },
    success: callback, // The same usage as $.ajax(), supporting more options.
    tokenWindow: window.parent // Token is in another window.
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you have better solution, please do tell me.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (10) Implementing LINQ to SQL Provider</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-10-implementing-linq-to-sql-provider/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-10-implementing-linq-to-sql-provider/</guid><description>\]</description><pubDate>Tue, 11 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;So far LINQ to SQL data CRUD (Creating / Retrieving / Updating / Deleting) has been explained. This post takes a deeper look at the internal implementation of LINQ to SQL query.&lt;/p&gt;
&lt;h2&gt;The provider model&lt;/h2&gt;
&lt;p&gt;Unlike IEnumerable / IEnumerable&amp;lt;T&amp;gt;, the IQueryable / IQueryable&amp;lt;T&amp;gt; need a query provider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable : IEnumerable
    {
        Type ElementType { get; }

        Expression Expression { get; }

        IQueryProvider Provider { get; }
    }

    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IQueryable, IEnumerable
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the definition of IQueryProvider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryProvider
    {
        IQueryable CreateQuery(Expression expression);

        IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression);

        object Execute(Expression expression);

        TResult Execute&amp;lt;TResult&amp;gt;(Expression expression);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, IQueryable / IQueryable&amp;lt;T&amp;gt; are much more complex than IEnumerable / IEnumerable&amp;lt;T&amp;gt;, because they are supposed to work against non-.NET data source, like SQL Server database, etc.&lt;/p&gt;
&lt;p&gt;Please also notice IOrderedQueryable and IOrderedQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    // The same as IQueryable.
    public interface IOrderedQueryable : IQueryable, IEnumerable
    {
    }
    
    // The same as IQueryable&amp;lt;T&amp;gt;.
    public interface IOrderedQueryable&amp;lt;out T&amp;gt; : IOrderedQueryable,
                                                IQueryable&amp;lt;T&amp;gt;, IQueryable,
                                                IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are the same as IQueryable and IQueryable&amp;lt;T&amp;gt;, and just used to represent an ordering query, like OrderBy(), etc.&lt;/p&gt;
&lt;h3&gt;Implement IQueryable&amp;lt;T&amp;gt; and IOrderedQueryable&amp;lt;T&amp;gt;&lt;/h3&gt;
&lt;p&gt;The best way to understand these interfaces is just creating IQueryable / IQueryable&amp;lt;T&amp;gt; objects, and examining how they work and query data from SQL Server.&lt;/p&gt;
&lt;p&gt;This is one simple implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Queryable&amp;lt;TSource&amp;gt; : IOrderedQueryable&amp;lt;TSource&amp;gt;
{
    public Queryable(IQueryProvider provider, IQueryable&amp;lt;TSource&amp;gt; innerSource)
    {
        this.Provider = provider;
        this.Expression = Expression.Constant(innerSource);
    }

    public Queryable(IQueryProvider provider, Expression expression)
    {
        this.Provider = provider;
        this.Expression = expression;
    }

    #region IEnumerable&amp;lt;TSource&amp;gt; Members

    public IEnumerator&amp;lt;TSource&amp;gt; GetEnumerator()
    {
        return this.Provider.Execute&amp;lt;IEnumerable&amp;lt;TSource&amp;gt;&amp;gt;(this.Expression).GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    #endregion

    #region IQueryable Members

    public Type ElementType
    {
        get
        {
            return typeof(TSource);
        }
    }

    public Expression Expression
    {
        get;
        private set;
    }

    public IQueryProvider Provider
    {
        get;
        private set;
    }

    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since Queryable&amp;lt;TSource&amp;gt; implements IOrderedQueryable&amp;lt;T&amp;gt;, it also implements IQeryable&amp;lt;TSource&amp;gt;, IQeryable and IOrderedQueryable.&lt;/p&gt;
&lt;p&gt;There is not too much things. The most important method is GetEnumerator(). When a Queryable&amp;lt;TSource&amp;gt; object is iterated to traverse the data items, it simply asks its query provider to execute its expression to retrieve an IEnumerable&amp;lt;TSource&amp;gt; object, and return that object’s iterator.&lt;/p&gt;
&lt;h3&gt;Implement IQueryProvider&lt;/h3&gt;
&lt;p&gt;So the actual SQL query implantation is in the query provider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class QueryProvider : IQueryProvider
{
    // Translates LINQ query to SQL.
    private readonly Func&amp;lt;IQueryable, DbCommand&amp;gt; _translator;

    // Executes the translated SQL and retrieves results.
    private readonly Func&amp;lt;Type, string, object[], IEnumerable&amp;gt; _executor;

    public QueryProvider(
        Func&amp;lt;IQueryable, DbCommand&amp;gt; translator,
        Func&amp;lt;Type, string, object[], IEnumerable&amp;gt; executor)
    {
        this._translator = translator;
        this._executor = executor;
    }

    #region IQueryProvider Members

    public IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression)
    {
        return new Queryable&amp;lt;TElement&amp;gt;(this, expression);
    }

    public IQueryable CreateQuery(Expression expression)
    {
        throw new NotImplementedException();
    }

    public TResult Execute&amp;lt;TResult&amp;gt;(Expression expression)
    {
        bool isCollection = typeof(TResult).IsGenericType &amp;amp;&amp;amp;
            typeof(TResult).GetGenericTypeDefinition() == typeof(IEnumerable&amp;lt;&amp;gt;);
        Type itemType = isCollection
            // TResult is an IEnumerable`1 collection.
            ? typeof(TResult).GetGenericArguments().Single()
            // TResult is not an IEnumerable`1 collection, but a single item.
            : typeof(TResult);
        IQueryable queryable = Activator.CreateInstance(
            typeof(Queryable&amp;lt;&amp;gt;).MakeGenericType(itemType), this, expression) as IQueryable;

        IEnumerable queryResult;

        // Translates LINQ query to SQL.
        using (DbCommand command = this._translator(queryable))
        {
            // Executes the transalted SQL.
            queryResult = this._executor(
                itemType,
                command.CommandText,
                command.Parameters.OfType&amp;lt;DbParameter&amp;gt;()
                                  .Select(parameter =&amp;gt; parameter.Value)
                                  .ToArray());
        }

        return isCollection
            ? (TResult)queryResult // Returns an IEnumerable`1 collection.
            : queryResult.OfType&amp;lt;TResult&amp;gt;()
                         .SingleOrDefault(); // Returns a single item.
    }

    public object Execute(Expression expression)
    {
        throw new NotImplementedException();
    }

    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;QueryProvider must be initialized with a translator and executor, so that it is able to translate LINQ query to SQL, and execute the translated SQL.&lt;/p&gt;
&lt;p&gt;And here the most important is the generic Execute() method, which is called by the above Queryable&amp;lt;TSource&amp;gt;.GetEnumerator(). It does the following work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checks whether it should return a collection of items (for the Where() scenarios, etc.), or should return a sinlge item (for the Single() query scenarios, etc.)&lt;/li&gt;
&lt;li&gt;Invokes the translator to translate LINQ query to SQL.&lt;/li&gt;
&lt;li&gt;Invokes the executor to execute the translated SQL and retrieves the result.&lt;/li&gt;
&lt;li&gt;Returns result of a proper type (either a collection, or a single item).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Query method internals&lt;/h2&gt;
&lt;p&gt;Before running the query, take a look at the IQueryable&amp;lt;T&amp;gt; query methods.&lt;/p&gt;
&lt;h3&gt;Deferred execution methods&lt;/h3&gt;
&lt;p&gt;Take Where() as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
{
    public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
        this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
    {
        // Checks arguments.
        return source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(
            Expression.Call(
                null,
                ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[]
                    { 
                        typeof(TSource) 
                    }),
                new Expression[] 
                    { 
                        source.Expression, 
                        Expression.Quote(predicate) 
                    }));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is very very different from &lt;a href=&quot;/posts/understanding-linq-to-objects-7-query-methods-internals&quot;&gt;IEnumerable&amp;lt;T&amp;gt;’s Where() query method&lt;/a&gt;. It is not executing any thing, it just:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Constructs a new expression tree, which contains the following information:
&lt;ul&gt;
&lt;li&gt;The original expression tree from the source IQueryable&amp;lt;T&amp;gt; object&lt;/li&gt;
&lt;li&gt;The predicate expression tree&lt;/li&gt;
&lt;li&gt;This Where() query method is invoked&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Then invokes the query provider’s generic CreateQuery() method to construct a new IQueryable&amp;lt;TSource&amp;gt; object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Obviously, the above constructed expression tree is used to contain the information which is prepared to be translated.&lt;/p&gt;
&lt;p&gt;The ordering query method, like OrderBy(), is a little different, which converts the constructed IQueryable&amp;lt;TSource&amp;gt; object to an IOrderedQueryable&amp;lt;TSource&amp;gt; object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; OrderBy&amp;lt;TSource, TKey&amp;gt;(
    this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector)
{
    // Checks arguments.
    return (IOrderedQueryable&amp;lt;TSource&amp;gt;)source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(
        Expression.Call(
            null, 
            ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] 
                { 
                    typeof(TSource), 
                    typeof(TKey) 
                }), 
            new Expression[] 
                { 
                    source.Expression, 
                    Expression.Quote(keySelector) 
                }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so is ThenBy():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IOrderedQueryable&amp;lt;TSource&amp;gt; ThenBy&amp;lt;TSource, TKey&amp;gt;(
    this IOrderedQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, TKey&amp;gt;&amp;gt; keySelector)
{
    // Checks arguments.
    return (IOrderedQueryable&amp;lt;TSource&amp;gt;)source.Provider.CreateQuery&amp;lt;TSource&amp;gt;(
        Expression.Call(
            null, 
            ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] 
                { 
                    typeof(TSource), 
                    typeof(TKey) 
                }), 
            new Expression[] { 
                    source.Expression, 
                    Expression.Quote(keySelector) 
            }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ThenBy() / ThenByDescending() are extension methods of IOrderedQueryable&amp;lt;TSource&amp;gt; instead of IQueryable&amp;lt;TSource&amp;gt;, which means, It must be invoked after invoking OrderBy() / OrderByDescending().&lt;/p&gt;
&lt;h3&gt;Eager execution methods&lt;/h3&gt;
&lt;p&gt;Single() is different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static TSource Single&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source)
{
    // Checks arguments.
    return source.Provider.Execute&amp;lt;TSource&amp;gt;(
        Expression.Call(
            null, 
            ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] 
                { 
                    typeof(TSource) 
                }), 
            new Expression[] 
                { 
                    source.Expression 
                }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Logically, Single() cannot be deferred. So after construction the expression tree, it invokes query provider’s generic Execute() method, and returns a TSource object instead of a IQueryable&amp;lt;TSource&amp;gt;.&lt;/p&gt;
&lt;p&gt;Of course, the aggregate methods looks similar, invoking Execute() instead of CreateQuery():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static decimal Average&amp;lt;TSource&amp;gt;(
    this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, decimal&amp;gt;&amp;gt; selector)
{
    // Checks arguments.
    return source.Provider.Execute&amp;lt;decimal&amp;gt;(
        Expression.Call(
            null, 
            ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] 
                { 
                    typeof(TSource) 
                }), 
            new Expression[] 
                { 
                    source.Expression, 
                    Expression.Quote(selector) 
                }));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It cannot be deferred either.&lt;/p&gt;
&lt;h2&gt;Work together&lt;/h2&gt;
&lt;p&gt;Now it is ready to run all the stuff above.&lt;/p&gt;
&lt;h3&gt;Query a collection of items (deferred execution)&lt;/h3&gt;
&lt;p&gt;The following query expects a collection of Product objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryProvider provider = new QueryProvider(database.GetCommand, database.ExecuteQuery);
    IQueryable&amp;lt;Product&amp;gt; source = new Queryable&amp;lt;Product&amp;gt;(provider, database.GetTable&amp;lt;Product&amp;gt;());
    IQueryable&amp;lt;string&amp;gt; results = source.Where(product =&amp;gt; product.CategoryID == 2)
                                       .OrderBy(product =&amp;gt; product.ProductName)
                                       .Select(product =&amp;gt; product.ProductName)
                                       .Skip(5)
                                       .Take(10);

    using (IEnumerator&amp;lt;string&amp;gt; iterator = results.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            string item = iterator.Current;
            Console.WriteLine(item);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To initialize the provider, DataContext.GetCommand() and DataContext.ExecuteQuery() are passed as translator and executor.&lt;/p&gt;
&lt;p&gt;When results.GetEnumerator() is invoked, provider.Execute() is invoked. The query is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t1].[ProductName]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ProductName]) AS [ROW_NUMBER], [t0].[ProductName]
    FROM [dbo].[Products] AS [t0]
    WHERE [t0].[CategoryID] &amp;gt; @p0
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER]&apos;,N&apos;@p0 int,@p1 int,@p2 int&apos;,@p0=2,@p1=5,@p2=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;by the provider’s translator, then provider’s executor executes the above SQL in SQL Server, and return a collection of items.&lt;/p&gt;
&lt;p&gt;This is the printed output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Escargots de Bourgogne Filo Mix Flotemysost Geitost Gnocchi di nonna Alice Gorgonzola Telino Gravad lax Gudbrandsdalsost Gumbär Gummibärchen Gustaf&apos;s Knäckebröd&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Query a single item (eager execution)&lt;/h3&gt;
&lt;p&gt;The following sample is different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider provider = new QueryProvider(database.GetCommand, database.ExecuteQuery);
IQueryable&amp;lt;Product&amp;gt; source = new Queryable&amp;lt;Product&amp;gt;(provider, database.GetTable&amp;lt;Product&amp;gt;());
string productName = source.Where(product =&amp;gt; product.CategoryID &amp;gt; 2)
                           .Select(product =&amp;gt; product.ProductName)
                           .First();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without deferred execution and iterating, the First() invokes provider.Execute() directly.&lt;/p&gt;
&lt;p&gt;This is the translated SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT TOP (1) [t0].[ProductName]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] &amp;gt; @p0&apos;,N&apos;@p0 int&apos;,@p0=2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Aggregate (eager execution)&lt;/h3&gt;
&lt;p&gt;Aggregate query is also eager:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryProvider provider = new QueryProvider(database.GetCommand, database.ExecuteQuery);
IQueryable&amp;lt;Product&amp;gt; source = new Queryable&amp;lt;Product&amp;gt;(provider, database.GetTable&amp;lt;Product&amp;gt;());
decimal averagePrice = source.Where(product =&amp;gt; product.CategoryID == 2)
                             .Average(product =&amp;gt; product.UnitPrice.GetValueOrDefault());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the translated SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT AVG([t1].[value]) AS [value]
FROM (
    SELECT COALESCE([t0].[UnitPrice],0) AS [value], [t0].[CategoryID]
    FROM [dbo].[Products] AS [t0]
    ) AS [t1]
WHERE [t1].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;SQL translating and executing&lt;/h3&gt;
&lt;p&gt;The above samples explained the implementation of LINQ to SQL query and query provider. Inside the QueryProvider class, it does not provide the detailed implementation of SQL translating and executing, but pass the work to DataContext.GetCommand() and DataContext.ExecuteQuery().&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;This post&lt;/a&gt; has demonstrated the simplest SQL translating and executing. But the realistic work is very very complex. Since this is not a SQL series but a LINQ / functional programming series, to develop a full featured SQL “compiler” is far beyond this series’ scope. For SQL executing, it is also complex to convert the retrieved data back to strong-typed objects in LINQ to SQL. To understand the entire translating and executing process, please follow the source code of Table&amp;lt;T&amp;gt;, which implements IQueryProvider.&lt;/p&gt;
&lt;p&gt;Internally, Table&amp;lt;T&amp;gt; uses several internal classes, like SqlProvider, QueryConverter, etc., to accomplish the translating. For example, one of the core APIs is the QueryConverter.VisitSequenceOperatorCall():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class QueryConverter
{
    private SqlNode VisitSequenceOperatorCall(MethodCallExpression mc)
    {
        Type declaringType = mc.Method.DeclaringType;
        if (!(declaringType == typeof(Enumerable)) &amp;amp;&amp;amp; !(declaringType == typeof(Queryable)))
        {
            throw new InvalidOperationException(string.Format(
                CultureInfo.InvariantCulture,
                &quot;Sequence operator call is only valid for Sequence, Queryable, or DataQueryExtensions not for &apos;{0}&apos;&quot;,
                declaringType));
        }

        bool isNotSupported = false;
        switch (mc.Method.Name)
        {
            case &quot;Where&quot;:
                isNotSupported = true;

                // The overload:
                // IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
                // this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, int, bool&amp;gt;&amp;gt; predicate)
                // is not supported.

                // The MethodCallExpression object mc should have 2 arguments.
                // The first argument should be null.
                // The second argument should be Expression.Quote(predicate).
                if (mc.Arguments.Count != 2 ||
                    // IsLambda() removes the quote to get the predicate object,
                    // and checks predicate.NodeType ==  ExpressionType.Lambda.
                    !this.IsLambda(mc.Arguments[1]) ||
                    // precicate should have 1 TSource argument.
                    this.GetLambda(mc.Arguments[1]).Parameters.Count != 1)
                {
                    break; // The overload is not supported.
                }

                // The overload:
                // IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
                // this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
                // is supported.
                return this.VisitWhere(mc.Arguments[0], this.GetLambda(mc.Arguments[1]));

            case &quot;OrderBy&quot;:
                isNotSupported = true;

                if (mc.Arguments.Count != 2 || !this.IsLambda(mc.Arguments[1]) ||
                    this.GetLambda(mc.Arguments[1]).Parameters.Count != 1)
                {
                    break; // The overload is not supported.
                }

                return this.VisitOrderBy(
                    mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Ascending);

            case &quot;ThenBy&quot;:
                isNotSupported = true;

                if (mc.Arguments.Count != 2 || !this.IsLambda(mc.Arguments[1]) ||
                    this.GetLambda(mc.Arguments[1]).Parameters.Count != 1)
                {
                    break; // The overload is not supported.
                }

                return this.VisitThenBy(
                    mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Ascending);

            case &quot;Single&quot;:
            case &quot;SingleOrDefault&quot;:
                isNotSupported = true;

                if (mc.Arguments.Count != 1)
                {
                    if (mc.Arguments.Count != 2 || !this.IsLambda(mc.Arguments[1]) ||
                        this.GetLambda(mc.Arguments[1]).Parameters.Count != 1)
                    {
                        break; // The overload is not supported.
                    }

                    return this.VisitFirst(
                        mc.Arguments[0], this.GetLambda(mc.Arguments[1]), false);
                }

                return this.VisitFirst(mc.Arguments[0], null, false);

            case &quot;Average&quot;:
                isNotSupported = true;

                if (mc.Arguments.Count != 1)
                {
                    if (mc.Arguments.Count != 2 || !this.IsLambda(mc.Arguments[1]) ||
                        this.GetLambda(mc.Arguments[1]).Parameters.Count != 1)
                    {
                        break; // The overload is not supported.
                    }

                    return this.VisitAggregate(
                        mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Avg, mc.Type);
                }

                return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Avg, mc.Type);

            // Other cases, like &quot;Take&quot;, &quot;Skip&quot;, &quot;Distinct&quot;, etc.                
        }

        if (isNotSupported)
        {
            throw new NotSupportedException(string.Format(
                CultureInfo.InvariantCulture,
                &quot;Unsupported overload used for query operator &apos;{0}&apos;.&quot;,
                mc.Method.Name));
        }

        throw new NotSupportedException(string.Format(
            CultureInfo.InvariantCulture,
            &quot;The query operator &apos;{0}&apos; is not supported.&quot;,
            mc.Method.Name));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please compare this with the fore mentioned IQueryable&amp;lt;T&amp;gt; query methods, Where(), OrderBy(), Single(), Average(), etc.&lt;/p&gt;
&lt;p&gt;There is also &lt;a href=&quot;http://msdn.microsoft.com/en-us/vcsharp/ee672195.aspx&quot;&gt;an excellent tutorial&lt;/a&gt; from MSDN.&lt;/p&gt;
&lt;h2&gt;LINQ Providers&lt;/h2&gt;
&lt;p&gt;There are several kinds of built-in LINQ in .NET 4.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb397919.aspx&quot;&gt;LINQ to Objects&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd460688.aspx&quot;&gt;Parallel LINQ to Objects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb387098.aspx&quot;&gt;LINQ to XML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb397942.aspx&quot;&gt;LINQ to ADO.NET&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386976.aspx&quot;&gt;LINQ to SQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386977.aspx&quot;&gt;LINQ to DataSet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386964.aspx&quot;&gt;LINQ to Entities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb399365.aspx&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/builtinlinq_12A094FC.gif&quot; alt=&quot;built-in-linq&quot; title=&quot;built-in-linq&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Built-in IQueryable LINQ Providers&lt;/h3&gt;
&lt;p&gt;LINQ to Objects and LINQ to XML are IEnumerable based, and the 3 kinds of LINQ to ADO.NET are IQueryable-based, which have their specific IQueryProvider.&lt;/p&gt;
&lt;p&gt;For example, in LINQ to SQL, the IQueryable, IQueryable&amp;lt;T&amp;gt; and IQueryProvider are implemented by Table&amp;lt;T&amp;gt; class and an internal DataQuery&amp;lt;T&amp;gt; class. DataQuery&amp;lt;T&amp;gt; also implements IOrderedQueryable and IOrderedQueryable&amp;lt;T&amp;gt;. These classes and all the other related classes (like SqlProvider, ) can be considered the provider of LINQ to SQL.&lt;/p&gt;
&lt;h3&gt;LINQ to Everything&lt;/h3&gt;
&lt;p&gt;To implement any other LINQ query against a specific data source, the specific LINQ provider should be provided. That is, classes which implements the above IQueryable, IQueryable&amp;lt;T&amp;gt;, IQueryProvider, IOrderedQueryable and IOrderedQueryable&amp;lt;T&amp;gt; interfaces. The &lt;a href=&quot;http://linqtowikipedia.codeplex.com/&quot;&gt;LINQ to Wikipedia&lt;/a&gt; provider &lt;a href=&quot;/posts/introducing-linq-1-what-is-linq&quot;&gt;at the beginning of the series&lt;/a&gt; is one example. &lt;a href=&quot;http://blogs.msdn.com/charlie/archive/2008/02/28/link-to-everything-a-list-of-linq-providers.aspx&quot;&gt;This post&lt;/a&gt; lists a lot of custom LINQ providers, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.codeplex.com/xlslinq&quot;&gt;LINQ to Excel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.codeplex.com/LINQtoSharePoint&quot;&gt;LINQ to Sharepoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://bloggingabout.net/blogs/emile/archive/2005/12/12/10514.aspx&quot;&gt;LINQ to WMI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb546158.aspx&quot;&gt;This tutorial&lt;/a&gt; teaches how to create a IQueryable LINQ provider against the &lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkId=98557&quot;&gt;TerraServer-USA Web service&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;LINQ to Objects provider&lt;/h3&gt;
&lt;p&gt;LINQ to Objects is IEnumerable based, but the interesting thing is, IEnumerble&amp;lt;T&amp;gt; has an AsQueryable() extension method, which turns IEnumerble-based query into IQueryable-based query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Queryable
{
    public static IQueryable&amp;lt;TElement&amp;gt; AsQueryable&amp;lt;TElement&amp;gt;(
        this IEnumerable&amp;lt;TElement&amp;gt; source)
    {
        // Checks arguments.
        if (source is IQueryable&amp;lt;TElement&amp;gt;)
        {
            return (IQueryable&amp;lt;TElement&amp;gt;)source;
        }

        return new EnumerableQuery&amp;lt;TElement&amp;gt;(source);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the EnumerableQuery&amp;lt;T&amp;gt; class implements IQueryable&amp;lt;T&amp;gt;, as well as the IQueryProvider:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public abstract class EnumerableQuery
    {
        // ...
    }

    public class EnumerableQuery&amp;lt;T&amp;gt; : EnumerableQuery, IQueryProvider,
                                      IQueryable&amp;lt;T&amp;gt;, IQueryable,
                                      IOrderedQueryable&amp;lt;T&amp;gt;, IOrderedQueryable,
                                      IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Internally, EnumerableQuery&amp;lt;T&amp;gt;.Execute() invokes Expression&amp;lt;TDelegate&amp;gt;.Compile() to execute the expression representing the query.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (9) Concurrent Conflict</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-9-concurrent-conflict/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-9-concurrent-conflict/</guid><description>\]</description><pubDate>Mon, 26 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Conflicts are very common when &lt;a href=&quot;http://en.wikipedia.org/wiki/Concurrency_(computer_science)&quot;&gt;concurrently&lt;/a&gt; accessing the same data.&lt;/p&gt;
&lt;h2&gt;Conflicts in concurrent data access&lt;/h2&gt;
&lt;p&gt;The following code demonstrates the concurrent conflict scenario:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, Action&amp;lt;Category&amp;gt;&amp;gt; updateCategory = (id, updater) =&amp;gt;
    {
        using (NorthwindDataContext database = new NorthwindDataContext())
        {
            Category category = database.Categories
                                        .Single(item =&amp;gt; item.CategoryID == id);

            Thread.Sleep(4000);

            updater(category);
            // database.SubmitChanges() invokes:
            database.SubmitChanges(ConflictMode.FailOnFirstConflict);
        }
    };

new Thread(() =&amp;gt; updateCategory(1, category =&amp;gt; category.CategoryName = &quot;Thread 1&quot;)).Start();

Thread.Sleep(2000);

new Thread(() =&amp;gt; updateCategory(1, category =&amp;gt; category.CategoryName = &quot;Thread 2&quot;)).Start();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here 2 threads are accessing the same category. This is the order of the executions:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;662&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;127&quot;&amp;gt;Time (second)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;149&quot;&amp;gt;Thread 1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;Thread 2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;206&quot;&amp;gt;[CategoryName] database value&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;127&quot;&amp;gt;0 (Thread 1 reads)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;149&quot;&amp;gt;Retrieves “Beverages”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;206&quot;&amp;gt;“Beverages”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;127&quot;&amp;gt;2 (Thread 2 reads)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;149&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;Retrieves “Beverages”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;206&quot;&amp;gt;“Beverages”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;127&quot;&amp;gt;4 (Thread 1 writes)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;149&quot;&amp;gt;updates “Beverages” to “Thread 1”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;206&quot;&amp;gt;“Thread 1”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;127&quot;&amp;gt;6 (Thread 2 writes)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;149&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;178&quot;&amp;gt;&amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;Should update “Beverages” to “Thread 2”&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;206&quot;&amp;gt;&amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;[CategoryName] is no longer “Beverages”&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;When the later started thread (thread 2) tries to submit the change, the conflict occurs, and DataContext.SubmitChanges() throws a ChangeConflictException:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Row not found or changed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Optimistic concurrency control&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Concurrency_control&quot;&gt;concurrency control&lt;/a&gt; tactic of LINQ to SQL is &lt;a href=&quot;http://en.wikipedia.org/wiki/Optimistic_concurrency_control&quot;&gt;optimistic&lt;/a&gt;, which means LINQ to SQL checks the status of data instead of locking the data (pessimistic concurrency control).&lt;/p&gt;
&lt;p&gt;This is the translated SQL from 2 threads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Thread 1 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 2 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 1 writes.
BEGIN TRANSACTION 
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=1,@p1=N&apos;Beverages&apos;,@p2=N&apos;Thread 1&apos; -- CategoryName has an [Column(UpdateCheck = UpdateCheck.Always)] attribute.
COMMIT TRANSACTION -- Updating successes.

-- Thread 2 writes.
BEGIN TRANSACTION 
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=1,@p1=N&apos;Beverages&apos;,@p2=N&apos;Thread 2&apos; -- CategoryName has an [Column(UpdateCheck = UpdateCheck.Always)] attribute.
ROLLBACK TRANSACTION -- Updating fails.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When submitting data changes, LINQ to SQL not only uses primary key to identify the data, but also checks the original state of the column which is expected to be updated.&lt;/p&gt;
&lt;h3&gt;Update check&lt;/h3&gt;
&lt;p&gt;This original state check is specified by the [Column] attribute of entity property:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_14545167.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If ColumnAttribute.UpdateCheck is not specified:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Column(Storage = &quot;_CategoryName&quot;, DbType = &quot;NVarChar(15) NOT NULL&quot;, CanBeNull = false)]
public string CategoryName
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then it will have a default value: UpdateCheck.Always:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public sealed class ColumnAttribute : DataAttribute
{
    private UpdateCheck _updateCheck = UpdateCheck.Always;

    public UpdateCheck UpdateCheck
    {
        get
        {
            return this._updateCheck;
        }
        set
        {
            this._updateCheck = value;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Time stamp&lt;/h3&gt;
&lt;p&gt;In the above screenshot, there is a [Time Stamp] option in the O/R designer, which can be used when this column is of type timestamp (rowversion). To demonstrating this, add a timestamp column [Version] to the [Categories] table:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_2F5CFAA8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And recreate the model in O/R designer. Now this is the generated [Column] attribute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Column(Storage = &quot;_Version&quot;, AutoSync = AutoSync.Always, DbType = &quot;rowversion NOT NULL&quot;, 
    CanBeNull = false, IsDbGenerated = true, IsVersion = true, UpdateCheck = UpdateCheck.Never)]
public Binary Version
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now LINQ to SQL always checks the [Version] column instead of [CategoryName] column. So when rerunning the above code, the translated SQL is different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Thread 1 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture], [t0].[Version]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 2 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture], [t0].[Version]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 1 writes.
BEGIN TRANSACTION 
-- Checks time stamp.
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([Version] = @p1)

SELECT [t1].[Version]
FROM [dbo].[Categories] AS [t1]
WHERE ((@@ROWCOUNT) &amp;gt; 0) AND ([t1].[CategoryID] = @p3)&apos;,N&apos;@p0 int,@p1 timestamp,@p2 nvarchar(4000),@p3 int&apos;,@p0=1,@p1=0x0000000000000479,@p2=N&apos;Thread 1&apos;,@p3=1
-- SELECT for [Column(AutoSync = AutoSync.Always)]
COMMIT TRANSACTION -- Updating successes.

-- Thread 2 writes.
BEGIN TRANSACTION 
-- Checks time stamp.
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([Version] = @p1)

SELECT [t1].[Version]
FROM [dbo].[Categories] AS [t1]
WHERE ((@@ROWCOUNT) &amp;gt; 0) AND ([t1].[CategoryID] = @p3)&apos;,N&apos;@p0 int,@p1 timestamp,@p2 nvarchar(4000),@p3 int&apos;,@p0=1,@p1=0x0000000000000479,@p2=N&apos;Thread 2&apos;,@p3=1
-- SELECT for [Column(AutoSync = AutoSync.Always)]
ROLLBACK TRANSACTION -- Updating fails.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Handle ChangeConflictException&lt;/h2&gt;
&lt;p&gt;When concurrent conflict occurs, SubmitChanges() rollbacks the TRANSACTION, then throws a ChangeConflictException exception.&lt;/p&gt;
&lt;p&gt;So if the caller of DataContext.SubmitChanges() knows how to resolve the conflict, it can detects conflict by handling ChangeConflictException .&lt;/p&gt;
&lt;h3&gt;Merge changes to resolve conflict&lt;/h3&gt;
&lt;p&gt;For example, a common tactic is to merge the changes into database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;int, Action&amp;lt;Category&amp;gt;&amp;gt; updateCategory = (id, updater) =&amp;gt;
    {
        using (NorthwindDataContext database = new NorthwindDataContext())
        {
            Category category = database.Categories
                                        .Single(item =&amp;gt; item.CategoryID == id);

            Thread.Sleep(4000);

            updater(category);
            try
            {
                // All data changes will be tried before rollback.
                database.SubmitChanges(ConflictMode.ContinueOnConflict);
                // Now all conflicts are stored in DataContext.ChangeConflicts.
            }
            catch (ChangeConflictException)
            {
                foreach (ObjectChangeConflict conflict in database.ChangeConflicts)
                {
                    Console.WriteLine(
                        &quot;Conflicted row: ID = {0}.&quot;,
                        (conflict.Object as Category).CategoryID);

                    foreach (MemberChangeConflict member in conflict.MemberConflicts)
                    {
                        Console.WriteLine(
                            &quot;[{0}] column is expected to be &apos;{1}&apos; in database, but it is not.&quot;,
                            member.Member.Name,
                            member.CurrentValue);
                    }

                    conflict.Resolve(RefreshMode.KeepChanges); // Queries row to merge changes.
                    Console.WriteLine(&quot;Merged changes to row: {0}.&quot;, conflict.IsResolved);
                }

                // Submits again by merging changes.
                database.SubmitChanges();
            }
        }
    };

new Thread(() =&amp;gt; updateCategory(1, category =&amp;gt; category.CategoryName = &quot;Thread 1&quot;)).Start();

Thread.Sleep(2000);

new Thread(() =&amp;gt; updateCategory(1, category =&amp;gt; category.Description = &quot;Thread 2&quot;)).Start();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running this refined code will print:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Conflicted row: ID = 1. [CategoryName] column is expected to be &apos;Beverages&apos; in database, but it is not. Merged changes to row: True.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the order of the executions:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;713&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;Time (second)&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;185&quot;&amp;gt;Thread 1&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;Thread 2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;[CategoryName]&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;[Description]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;0&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;185&quot;&amp;gt;Retrieves “Beverages” for [CategoryName].&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Beverages”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Soft drinks, coffees, teas, beers, and ales”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;185&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;Retrieves “Beverages” for [CategoryName].&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Beverages”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Soft drinks, coffees, teas, beers, and ales”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;4&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;185&quot;&amp;gt;Checks whether [CategoryName] is “Beverages”, and updates [CategoryName].&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Thread 1”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Soft drinks, coffees, teas, beers, and ales”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td rowspan=&quot;3&quot; valign=&quot;top&quot; width=&quot;99&quot;&amp;gt;6&amp;lt;/td&amp;gt;&amp;lt;td rowspan=&quot;3&quot; valign=&quot;top&quot; width=&quot;185&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;Checks whether [CategoryName] is “Beverages”.&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Thread 1”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Soft drinks, coffees, teas, beers, and ales”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;Retrieves “Thread1” for [CategoryName]&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Thread 1”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Soft drinks, coffees, teas, beers, and ales”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;174&quot;&amp;gt;Checks whether [CategoryName] is “Thread 1”., and updates [Description].&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;106&quot;&amp;gt;“Thread 1”&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;147&quot;&amp;gt;“Thread 2”&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Please notice that, to merge the changes, database must be queried.&lt;/p&gt;
&lt;p&gt;This is the entire translated SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Thread 1 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 2 reads.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 1 writes.
BEGIN TRANSACTION 
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=1,@p1=N&apos;Beverages&apos;,@p2=N&apos;Thread 1&apos; -- CategoryName has an [Column(UpdateCheck = UpdateCheck.Always)] attribute.
COMMIT TRANSACTION -- Updating successes.

-- Thread 2 writes.
BEGIN TRANSACTION 
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [Description] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 ntext&apos;,@p0=1,@p1=N&apos;Beverages&apos;,@p2=N&apos;Thread 2&apos; -- CategoryName has an [Column(UpdateCheck = UpdateCheck.Always)] attribute.
ROLLBACK TRANSACTION -- Updating fails.

-- Thread 2 reads data to merge changes.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Thread 2 writes again.
BEGIN TRANSACTION 
exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2, [Description] = @p3
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 ntext&apos;,@p0=1,@p1=N&apos;Thread 1&apos;,@p2=N&apos;Thread 1&apos;,@p3=N&apos;Thread 2&apos;
COMMIT TRANSACTION -- Updating successes.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To resolve conflicts, an easier way is just invoking ChangeConflictCollection.ResolveAll():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;catch (ChangeConflictException)
{
    database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
    database.SubmitChanges();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More about concurrency&lt;/h2&gt;
&lt;p&gt;Because this is a LINQ / functional programming series, not a SQL / database series, this post only gives a brief explanation about how LINQ to SQL controls concurrent conflict. please check &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb399373.aspx&quot;&gt;MSDN&lt;/a&gt; and Wikipedia for further topics, like &lt;a href=&quot;http://en.wikipedia.org/wiki/Concurrency_(computer_science)&quot;&gt;concurrency&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Concurrency_control&quot;&gt;concurrency control&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Optimistic_concurrency_control&quot;&gt;optimistic concurrency control&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Timestamp-based_concurrency_control&quot;&gt;timestamp-based concurrency control&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa213068(v=SQL.80).aspx&quot;&gt;SQL Server transactions&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa213039(SQL.80).aspx&quot;&gt;SQL Server locking&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa213034(SQL.80).aspx&quot;&gt;SQL Server isolation levels&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc917674.aspx&quot;&gt;SQL Server row level versioning&lt;/a&gt;, etc.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (8) Transaction</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-8-transaction/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-8-transaction/</guid><description>\]</description><pubDate>Thu, 22 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Database data Changing cannot be talked about without &lt;a href=&quot;http://en.wikipedia.org/wiki/Database_transaction&quot;&gt;transactions&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Implementing TRANSACTION (BEGIN / COMMIT / ROLLBACK)&lt;/h2&gt;
&lt;p&gt;The previous post has shown that, when invoking SubmitChanges(), the translated SQL (INSERT / UPDATE / DELETE) are always executed within a TRANSACTION.&lt;/p&gt;
&lt;p&gt;Internally, DataContext.SubmitChanges() invokes DataContext.SubmitChanges(ConflictMode.FailOnFirstConflict). The latter is implemented like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DataContext : IDisposable
{
    public virtual void SubmitChanges(ConflictMode failureMode)
    {
        if (this._isInSubmitChanges) // Concurrency is not allowed.
        {
            throw new InvalidOperationException(
                &quot;The operation cannot be performed during a call to SubmitChanges.&quot;);
        }

        if (!this.ObjectTrackingEnabled) // Tracking must be enabled.
        {
            throw new InvalidOperationException(
                &quot;Object tracking is not enabled for the current data context instance.&quot;);
        }

        this._isInSubmitChanges = true;

        try
        {
            if (Transaction.Current != null ||
                this.Transaction != null) // Custom transaction is specified.
            {
                // Process changes...
                return;
            }

            try
            {
                try
                {
                    this.Transaction = this.Connection.BeginTransaction(
                        IsolationLevel.ReadCommitted); // BEGIN TRANSACTION
                    // Process changes...
                    this.Transaction.Commit(); // COMMIT TRANSACTION
                }
                catch
                {
                    this.Transaction.Rollback(); // ROLLBACK TRANSACTION
                    throw; // Failure is notified to the caller.
                }

                return; // Successes.
            }
            finally
            {
                this.Transaction = null; // Finally block ensures clearing transaction.
            }
        }
        finally
        {
            this._isInSubmitChanges = false; // Finally block ensures resetting the flag.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It ensures all changes (INSERT / UPDATE / DELETE) are submitted within a TRANSACTION.&lt;/p&gt;
&lt;p&gt;Conflict will be explained in the next post.&lt;/p&gt;
&lt;h2&gt;Default transaction&lt;/h2&gt;
&lt;p&gt;If the DataContext.Transaction has never been set, it is null. In such scenarios LINQ to SQL will create a DbTransaction object to implement the TRANSACTION:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        Category[] categories = database.Categories.Take(2).ToArray();
        Console.WriteLine(&quot;Category[0]: {0}&quot;, categories[0].CategoryName); // Beverages
        categories[0].CategoryName = &quot;Updated&quot;;
        // Updating should success.

        Console.WriteLine(&quot;Category[1]: {0}&quot;, categories[1].CategoryName); // Condiments
        categories[1].CategoryName = &quot;Aotobots of Transformers&quot;;
        // Updating should fail in database, because CategoryName is NVARCHAR(15).

        database.SubmitChanges();
    }
}
catch (Exception exception)
{
    Console.WriteLine(&quot;{0}: {1}&quot;, exception.GetType(), exception.Message);

    // Checks whether any change has been submitted.
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        Category[] categories = database.Categories.Take(2).ToArray();
        // All records are not updated.
        Console.WriteLine(&quot;Category[0]: {0}&quot;, categories[0].CategoryName); // Beverages
        Console.WriteLine(&quot;Category[1]: {0}&quot;, categories[1].CategoryName); // Condiments
    }

    throw;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code tried to submit two changes, which are translated to two UPDATE statements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION 

exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=1,@p1=N&apos;Beverages&apos;,@p2=N&apos;Updated&apos;
-- Successes.

exec sp_executesql N&apos;UPDATE [dbo].[Categories]
SET [CategoryName] = @p2
WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=2,@p1=N&apos;Condiments&apos;,@p2=N&apos;Aotobots of Transformers&apos;
-- Falis. SubmitChanges() catches a SqlException.

ROLLBACK TRANSACTION -- this.Transaction.Rollback();

-- SubmitChanges() re-throws the SqlException to caller.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because the second UPDATE fails, Submit() catches a SqlException, then it invoke DbTransaction.Rollback() and re-throw the SqlException to the code in the upper call stack.&lt;/p&gt;
&lt;h2&gt;Custom transactions&lt;/h2&gt;
&lt;p&gt;If DataContext.Transaction is set with a custom DbTransaction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    database.Transaction = database.Connection.BeginTransaction();
    // Now DataContext.Transaction is not null.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or current submitting code is bracketed inside a TransactionScope:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    using (TransactionScope transactionScope = new TransactionScope())
    {
        // Transaction.Current is not null here.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then it is not LINQ to SQL’s responsibility to implement the logic of transactions.&lt;/p&gt;
&lt;p&gt;Because this is a LINQ / functional programming series, not a SQL / ADO.NET series, the further details of transaction will not be explained. Please check &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386995.aspx&quot;&gt;MSDN&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Database_transaction&quot;&gt;Wikipedia&lt;/a&gt; for more information.&lt;/p&gt;
</content:encoded></item><item><title>Where Is Transaction Events In SQL Server Profiler?</title><link>https://dixin.github.io/posts/where-is-transaction-events-in-sql-server-profiler/</link><guid isPermaLink="true">https://dixin.github.io/posts/where-is-transaction-events-in-sql-server-profiler/</guid><description>does not monitor transaction events by default.</description><pubDate>Wed, 21 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms181091.aspx&quot;&gt;SQL Server Profiler&lt;/a&gt; does not monitor transaction events by default.&lt;/p&gt;
&lt;p&gt;After installing SQL Server, when creating a new trace, the default template is “Standard”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_0338E252.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Transaction events will not show in the trace because “Transactions” is not included in the “Standard” template:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_36847FE1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;“Transactions” is hidden by default. To show it up, check “Show all events”.&lt;/p&gt;
&lt;p&gt;So the solution of monitoring transaction is, create a new template, and check the transaction events excepted to monitor. Then the profiler rocks!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_6E5AC7BA.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (7) Data Changing</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-7-data-changing/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-7-data-changing/</guid><description>\]</description><pubDate>Tue, 20 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;After understanding how to retrieve data with LINQ to SQL, now take a look at data change (create (insert) / update / delete).&lt;/p&gt;
&lt;h2&gt;Object Identity&lt;/h2&gt;
&lt;p&gt;When changing data queried by LINQ to SQL, one common confusion for LINQ to SQL beginners is the object identity.&lt;/p&gt;
&lt;h3&gt;Identity of entity objects&lt;/h3&gt;
&lt;p&gt;The models working in LINQ to SQL are mappings of SQL Server database stuff, like one .NET entity object in the mummery is the mapping of one record in the database table, etc. Generally speaking, within the scope of one DataContext:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When one query retrieves one record, a mapping entity is created, referring to an object in the memory.&lt;/li&gt;
&lt;li&gt;Later if another query executes, retrieving the same one record again, the newly created entity will refer to the same one object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This default behavior ensures the consistency of mapping: one unique record in database table &amp;lt;-&amp;gt; one unique entity object in application memory.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    Product[] queryResults1 = source.Where(product =&amp;gt; product.ProductID &amp;lt; 4)
                                    .ToArray();
    Product[] queryResults2 = source.Where(product =&amp;gt; product.CategoryID == 1)
                                    .OrderBy(product =&amp;gt; product.UnitPrice)
                                    .ToArray();

    Console.WriteLine(
        &quot;queryResults1[0]: ProductID = {0}, ProductName = {1}, ...&quot;,
        queryResults1[0].ProductID,
        queryResults1[0].ProductName);
    Console.WriteLine(
        &quot;queryResults2[7]: ProductID = {0}, ProductName = {1}, ...&quot;,
        queryResults2[7].ProductID,
        queryResults2[7].ProductName);

    Console.WriteLine(
        &quot;queryResults1[0] == queryResults2[7]: {0}&quot;,
        object.ReferenceEquals(queryResults1[0], queryResults2[7]));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;queryResults1[0]: ProductID = 1, ProductName = Chai, ... queryResults2[7]: ProductID = 1, ProductName = Chai, ... queryResults1[0] == queryResults2[7]: True&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So once queryResults1[0] is changed later, queryResults2[7] will also be changed!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(queryResults2[7].ProductName); // Chai.
queryResults1[0].ProductName = &quot;Test&quot;;
Console.WriteLine(queryResults2[7].ProductName); // Test.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Too many people are confused by this default behavior.&lt;/p&gt;
&lt;p&gt;Because this feature relies on the uniqueness of record in SQL Server, LINQ to SQL requires a primary key on the table. Otherwise, because there is no way to check the uniqueness of record, any newly created entity always refer to a new object in memory. Fortunately, table has a primary key in most of the scenarios.&lt;/p&gt;
&lt;h3&gt;Identity and DataContext&lt;/h3&gt;
&lt;p&gt;Since query relies on DataContext, identity works within the scope of DataContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Product[] queryResults1;
using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    queryResults1 = source.Where(product =&amp;gt; product.ProductID &amp;lt; 4)
                          .ToArray();

}

Product[] queryResults2;
using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    queryResults2 = source.Where(product =&amp;gt; product.CategoryID == 1)
                          .OrderBy(product =&amp;gt; product.UnitPrice)
                          .ToArray();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this sample, entity objects in queryResults1 have nothing to do with entity objects in queryResults2, because two queries’ results come out from tow different DataContexts.&lt;/p&gt;
&lt;h3&gt;Identity of projected objects (non-entity objects)&lt;/h3&gt;
&lt;p&gt;The above feature is designed only for the entity objects mapped to SQL data items, and does not work on projected objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    var queryResults1 = source.Where(product =&amp;gt; product.ProductID &amp;lt; 4)
                              .Select(product =&amp;gt; new
                              {
                                  ProductID = product.ProductID,
                                  ProductName = product.ProductName
                              }) // Projection.
                              .ToArray();
    var queryResults2 = source.Where(product =&amp;gt; product.CategoryID == 1)
                              .OrderBy(product =&amp;gt; product.UnitPrice)
                              .Select(product =&amp;gt; new
                              {
                                  ProductID = product.ProductID,
                                  ProductName = product.ProductName
                              }) // Projection.
                              .ToArray();

    Console.WriteLine(
        &quot;queryResults1[0]: ProductID = {0}, ProductName = {1}&quot;,
        queryResults1[0].ProductID,
        queryResults1[0].ProductName);
    Console.WriteLine(
        &quot;queryResults2[7]: ProductID = {0}, ProductName = {1}&quot;,
        queryResults2[7].ProductID,
        queryResults2[7].ProductName);

    Console.WriteLine(
        &quot;queryResults1[0] == queryResults2[7]: {0}&quot;,
        object.ReferenceEquals(queryResults1[0], queryResults2[7]));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;queryResults1[0]: ProductID = 1, ProductName = Chai queryResults2[7]: ProductID = 1, ProductName = Chai queryResults1[0] == queryResults2[7]: False&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And changing a projected object of one query has nothing to do with a projected object of another query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(queryResults2[7].ProductName); // Chai.
queryResults1[0] = new
    {
        ProductID = 0,
        ProductName = &quot;Test&quot;
    };
Console.WriteLine(queryResults2[7].ProductName); // Chai.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason is projecting is different from mapping. The above projection always creates an new object in memory while working.&lt;/p&gt;
&lt;h2&gt;Track changes&lt;/h2&gt;
&lt;p&gt;By default, when state change happens to entity, it is not reflected to the database immediately, so the state of the entity object and the state of the mapped record become different. The change is deferred and tracked by DataContext. This tracking is possible because the auto-generated entities all implement INotifyPropertyChanging and INotifyPropertyChanged interfaced, which have been explained in &lt;a href=&quot;/posts/understanding-linq-to-sql-1-object-relational-mapping&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;State changes&lt;/h3&gt;
&lt;p&gt;The following example shows the state change is tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Table&amp;lt;Product&amp;gt; source = database.Products;
    Product result = source.First();
    Console.WriteLine(result.ProductName); // Original state: Chai

    result.ProductName = &quot;Transformer&quot;; // Updating property (field) is tracked.
    Console.WriteLine(result.ProductName); // Changed state: Transformer

    Product original = source.GetOriginalEntityState(result);
    Console.WriteLine(original.ProductName); // Original state: Chai
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice it is tracking the object state change, not object change:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Table&amp;lt;Product&amp;gt; source = database.Products;
    Product result = source.First();
    result = new Product() 
        { 
            ProductName = &quot;Transformer&quot; 
        }; // result now refer to an custom object not created by DataContext.

    // DataContext tracks change of query results created by itself, 
    // and does not know about the state of this offline object. 
    Product original = source.GetOriginalEntityState(result);
    // So original is null.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To track the change of an entity object not created by current DataContext (also called offline entity), this entity object is required to be explicitly attached to the current DataConetxt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Table&amp;lt;Product&amp;gt; source = database.Products;
    Product offline = new Product()
        {
            ProductName = &quot;Autobots&quot;
        }; // Offline object from custom code or another DataContext.

    Console.WriteLine(offline.ProductName); // Original state: Autobots

    source.Attach(offline);
    offline.ProductName = &quot;Decipticons&quot;;
    Console.WriteLine(offline.ProductName); // Updated state: Decipticons

    Product original = source.GetOriginalEntityState(offline);
    Console.WriteLine(original.ProductName); // Original state: Autobots
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Association change&lt;/h3&gt;
&lt;p&gt;The association is not tracked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Category category = database.Categories.Single(item =&amp;gt; item.CategoryID == 1);
    Console.WriteLine(category.Products.Count()); // 12.

    category.Products.Clear();
    Console.WriteLine(category.Products.Count()); // 0.

    Category original = database.Categories.GetOriginalEntityState(category);
    Console.WriteLine(original.Products.Count()); // 0 (Not original value 12).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but synchronized:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Category category = database.Categories.Single(item =&amp;gt; item.CategoryID == 1);
    Product product = category.Products[0];
    Console.WriteLine(
        &quot;Product: ProductID = {0}, CategoryID = {1}&quot;, 
        product.ProductID, // 1.
        product.CategoryID); // 1.

    // Deletes the association on Category object.
    category.Products.Clear();
    // Associated Product objects should be synchronized.

    product = database.Products.Single(item =&amp;gt; item.ProductID == 1);
    Console.WriteLine(
        &quot;Product: ProductID = {0}, CategoryID = {1}&quot;,
        product.ProductID, // 1.
        product.CategoryID); // null, becuase of category.Products.Clear().
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sine there is an association (foreign key) between Product and Category, when one side of the association is changed, the other side is also changed to ensure the consistency:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Category category = new Category(); // category.Products is empty.

    IQueryable&amp;lt;Product&amp;gt; productsOfCategory2 = database.Products.Where(
        item =&amp;gt; item.CategoryID == 2);

    // Updates the association on each Product object.
    foreach (Product item in productsOfCategory2)
    {
        item.Category = category;
    }
    // Associated Category object should be synchronized.

    foreach (Product item in category.Products)
    {
        Console.WriteLine(item.ProductName);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Change set&lt;/h3&gt;
&lt;p&gt;The tracked changes can be retrieved by DataContext.GetChangeSet():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Product product = database.Products.First();
    Category category = database.Categories.Single(item =&amp;gt; item.CategoryID == 5);

    // Changes state.
    product.UnitPrice++;
                
    // Changes association.
    category.Products.Add(product);

    ChangeSet changeSet = database.GetChangeSet();
    Console.WriteLine(&quot;{0} updated entitie(s):&quot;, changeSet.Updates.Count); // 1.
    foreach (object updated in changeSet.Updates)
    {
        Console.WriteLine(updated.GetType().Name); // Product.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here it looks two entities are updated, but actually one, because of the association.&lt;/p&gt;
&lt;h2&gt;Submit changes&lt;/h2&gt;
&lt;p&gt;After changes (create / update / delete) on entities / entity states / associations are made with the caution of object identity and change tracking, and association synchronization, these changed need to be submitted to the database to take effect by invoking the SubmitChanges() method on DataContext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;database.SubmitChanges();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is very simple.&lt;/p&gt;
&lt;h3&gt;INSERT&lt;/h3&gt;
&lt;p&gt;INSERT can be done by invoking DataContext.InsertOnsubmit() and DataContext.InsertAllOnsubmit().&lt;/p&gt;
&lt;h3&gt;Work with IDENTITY field&lt;/h3&gt;
&lt;p&gt;The most common scenarios for table primary key is IDENTITY and GUID.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_041BD433.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If the table has a IDENTITY primary key, SQL Server just ignores this field when inserting.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Category category = new Category() // CategoryID is default(int)
        {
            CategoryName = &quot;Transformers&quot;,
        };
    Product product = new Product() // ProductID is default(int)
        {
            ProductName = &quot;OptimusPrime&quot;
        };
    category.Products.Add(product);
    // Inserts category, as well as the associated product.
    database.Categories.InsertOnSubmit(category); 

    Console.WriteLine(category.CategoryID); // 0.
    Console.WriteLine(product.ProductID); // 0.

    database.SubmitChanges();

    Console.WriteLine(category.CategoryID); // 9.
    Console.WriteLine(product.ProductID); // 78.
    Console.WriteLine(product.CategoryID); // 9.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translated SQL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BEGIN TRANSACTION

-- Inserts category, ignoring provided CategoryID (0).
exec sp_executesql N&apos;INSERT INTO [dbo].[Categories]([CategoryName], [Description], [Picture])
VALUES (@p0, @p1, @p2)

SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]&apos;,N&apos;@p0 nvarchar(4000),@p1 ntext,@p2 image&apos;,@p0=N&apos;Transformers&apos;,@p1=NULL,@p2=NULL
-- Returns the last IDENTITY value(9) inserted into an IDENTITY column in the current scope.

-- Inserts product with the foreign key (the CategoryID(9) just generated), ignoring provided ProductID (0).
exec sp_executesql N&apos;INSERT INTO [dbo].[Products]([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)

SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]&apos;,N&apos;@p0 nvarchar(4000),@p1 int,@p2 int,@p3 nvarchar(4000),@p4 money,@p5 smallint,@p6 smallint,@p7 smallint,@p8 bit&apos;,@p0=N&apos;OptimusPrime&apos;,@p1=NULL,@p2=9,@p3=NULL,@p4=NULL,@p5=NULL,@p6=NULL,@p7=NULL,@p8=0
-- Returns the last IDENTITY value(78).

COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are several interesting things to notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first thing is, LINQ to SQL determines to first INSERT category, then product, because of the foreign key (product.CategoryID);&lt;/li&gt;
&lt;li&gt;When translating the SQL for inserting category, the value of CategoryID (0) provided by entity is ignored, because the CategoryID column has an IDENTITY primary key;&lt;/li&gt;
&lt;li&gt;After executing INSERT, the inserted record has a CategoryID value (9) generated by SQL Server, it is returned to LINQ to SQL by invoking SCOPE_IDENTITY();&lt;/li&gt;
&lt;li&gt;In LINQ to SQL, this CategoryID value is set back to category.CategoryID to ensure the consistency of between entity and record;&lt;/li&gt;
&lt;li&gt;This value is also provided to product.CategoryID, because there is an association (foreign key);&lt;/li&gt;
&lt;li&gt;By inserting category, the associated product is also inserted (with the CategoryID value just generated) to ensure the consistency of mapping;&lt;/li&gt;
&lt;li&gt;Similar with CategoryID, LINQ to SQL gets ProductID for product after INSERT executed;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This feature of synchronizing value back to entity is very useful. It is specified in the [Column] attribute of property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Column(Storage = &quot;_CategoryID&quot;, AutoSync = AutoSync.OnInsert, 
    DbType = &quot;Int NOT NULL IDENTITY&quot;, IsPrimaryKey = true, IsDbGenerated = true)]
public int CategoryID
{
    get
    {
        return this._CategoryID;
    }
    set
    {
        if ((this._CategoryID != value))
        {
            this.OnCategoryIDChanging(value);
            this.SendPropertyChanging();
            this._CategoryID = value;
            this.SendPropertyChanged(&quot;CategoryID&quot;);
            this.OnCategoryIDChanged();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it can be changed in the O/R designer:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_35E57BAF.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;UPDATE&lt;/h3&gt;
&lt;p&gt;Updating is straight foreword:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Product product = database.Products.First();
    product.UnitPrice++;
    database.SubmitChanges();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translated SQL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]

BEGIN TRANSACTION 

exec sp_executesql N&apos;UPDATE [dbo].[Products]
SET [UnitPrice] = @p9
WHERE ([ProductID] = @p0) AND ([ProductName] = @p1) AND ([SupplierID] = @p2) AND ([CategoryID] = @p3) AND ([QuantityPerUnit] = @p4) AND ([UnitPrice] = @p5) AND ([UnitsInStock] = @p6) AND ([UnitsOnOrder] = @p7) AND ([ReorderLevel] = @p8) AND (NOT ([Discontinued] = 1))&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 int,@p3 int,@p4 nvarchar(4000),@p5 money,@p6 smallint,@p7 smallint,@p8 smallint,@p9 money&apos;,@p0=1,@p1=N&apos;Chai&apos;,@p2=1,@p3=1,@p4=N&apos;10 boxes x 20 bags&apos;,@p5=$18.0000,@p6=39,@p7=0,@p8=10,@p9=$19.0000

COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take a look at the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Product product = database.Products.First();
    product.UnitPrice++; // State change is deferred. 
    product.UnitPrice—; // State change is deferred.

    // At this point, product’s current state is the same as original state.
    database.SubmitChanges(); // No change is submitted.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and guess what happens to database?&lt;/p&gt;
&lt;p&gt;Since the change is tracked, so when invoking SubmitChanges(), there is no state change requiring submitting, because the entity’s current state is the same as its original state. Here LINQ to SQL submit nothing to database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (1) [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]

BEGIN TRANSACTION 
-- No change is executed.
COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;DELETE&lt;/h3&gt;
&lt;p&gt;Similar with INSERT, DELETE can be implemented by DataContext.DeleteOnsubmit() and DataContext.DeleteAllOnsubmit().&lt;/p&gt;
&lt;p&gt;Just like fore mentioned, since all data change are deferred and tracked, when submitting all these change, order of performing these changes need to be figured out. Again, foreign key is very important for this order.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    database.Categories.DeleteAllOnSubmit(database.Categories.Where(
        item =&amp;gt; item.CategoryName == &quot;Transformers&quot;));
    database.Products.DeleteAllOnSubmit(database.Products.Where(
        item =&amp;gt; item.ProductName == &quot;OptimusPrime&quot;));
    database.SubmitChanges();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The C# code changes the data by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;first delete products,&lt;/li&gt;
&lt;li&gt;then delete categories&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But when executing SubmitChanges(), LINQ to SQL translates SQL to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;first DELETE products,&lt;/li&gt;
&lt;li&gt;then DELETE the categories&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;because there is a dependency (association in LINQ to SQL / foreign key in database) between those products and categories. So the transalted SQL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Retrieves categories. Actual result is one category.
exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[CategoryName] = @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;Transformers&apos;

-- Retrieves products. Actual result is one category.
exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] = @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;OptimusPrime&apos;

BEGIN TRANSACTION 

-- Deletes category first.
exec sp_executesql N&apos;DELETE FROM [dbo].[Products] WHERE ([ProductID] = @p0) AND ([ProductName] = @p1) AND ([SupplierID] IS NULL) AND ([CategoryID] = @p2) AND ([QuantityPerUnit] IS NULL) AND ([UnitPrice] IS NULL) AND ([UnitsInStock] IS NULL) AND ([UnitsOnOrder] IS NULL) AND ([ReorderLevel] IS NULL) AND (NOT ([Discontinued] = 1))&apos;,N&apos;@p0 int,@p1 nvarchar(4000),@p2 int&apos;,@p0=78,@p1=N&apos;OptimusPrime&apos;,@p2=9

-- Deletes product then.
exec sp_executesql N&apos;DELETE FROM [dbo].[Categories] WHERE ([CategoryID] = @p0) AND ([CategoryName] = @p1)&apos;,N&apos;@p0 int,@p1 nvarchar(4000)&apos;,@p0=9,@p1=N&apos;Transformers&apos;

COMMIT TRANSACTION
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is clear LINQ to SQL uses TRANSACTION to implement data changing. This is will be talked in detail in the next post.&lt;/p&gt;
&lt;h2&gt;Read-only DataContext&lt;/h2&gt;
&lt;p&gt;DataContext becomes read-only if tracking is disabled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;database.ObjectTrackingEnabled = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object identity is disabled. each query always create a new entity.&lt;/li&gt;
&lt;li&gt;State change will not tracked.&lt;/li&gt;
&lt;li&gt;Association change will not be synchronized.&lt;/li&gt;
&lt;li&gt;Invoking SubmitChanges() throws an InvalidOperationException, because it becomes impossible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Internally, ObjectTrackingEnabled is checked at the beginning of SubmitChanges():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!this.ObjectTrackingEnabled)
{
    throw new InvalidOperationException(
        &quot;Object tracking is not enabled for the current data context instance.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last thing is, ObjectTrackingEnabled must be set false before any query execution. Otherwise, after query execution, the tracking is already started and cannot be disabled.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (6) Working With Deferred Execution</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-6-working-with-deferred-execution/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-6-working-with-deferred-execution/</guid><description>\]</description><pubDate>Mon, 19 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Similar with LINQ to Objects, LINQ to SQL supports deferred execution when possible. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Category&amp;gt; source = database.Categories;

    // Query is deferred.
    IQueryable&amp;lt;Category&amp;gt; results = source.Where(category =&amp;gt; category.CategoryID &amp;lt; 5);

    // Foreaches the IQueryable&amp;lt;Category&amp;gt; object, which implements IEnumerable&amp;lt;Category&amp;gt;.
    // Query is starting translaion and execution.
    using (IEnumerator&amp;lt;Category&amp;gt; iterator = results.GetEnumerator())
    {
        // The data is pulled from SQL Server to memory.
        while (iterator.MoveNext()) // Iterats the data.
        {
            Category item = iterator.Current;
            Console.WriteLine(&quot;Category {0}: {1}&quot;, item.CategoryID, item.CategoryName);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The execution can be traced in SQL Server Profiler.&lt;/p&gt;
&lt;p&gt;When a query is impossible to be deferred, the eager execution is applied, like aggregation, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Category&amp;gt; source = database.Categories;

// It is impossible to defer the execution.
Category result = source.Single(category =&amp;gt; category.CategoryID == 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code results a single item from the source, which cannot be deferred.&lt;/p&gt;
&lt;h2&gt;Deferred execution and DataContext&lt;/h2&gt;
&lt;p&gt;Since LINQ to SQL queries work against Table&amp;lt;T&amp;gt;s on DataContext, DataContext affects the execution of queries a lot.&lt;/p&gt;
&lt;p&gt;While designing applications, the data access and UI code are usually separated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class DataAccess
{
    internal static IEnumerable&amp;lt;string&amp;gt; GetCategoryNames(params int[] ids)
    {
        using (NorthwindDataContext database = new NorthwindDataContext())
        {
            IQueryable&amp;lt;Category&amp;gt; source = database.Categories;
            return source.Where(category =&amp;gt; ids.Contains(category.CategoryID))
                         .Select(category =&amp;gt; category.CategoryName);
        }
    }
}

internal static class UI
{
    internal static void Print()
    {
        IEnumerable&amp;lt;string&amp;gt; names = DataAccess.GetCategoryNames(1, 2, 3);
        foreach (string name in names)
        {
            Console.WriteLine(name);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the LINQ to SQL data access code and UI interactive code are decoupled, which looks very nice. But invoking UI.Print() always throws an ObjectDisposedException:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cannot access a disposed object. Object name: &apos;DataContext accessed after Dispose.&apos;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is because, when DataAccess.GetCategoryNames() returns, the query is not executed yet, but the DataContext object within the method is disposed. Later, when iterating the names, trying to execute the query definitely fails because there is no DataContext available.&lt;/p&gt;
&lt;p&gt;Logically there are 2 ways to avoid this kind of problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;either always execute the query before DataContext object is disposed;&lt;/li&gt;
&lt;li&gt;or always the DataContext object is disposed after the query execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here the first way is the simplest:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;string&amp;gt; GetCategoryNames(params int[] ids)
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        IQueryable&amp;lt;Category&amp;gt; source = database.Categories;
        return source.Where(category =&amp;gt; ids.Contains(category.CategoryID))
                     .Select(category =&amp;gt; category.CategoryName)
                     .ToArray(); // Eager execution before disposing.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the LINQ to Objects query method ToArray() &lt;a href=&quot;/posts/understanding-linq-to-objects-7-query-methods-internals&quot;&gt;converts the cold IEnumerable&amp;lt;T&amp;gt; to a hot IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt;, so that the query is executed immediately.&lt;/p&gt;
&lt;p&gt;The other solutions will be explained in later posts.&lt;/p&gt;
&lt;h2&gt;Deferred execution and eager loading&lt;/h2&gt;
&lt;p&gt;I saw the following kind of design from some production code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class DataAccess
{
    internal static IQueryable&amp;lt;Category&amp;gt; GetCategories()
    {
        NorthwindDataContext database = new NorthwindDataContext();
        return database.Categories;
        // DataContext is not disposed
        // to make the returned IQueryable&amp;lt;Category&amp;gt; still available
        // outside the scope of this method.
    }
}

internal static class UI
{
    internal static void Print()
    {
        IQueryable&amp;lt;Category&amp;gt; categories = DataAccess.GetCategories();

        foreach (Category category in categories)
        // This foreach cause the query executed.
        // Now the data of categories are pulled from SQL Server to memory.
        {
            Console.WriteLine(
                &quot;Category {0}: {1}&quot;, 
                category.CategoryID, 
                category.CategoryName);
            
            // Eagerly loads the associated data through the foreign key.
            foreach (Product product in category.Products)
            // This foreach causes a new query executed through the association.
            // Now the data of products are pulled.
            {
                Console.WriteLine(
                    &quot;    Product {0}: {1}&quot;,
                    product.ProductID,
                    product.ProductName);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Invoking UI.Print() prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Category 1: Beverages Product 1: Chai Product 2: Chang Product 24: Guaraná Fantástica Product 34: Sasquatch Ale Product 35: Steeleye Stout Product 38: Côte de Blaye Product 39: Chartreuse verte Product 43: Ipoh Coffee Product 67: Laughing Lumberjack Lager Product 70: Outback Lager Product 75: Rhönbräu Klosterbier Product 76: Lakkalikööri Category 2: Condiments Product 3: Aniseed Syrup Product 4: Chef Anton&apos;s Cajun Seasoning Product 5: Chef Anton&apos;s Gumbo Mix Product 6: Grandma&apos;s Boysenberry Spread Product 8: Northwoods Cranberry Sauce Product 15: Genen Shouyu Product 44: Gula Malacca Product 61: Sirop d&apos;érable Product 63: Vegie-spread Product 65: Louisiana Fiery Hot Pepper Sauce Product 66: Louisiana Hot Spiced Okra Product 77: Original Frankfurter grüne Soße Category 3: Confections Product 16: Pavlova Product 19: Teatime Chocolate Biscuits Product 20: Sir Rodney&apos;s Marmalade Product 21: Sir Rodney&apos;s Scones Product 25: NuNuCa Nuß-Nougat-Creme&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which looks well. But profiling shows N + 1 translated SQLs, where N is the number of categories. This is so horrible:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Queries categories.
SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
FROM [dbo].[Categories] AS [t0]

-- Queries products of the first category through the association (foreign key).
exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=1

-- Queries products of the second category.
exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=2

-- ...

-- Queries products of the last category.
exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = @p0&apos;,N&apos;@p0 int&apos;,@p0=8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So improper usage of deferred execution also causes performance issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When DataAccess.GetCategories() returns, the execution of query (return database.Categories) is deferred;&lt;/li&gt;
&lt;li&gt;The outer foreach cause the query executed. But at this point LINQ to SQL cannot know products of each category are also expected to query through the association (foreign key);&lt;/li&gt;
&lt;li&gt;Each inner foreach causes one query executed for current category’s products.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One possible solution is, make up a LEFT JOIN query to retrieve all the data, and use LINQ to Objects to project the items to a Category collection:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    return database.Products
                   // Queries all needed data with one single LEFT JOIN.
                   .Select(product =&amp;gt; new
                        {
                            Product = new
                                {
                                    ProductID = product.ProductID,
                                    ProductName = product.ProductName
                                    // Other fields, if needed.
                                },
                            Category = new
                                {
                                    CategoryID = product.Category.CategoryID,
                                    CategoryName = product.Category.CategoryName
                                    // Other fields, if needed.
                                }
                        })
                   // Then goes to LINQ to Objects for projection.
                   .AsEnumerable() 
                   .GroupBy(item =&amp;gt; item.Category)
                   .Select(group =&amp;gt;
                        {
                            Category category = new Category()
                                {
                                    CategoryID = group.Key.CategoryID,
                                    CategoryName = group.Key.CategoryName
                                };
                            category.Products.AddRange(group.Select(item =&amp;gt; new Product()
                                {
                                    ProductID = item.Product.ProductID,
                                    ProductName = item.Product.ProductName
                                }));
                            return category;
                        })
                   .ToArray(); // Eager execution before disposing.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The translated SQL is a clean LEFT JOIN as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[ProductID], [t0].[ProductName], [t1].[CategoryID], [t1].[CategoryName]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN [dbo].[Categories] AS [t1] ON [t1].[CategoryID] = [t0].[CategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this kind of code is horribly noisy. For example, in the above LEFT JOIN query, when constructing the anonymous type its properties (fields) should be specified one by one. If 50 fields are needed to query, the coding will be crazy!&lt;/p&gt;
&lt;h3&gt;DataLoadOptions.LoadWith()&lt;/h3&gt;
&lt;p&gt;The easiest solution for this kind of eager loading is using DataLoadOptions and its LoadWith() method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static IEnumerable&amp;lt;Category&amp;gt; GetCategories()
{
    using (NorthwindDataContext database = new NorthwindDataContext())
    {
        DataLoadOptions options = new DataLoadOptions();
        options.LoadWith&amp;lt;Category&amp;gt;(category =&amp;gt; category.Products);
        database.LoadOptions = options;
        return database.Categories.ToArray(); // Eager execution before disposing. 
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After refactoring, the query execution is only translated to one single SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture], [t1].[ProductID], [t1].[ProductName], [t1].[SupplierID], [t1].[CategoryID] AS [CategoryID2], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued], (
    SELECT COUNT(*)
    FROM [dbo].[Products] AS [t2]
    WHERE [t2].[CategoryID] = [t0].[CategoryID]
    ) AS [value]
FROM [dbo].[Categories] AS [t0]
LEFT OUTER JOIN [dbo].[Products] AS [t1] ON [t1].[CategoryID] = [t0].[CategoryID]
ORDER BY [t0].[CategoryID], [t1].[ProductID]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;DataLoadOptions.AssociateWith()&lt;/h3&gt;
&lt;p&gt;There is another useful method on DataLoadOptions, AssociateWith(). It specifies further query conditions on the eager-loaded associated objects, like restriction, ordering, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    DataLoadOptions options = new DataLoadOptions();
    options.AssociateWith&amp;lt;Category&amp;gt;(category =&amp;gt; category.Products.Where(product =&amp;gt; product.UnitPrice &amp;lt; 10));
    options.LoadWith&amp;lt;Category&amp;gt;(category =&amp;gt; category.Products);
    database.LoadOptions = options;
    return database.Categories.ToArray(); // Eager execution before disposing. 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time the translated SQL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture], [t1].[ProductID], [t1].[ProductName], [t1].[SupplierID], [t1].[CategoryID] AS [CategoryID2], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued], (
    SELECT COUNT(*)
    FROM [dbo].[Products] AS [t2]
    WHERE ([t2].[UnitPrice] &amp;lt; @p0) AND ([t2].[CategoryID] = ([t0].[CategoryID]))
    ) AS [value]
FROM [dbo].[Categories] AS [t0]
LEFT OUTER JOIN [dbo].[Products] AS [t1] ON ([t1].[UnitPrice] &amp;lt; @p0) AND ([t1].[CategoryID] = ([t0].[CategoryID]))
ORDER BY [t0].[CategoryID], [t1].[ProductID]&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=10.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;DataContext.DeferredLoadingEnabled&lt;/h3&gt;
&lt;p&gt;As fore mentioned, deferred loading is enabled by default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When accessing one entity, its associated entities are not loaded.&lt;/li&gt;
&lt;li&gt;When accessing its associated entities, they are loaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    database.DeferredLoadingEnabled = true; // By default and not needed.
    Product product = database.Products.First(); // product.Category is not loaded.
    Console.WriteLine(product.Category.CategoryName); // product.Category is loaded.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be turned off by setting DataContext.DeferredLoadingEnabled to false:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    database.DeferredLoadingEnabled = false;
    Product product = database.Products.First();
    Console.WriteLine(product.Category.CategoryName); // NullReferenceException.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time when accessing product.Category, it will not be loaded so it is null.&lt;/p&gt;
&lt;p&gt;Please notice that, DataContext.DeferredLoadingEnabled will be affected by DataContext.ObjectTrackingEnabled, just as &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.deferredloadingenabled.aspx&quot;&gt;MSDN said&lt;/a&gt;, when DataContext.ObjectTrackingEnabled is false:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DeferredLoadingEnabled is ignored and inferred to be false.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Object tracking will be explained in the next post.&lt;/p&gt;
</content:encoded></item><item><title>Crazy Bug in Visual Studio 2010 RTM: Copy And Paste</title><link>https://dixin.github.io/posts/crazy-bug-in-visual-studio-2010-rtm-copy-and-paste/</link><guid isPermaLink="true">https://dixin.github.io/posts/crazy-bug-in-visual-studio-2010-rtm-copy-and-paste/</guid><description>The copy / paste functionality is very buggy in  Beta and RC. In Beta sometimes this even cause Visual Studio crash. Now after using RT</description><pubDate>Sun, 18 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The copy / paste functionality is very buggy in &lt;a href=&quot;http://www.microsoft.com/visualstudio/en-us&quot;&gt;Visual Studio 2010&lt;/a&gt; Beta and RC. In Beta sometimes this even cause Visual Studio crash. Now after using RTM for a week, I found the bug remains, and greatly affect the experience. I searched the Internet and found this &lt;a href=&quot;http://connect.microsoft.com/VisualStudio/feedback/details/533726/copy-paste-issue-in-vs-2010-rc&quot;&gt;comment from Microsoft&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We unfortunately weren&apos;t able to address this in time for VS 2010 RTM, but we now understand the issue and are investigating it for a VS 2010 service pack and the next major release of Visual Studio. … It&apos;s too soon to know exactly when this will be fixed, but we agree that it&apos;s a serious issue, and we are working on addressing it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Currently, when copy / paste do not work, the only solution is to close the file and reopen, and try to copy / paste again. But this does not always work. Sometimes I have to restart Visual Studio. Because I frequently copy code from Visual Studio and paste to &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_Live_Writer&quot;&gt;Windows Live Writer&lt;/a&gt; while blogging, this really drives me crazy!&lt;/p&gt;
&lt;p&gt;Update:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_2EDD14E5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Sometimes “Copy exception detail to the clipboard” does not work either.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (5) Remote And Local Method Call</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-5-remote-and-local-method-call/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-5-remote-and-local-method-call/</guid><description>\]</description><pubDate>Sun, 18 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Since LINQ to SQL is translating C# methods into SQL, all the C# methods are required to make sense in SQL.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb882670.aspx&quot;&gt;According to MSDN&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A local method call is one that is executed within the object model. A remote method call is one that LINQ to SQL translates to SQL and transmits to the database engine for execution.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As long as .NET method call can be recognized by LINQ to SQL, it is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;translated to SQL, and&lt;/li&gt;
&lt;li&gt;executed in SQL Server remotely.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Otherwise it is executed in CLR locally.&lt;/p&gt;
&lt;h2&gt;Remote method call&lt;/h2&gt;
&lt;p&gt;In the previous post, remote method calls are everywhere. In the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
var results = source.Where(product =&amp;gt; product.ReorderLevel &amp;gt; 20)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = string.Concat(&quot;@&quot;, product.ProductName),
                            UnitPrice = product.UnitPrice
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;method calls are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Property access: product.get_ReorderLevel&lt;/li&gt;
&lt;li&gt;Numeric comparison: &amp;gt;&lt;/li&gt;
&lt;li&gt;Method call: IEnumerable&amp;lt;Product&amp;gt;.Where()&lt;/li&gt;
&lt;li&gt;Property access: product.get_ProductName&lt;/li&gt;
&lt;li&gt;Method call: string.Concat()&lt;/li&gt;
&lt;li&gt;Property access: product.get_UnitPrice&lt;/li&gt;
&lt;li&gt;Constructor call: new AnonymousType()&lt;/li&gt;
&lt;li&gt;Method call: IEnumerable&amp;lt;Product&amp;gt;.Select()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of them can be recognized by LINQ to SQL, and they are translated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;product.get_ReorderLevel –&amp;gt; [dbo].[Products].[RecordLevel]&lt;/li&gt;
&lt;li&gt;&amp;gt; –&amp;gt; &amp;gt;&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;Product&amp;gt;.Where() –&amp;gt; WHERE&lt;/li&gt;
&lt;li&gt;product.get_ProductName –&amp;gt; [dbo].[Products].[ProductName]&lt;/li&gt;
&lt;li&gt;string.Concat() –&amp;gt; +&lt;/li&gt;
&lt;li&gt;product.get_UnitPrice –&amp;gt; [dbo].[Products].[UnitPrice]&lt;/li&gt;
&lt;li&gt;new AnonymousType(): AS [ProductName]&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;Product&amp;gt;.Select() –&amp;gt; SELECT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the final result is:&lt;/p&gt;
&lt;p&gt;exec sp_executesql N&apos;SELECT @p1 + [t0].[ProductName] AS [ProductName], [t0].[UnitPrice] FROM [dbo].[Products] AS [t0] WHERE [t0].[ReorderLevel] &amp;gt; @p0&apos;,N&apos;@p0 int,@p1 nvarchar(4000)&apos;,@p0=20,@p1=N&apos;@&apos;&lt;/p&gt;
&lt;p&gt;As expected, method calls are not executed in CLR but in SQL Server.&lt;/p&gt;
&lt;h2&gt;Local method call&lt;/h2&gt;
&lt;p&gt;The called methods above are call .NET built-in or BCL built-in, like numeric “&amp;gt;” comparison operator, property access, string.Concat(), etc. Now consider this custom .NET method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static bool IsExpensive(decimal? price)
{
    return price &amp;lt; 10;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if it is used in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; IsExpensive(product.UnitPrice));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This custom method cannot be recognized and translated into SQL, so a NotSupportedException is thrown at runtime:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Method &apos;Boolean IsExpensive(System.Nullable`1[System.Decimal])&apos; has no supported translation to SQL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But it can work as a local method call in Select():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Where(product =&amp;gt; product.ReorderLevel &amp;gt; 20)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            IsExpensive = IsExpensive(product.UnitPrice)
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IsExpensive() cannot be recognized as a remote method call, and will not translated to SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice] AS [price]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ReorderLevel] &amp;gt; @p0&apos;,N&apos;@p0 int&apos;,@p0=20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After executing in SQL Server, CLR gets the results, and sends the results to the IsExpensive() method. Here IsExpensive() executes in CLR locally.&lt;/p&gt;
&lt;h2&gt;Remote method recognition&lt;/h2&gt;
&lt;p&gt;As in the previous post, LINQ to SQL is so smart that many .NET methods can be translated to SQL, like IEnumerable&amp;lt;T&amp;gt;.Contains() is translated to IN, product.CategoryID != null is translated to IS NOT NULL, etc. The only thing need to do is to make sure the method call can make sense in SQL, so that it is able to be recognized and translated.&lt;/p&gt;
&lt;p&gt;One example is the string equation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Category&amp;gt; source = database.Categories;
Category result = source.Single(category =&amp;gt; category.CategoryName == &quot;Beverage&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usually, for string equation, the following looks better:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Category&amp;gt; source = database.Categories;
Category result = source.Single(category =&amp;gt; 
    category.CategoryName.Equals(&quot;Beverages&quot;, StringComparison.Ordinal));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this throws an NotSupportedException:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Method &apos;Boolean Equals(System.String, System.StringComparison)&apos; has no supported translation to SQL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reason is, the StringComparison.Ordinal has no corresponding implementation in SQL so it cannot be translated. Please remember: the above lambda expression category =&amp;gt; category.CategoryName == &quot;Beverage&quot; is &lt;a href=&quot;/posts/understanding-linq-to-sql-3-expression-tree&quot;&gt;constructing an expression tree data structure&lt;/a&gt;, not &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;C# executable code&lt;/a&gt;. So it is both unnecessary and incorrect to change it into category.CategoryName.Equals(&quot;Beverages&quot;, StringComparison.Ordinal).&lt;/p&gt;
&lt;p&gt;Another overload of methods can make sense in SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Category result = source.Single(category =&amp;gt; 
    category.CategoryName.Equals(&quot;Beverages&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So it can also be recognized and translated.&lt;/p&gt;
&lt;p&gt;Another example is, string.ToUpper() can be translated (because there is UPPER() in SQL), but string.ToUpper(CultureInfo) and string.ToUpperInvariant() cannot.&lt;/p&gt;
&lt;p&gt;Generally speaking, these following method calls are supported:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normal arithmetic and comparison operators&lt;/li&gt;
&lt;li&gt;Part of methods of string, which do not involve .NET stuff like CultureInfo or StringComparison, etc.
&lt;ul&gt;
&lt;li&gt;CompareTo()&lt;/li&gt;
&lt;li&gt;Concat()&lt;/li&gt;
&lt;li&gt;Contains()&lt;/li&gt;
&lt;li&gt;EndsWith()&lt;/li&gt;
&lt;li&gt;Equals()&lt;/li&gt;
&lt;li&gt;IndexOf()&lt;/li&gt;
&lt;li&gt;Insert()&lt;/li&gt;
&lt;li&gt;LastIndexOf()&lt;/li&gt;
&lt;li&gt;Length&lt;/li&gt;
&lt;li&gt;PadLeft()&lt;/li&gt;
&lt;li&gt;PadRight()&lt;/li&gt;
&lt;li&gt;Remove()&lt;/li&gt;
&lt;li&gt;Replace()&lt;/li&gt;
&lt;li&gt;StartsWith()&lt;/li&gt;
&lt;li&gt;String() constructor&lt;/li&gt;
&lt;li&gt;Substring()&lt;/li&gt;
&lt;li&gt;ToLower()&lt;/li&gt;
&lt;li&gt;ToUpper()&lt;/li&gt;
&lt;li&gt;Trim()&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Most of methods of Math&lt;/li&gt;
&lt;li&gt;Part of methods of Convert, which converts among:
&lt;ul&gt;
&lt;li&gt;bool&lt;/li&gt;
&lt;li&gt;byte&lt;/li&gt;
&lt;li&gt;short&lt;/li&gt;
&lt;li&gt;int&lt;/li&gt;
&lt;li&gt;long&lt;/li&gt;
&lt;li&gt;float&lt;/li&gt;
&lt;li&gt;double&lt;/li&gt;
&lt;li&gt;decimal&lt;/li&gt;
&lt;li&gt;char&lt;/li&gt;
&lt;li&gt;string&lt;/li&gt;
&lt;li&gt;DateTime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Part of methods of DateTime&lt;/li&gt;
&lt;li&gt;Part of methods of TimeSpan&lt;/li&gt;
&lt;li&gt;All methods of SqlMethods&lt;/li&gt;
&lt;li&gt;Part of methods of IEnumerable&amp;lt;T&amp;gt;, like Contians(), etc.&lt;/li&gt;
&lt;li&gt;Part of methods of IQueryable&amp;lt;T&amp;gt;, listed in the beginning of &lt;a href=&quot;/posts/understanding-linq-to-sql-6-working-with-deferred-execution&quot;&gt;previous post&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Here is &lt;a href=&quot;http://msdn.microsoft.com/hi-in/library/bb425822(en-us).aspx#linqtosql_topic36&quot;&gt;a great article from MSDN&lt;/a&gt; talking about the translation support in detail. But it is a little outdated. For example, it says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Shift operators: &amp;lt;&amp;lt; and &amp;gt;&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;is supported, but actually not in RTM.&lt;/p&gt;
</content:encoded></item><item><title>Blog Code Font Change: From Courier New to Consolas</title><link>https://dixin.github.io/posts/blog-code-font-change-from-courier-new-to-consolas/</link><guid isPermaLink="true">https://dixin.github.io/posts/blog-code-font-change-from-courier-new-to-consolas/</guid><description>is an excellent  (non-proportional) [typeface](http://en.wikipedia.org/wik</description><pubDate>Fri, 16 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Courier_New#Courier_New&quot;&gt;Courier New&lt;/a&gt; is an excellent &lt;a href=&quot;http://en.wikipedia.org/wiki/Monospaced_font&quot;&gt;monospaced&lt;/a&gt; (non-proportional) &lt;a href=&quot;http://en.wikipedia.org/wiki/Typeface&quot;&gt;typeface&lt;/a&gt; introduced with &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_3.1&quot;&gt;Windows 3.1&lt;/a&gt;. As a UI designer, I cannot tell how many year I have worked with Courier New. As the release of Visual Studio 2010 and the new MSDN, &lt;a href=&quot;http://en.wikipedia.org/wiki/Consolas&quot;&gt;Consolas&lt;/a&gt; becomes the default font of code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd233250(VS.100).aspx&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_72F9F951.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The latest code font definition of MSDN is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;font-family: Consolas, Courier, monospace;
font-size: 0.83em;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Consolas&quot;&gt;According to Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consolas is a monospaced (non-proportional) typeface, designed by &lt;a href=&quot;http://en.wikipedia.org/wiki/Lucas_de_Groot&quot;&gt;Lucas de Groot&lt;/a&gt;. It is a part of a new suite of fonts that take advantage of Microsoft&apos;s &lt;a href=&quot;http://en.wikipedia.org/wiki/ClearType&quot;&gt;ClearType&lt;/a&gt; font rendering technology.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Although it is introduced with &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_vista&quot;&gt;Windows Vista&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Office_2007&quot;&gt;Office 2007&lt;/a&gt;, Consolas first came into my eyes later along with dev10. After playing with it for over 2 years, I think it is time to say goodbye to Courier New and catch up with the UI design of Visual Studio and MSDN.&lt;/p&gt;
&lt;p&gt;For me, Courier New is as beautiful as Consolas; Consolas rocks mainly because of &lt;a href=&quot;http://en.wikipedia.org/wiki/ClearType&quot;&gt;ClearType&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (4) Data Retrieving Via Query Methods</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-4-data-retrieving-via-query-methods/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-4-data-retrieving-via-query-methods/</guid><description>\]</description><pubDate>Wed, 14 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;After understanding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;object model generating from SQL Server schema&lt;/li&gt;
&lt;li&gt;query method chaining on IQueryable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;SQL are translated from expression tree, which is required by IQueryable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;now it is time to take a deeper look at the detail of SQL Server data &lt;a href=&quot;http://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD&lt;/a&gt; manipulation. This post will focus on how to retrieve (SELECT) data from SQL Server via LINQ to SQL.&lt;/p&gt;
&lt;p&gt;Since IQueryable&amp;lt;T&amp;gt; has extension methods which looks similar with IEnumerable&amp;lt;T&amp;gt;, queries in &lt;a href=&quot;/posts/understanding-linq-to-objects-3-query-methods&quot;&gt;this LINQ to Objects post&lt;/a&gt; can be applied in LINQ to SQL. Here the word “looks” is used because IQueryable&amp;lt;T&amp;gt;’s and IEnumerable&amp;lt;T&amp;gt;’s extension methods have the same name, and they all take lambda expressions as parameters; the difference is, the lambda expression syntactic sugar is compiled into anonymous method when token by IEnumerable&amp;lt;T&amp;gt;’s extension methods, and it is compiled into expression tree when token by IEnumerable&amp;lt;T&amp;gt;’s extension methods.&lt;/p&gt;
&lt;p&gt;The previous post has listed all the IQueryable&amp;lt;T&amp;gt; standard query methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restriction: Where, OfType&lt;/li&gt;
&lt;li&gt;Projection: Select, SelectMany&lt;/li&gt;
&lt;li&gt;Ordering: OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&lt;/li&gt;
&lt;li&gt;Join: Join, GroupJoin&lt;/li&gt;
&lt;li&gt;Grouping: GroupBy&lt;/li&gt;
&lt;li&gt;Set: Zip, Distinct, Union, Intersect, Except&lt;/li&gt;
&lt;li&gt;Aggregation: Aggregate, Count, LongCount, Sum, Min, Max, Average&lt;/li&gt;
&lt;li&gt;Partitioning: Take, Skip, TakeWhile, SkipWhile&lt;/li&gt;
&lt;li&gt;Cancatening: Concat&lt;/li&gt;
&lt;li&gt;Conversion: Cast&lt;/li&gt;
&lt;li&gt;Equality: SequenceEqual&lt;/li&gt;
&lt;li&gt;Elements: First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAt, ElementAtOrDefault, DefaultIfEmpty&lt;/li&gt;
&lt;li&gt;Qualifiers: Any, All, Contains&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The underlined methods are not supported in LINQ to SQL, because SQL does not have the corresponding implementation.&lt;/p&gt;
&lt;p&gt;Again, please remember IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;. All IEnumerable&amp;lt;T&amp;gt; standard query methods remain on IQueryable&amp;lt;T&amp;gt;, like ToArray().&lt;/p&gt;
&lt;h2&gt;Restriction (WHERE, AND, OR, NOT, LIKE, IN, IS, NULL)&lt;/h2&gt;
&lt;p&gt;Take the Products table as example:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_25B63014.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Where() query method is used to filter the items in the IQueryable&amp;lt;T&amp;gt; collection:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100);

    foreach (Product item in results)
    {
        Console.WriteLine(&quot;{0}: {1}&quot;, item.ProductName, item.UnitPrice);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thüringer Rostbratwurst: 123.7900 Côte de Blaye: 263.5000&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The above query will be translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[UnitPrice] &amp;gt; @p0&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=100.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be traced by &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms181091.aspx&quot;&gt;SQL Server Profiler&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The other overload of Where():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IQueryable&amp;lt;TSource&amp;gt; source, 
    Expression&amp;lt;Func&amp;lt;TSource, int, bool&amp;gt;&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is not supported in LINQ to SQL.&lt;/p&gt;
&lt;h3&gt;AND / OR&lt;/h3&gt;
&lt;p&gt;&amp;amp;&amp;amp; / || can be used in Where():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(
    product =&amp;gt; product.UnitPrice &amp;lt; 20 || product.UnitPrice &amp;gt; 90);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE ([t0].[UnitPrice] &amp;lt; @p0) OR ([t0].[UnitPrice] &amp;gt; @p1)&apos;,N&apos;@p0 decimal(33,4),@p1 decimal(33,4)&apos;,@p0=20.0000,@p1=90.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or Where() can be invoked for multiple times:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.UnitPrice &amp;lt; 20)
                                    .Where(product =&amp;gt; product.ReorderLevel &amp;gt; 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE ([t0].[ReorderLevel] &amp;gt; @p0) AND ([t0].[UnitPrice] &amp;lt; @p1)&apos;,N&apos;@p0 int,@p1 decimal(33,4)&apos;,@p0=10,@p1=20.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;LIKE&lt;/h3&gt;
&lt;p&gt;.NET API can be used for constructing query. Typically, when working with character data, string.StartsWith() can be used&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.ProductName.StartsWith(&quot;B&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;string.StartsWith(“x”) is recognized and translated to LIKE N’x%’:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] LIKE @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;B%&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same for string.EndsWith(“y”) and string.Contains(“z”). They are translated LIKE N’%y’ and LIKE N’%z%’.&lt;/p&gt;
&lt;p&gt;Generally, SqlMethods.Like() can be used for LIKE operation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(
    product =&amp;gt; SqlMethods.Like(product.ProductName, &quot;%st%&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be recognized and translated to LIKE.&lt;/p&gt;
&lt;p&gt;For the detail of wildcards, please check &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms179859.aspx&quot;&gt;MSDN&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;IN&lt;/h3&gt;
&lt;p&gt;When IEnumerable&amp;lt;T&amp;gt;.Contains() is used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;string&amp;gt; names = new string[] { &quot;Chai&quot;, &quot;Chang&quot;, &quot;Tofu&quot; };
IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; names.Contains(product.ProductName));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it is translated to IN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] IN (@p0, @p1, @p2)&apos;,N&apos;@p0 nvarchar(4000),@p1 nvarchar(4000),@p2 nvarchar(4000)&apos;,@p0=N&apos;Chai&apos;,@p1=N&apos;Chang&apos;,@p2=N&apos;Tofu&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;IS / NOT / NULL&lt;/h3&gt;
&lt;p&gt;The following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.CategoryID != null);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] IS NOT NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The predicate “product.CategoryID != null” is not executed in CLR but translated to SQL and remotely executed in SQL Server.&lt;/p&gt;
&lt;h2&gt;Projection (SELECT, CASE)&lt;/h2&gt;
&lt;p&gt;If querying all fields is not necessary, Select() can be used to specify the fields:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    var results = source.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100)
                        .Select(product =&amp;gt; new 
                            { 
                                product.ProductName, 
                                product.UnitPrice 
                            });

    foreach (var item in results)
    {
        Console.WriteLine(&quot;{0}: {1}&quot;, item.ProductName, item.UnitPrice);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here &lt;a href=&quot;/posts/understanding-csharp-3-0-features-3-type-inference&quot;&gt;var&lt;/a&gt; must be used because &lt;a href=&quot;/posts/understanding-csharp-3-0-features-4-anonymous-type&quot;&gt;anonymous type&lt;/a&gt; is created.&lt;/p&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[UnitPrice] &amp;gt; @p0&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=100.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only explicitly required fields (ProductName and UnitPrice) are queried.&lt;/p&gt;
&lt;h3&gt;Explicitly construct entity&lt;/h3&gt;
&lt;p&gt;In the above sample, constructing an object of anonymous type looks unnecessary. It should be Ok to use the Product type directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100)
                                    .Select(product =&amp;gt; new Product()
                                        {
                                            ProductName = product.ProductName,
                                            UnitPrice = product.UnitPrice
                                        });

foreach (Product item in results)
{
    Console.WriteLine(&quot;{0}: {1}&quot;, item.ProductName, item.UnitPrice);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this code throws an NotSupportedException at runtime:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Explicit construction of entity type &apos;Product&apos; in query is not allowed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Explicit construction of entity type is not allowed after .NET 3.5 Beta2. &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/1ce25da3-44c6-407d-8395-4c146930004b&quot;&gt;According to Microsoft&lt;/a&gt;, this is because:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This check was added because it was supposed to be there from the beginning and was missing. Constructing entity instances manually as a projection pollutes the cache with potentially malformed objects, leading to confused programmers and lots of bug reports for us. In addition, it is ambiguous whether projected entities should be in the cache or changed tracked at all. The usage pattern for entities is that they are created outside of queries and inserted into tables via the DataContext and then later retrieved via queries, never created by queries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To explicitly construct entity, there are several ways to work around. One way is construct object of anonymous type, then use LINQ to Objects to construct entity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Product&amp;gt; results = source.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100)
                                     .Select(product =&amp;gt; new
                                         {
                                             product.ProductName,
                                             product.UnitPrice
                                         })
                                     .AsEnumerable() // Converts to IEnumerable&amp;lt;T&amp;gt;
                                     .Select(item =&amp;gt; new Product() 
                                         { 
                                             ProductName = item.ProductName, 
                                             UnitPrice = item.UnitPrice
                                         }); // Uses IEnumerable&amp;lt;T&amp;gt;.Select()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CASE&lt;/h3&gt;
&lt;p&gt;The following query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Where(product =&amp;gt; product.ReorderLevel &amp;gt; 20)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            IsExpensive = product.UnitPrice &amp;lt; 10
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to CASE:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], 
    (CASE 
        WHEN [t0].[UnitPrice] &amp;lt; @p1 THEN 1
        WHEN NOT ([t0].[UnitPrice] &amp;lt; @p1) THEN 0
        ELSE NULL
     END) AS [IsExpensive]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ReorderLevel] &amp;gt; @p0&apos;,N&apos;@p0 int,@p1 decimal(33,4)&apos;,@p0=20,@p1=10.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Ordering (ORDER BY, ASC, DESC)&lt;/h2&gt;
&lt;p&gt;The query methods OrderBy(), OrderByDescending(), ThenBy(), ThenByDescending() work similarly with LINQ to Objects.&lt;/p&gt;
&lt;p&gt;The following OrderBy(A).OrderBy(B):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Where(product =&amp;gt; product.ReorderLevel &amp;gt; 20)
                    .OrderBy(product =&amp;gt; product.ProductName)
                    .OrderBy(product =&amp;gt; product.UnitPrice)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to ORDER BY B, A:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ReorderLevel] &amp;gt; @p0
ORDER BY [t0].[UnitPrice], [t0].[ProductName]&apos;,N&apos;@p0 int&apos;,@p0=20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While OrderBy(A).ThenBy(B):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Where(product =&amp;gt; product.ReorderLevel &amp;gt; 20)
                    .OrderBy(product =&amp;gt; product.ProductName)
                    .ThenBy(product =&amp;gt; product.UnitPrice)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to ORDER BY A, B:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ReorderLevel] &amp;gt; @p0
ORDER BY [t0].[ProductName], [t0].[UnitPrice]&apos;,N&apos;@p0 int&apos;,@p0=20
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Join (JOIN, INNER JOIN, OUTER JOIN, CROSS JOIN)&lt;/h2&gt;
&lt;p&gt;LINQ to SQL can implement all kinds of SQL join. But this is not easy enough. In the following samples, query methods and query expressions will be both provided for contrast.&lt;/p&gt;
&lt;h3&gt;Natural join&lt;/h3&gt;
&lt;p&gt;Natural JOIN is typically applied in one-to-one scenarios. But &lt;a href=&quot;http://database.blogs.webucator.com/2010/03/31/why-sql-server-doesnt-support-natural-join-syntax/&quot;&gt;natural join is not supported&lt;/a&gt; by either SQL Server or LINQ to SQL. Natural join should be implemented via INNER JOIN.&lt;/p&gt;
&lt;p&gt;The interesting thing is, there are some posts talking about SQL Server natural join, like &lt;a href=&quot;http://www.c-sharpcorner.com/UploadFile/raj1979/SqlJoins10012008164642PM/SqlJoins.aspx&quot;&gt;this one&lt;/a&gt; from &lt;a href=&quot;http://www.c-sharpcorner.com/&quot;&gt;C# Corner&lt;/a&gt;, and &lt;a href=&quot;http://blogs.msdn.com/vbteam/archive/2007/12/31/converting-sql-to-linq-part-6-joins-bill-horst.aspx&quot;&gt;this one&lt;/a&gt; from &lt;a href=&quot;http://blogs.msdn.com/vbteam/&quot;&gt;Microsoft VB team&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;INNER JOIN&lt;/h3&gt;
&lt;p&gt;INNER JOIN is very typically applied one-to-many scenarios (One-to-one natural join can be considered as a special one-to-many scenario, where “many” consists of “one”.).&lt;/p&gt;
&lt;p&gt;Take the Products table and Categories table as an example. This is the model of both tables, and the foreign key is mapped as an association:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_42DBD81E.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Similar with LINQ to Objects queries, INNER JOIN can be implemented by Join().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; outer = database.Products;
IQueryable&amp;lt;Category&amp;gt; inner = database.Categories;
var results = outer.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100)
                   .Join(
                        inner,
                        product =&amp;gt; product.CategoryID,
                        category =&amp;gt; category.CategoryID,
                        (product, category) =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice,
                            CategoryName = category.CategoryName
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated into:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice], [t1].[CategoryName]
FROM [dbo].[Products] AS [t0]
INNER JOIN [dbo].[Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])
WHERE [t0].[UnitPrice] &amp;gt; @p0&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=100.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, in C#, Where() is before Join(). This is Ok for translating to SQL, where Join() should come before Where().&lt;/p&gt;
&lt;p&gt;The above query can be implemented by query expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from product in outer
              where product.UnitPrice &amp;gt; 100
              join category in inner on product.CategoryID equals category.CategoryID
              select new
                  {
                      ProductName = product.ProductName,
                      UnitPrice = product.UnitPrice,
                      CategoryName = category.CategoryName
                  };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which looks a little easier.&lt;/p&gt;
&lt;p&gt;INNER JOIN can also be done by SelectMany():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Category&amp;gt; source = database.Categories;
var results = source.Where(category =&amp;gt; category.CategoryName == &quot;Beverages&quot;)
                    .SelectMany(
                        category =&amp;gt; category.Products,
                        (category, product) =&amp;gt; new 
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice,
                            CategoryName = category.CategoryName
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t1].[ProductName], [t1].[UnitPrice], [t0].[CategoryName]
FROM [dbo].[Categories] AS [t0], [dbo].[Products] AS [t1]
WHERE ([t0].[CategoryName] = @p0) AND ([t1].[CategoryID] = [t0].[CategoryID])&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;Beverages&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;OUTER JOIN&lt;/h3&gt;
&lt;p&gt;OUTER JOIN is also typically applied one-to-many scenarios. OUTER JOIN can be implemented by GroupJoin().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; outer = database.Products;
    IQueryable&amp;lt;Category&amp;gt; inner = database.Categories;
    var results = outer.Where(product =&amp;gt; product.UnitPrice &amp;lt; 10)
                       .OrderBy(product =&amp;gt; product.ProductName)
                       .GroupJoin(
                            inner,
                            product =&amp;gt; product.CategoryID,
                            category =&amp;gt; category.CategoryID,
                            (product, categories) =&amp;gt; new
                                {
                                    Product = product,
                                    Categories = categories
                                })
                       .SelectMany( // Flattens the data after outer join.
                            item =&amp;gt; item.Categories.DefaultIfEmpty(),
                            (item, category) =&amp;gt; new
                                {
                                    ProductName = item.Product.ProductName,
                                    CategoryName = category.CategoryName
                                });

    foreach (var item in results)
    {
        Console.WriteLine(&quot;{0} &amp;lt;- {1}&quot;, item.ProductName, item.CategoryName);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t1].[CategoryName] AS [CategoryName]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN [dbo].[Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])
WHERE [t0].[UnitPrice] &amp;lt; @p0
ORDER BY [t0].[ProductName]&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=10.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Filo Mix &amp;lt;- Grains/Cereals Geitost &amp;lt;- Dairy Products Guaraná Fantástica &amp;lt;- Beverages Jack&apos;s New England Clam Chowder &amp;lt;- Seafood Konbu &amp;lt;- Seafood Rhönbräu Klosterbier &amp;lt;- Beverages Rogede sild &amp;lt;- Seafood Teatime Chocolate Biscuits &amp;lt;- Confections Tourtière &amp;lt;- Meat/Poultry Tunnbröd &amp;lt;- Grains/Cereals Zaanse koeken &amp;lt;- Confections&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This looks a little tough. Query expression is a little easier:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from product in outer
              where product.UnitPrice &amp;lt; 10
              orderby product.ProductName
              join category in inner on product.CategoryID equals category.CategoryID
              into categories
              from item in categories.DefaultIfEmpty()
              select new
                  {
                      ProductName = product.ProductName,
                      CategoryName = item.CategoryName
                  };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the second from. 2 “from”s will be compiled into SelectMany().&lt;/p&gt;
&lt;p&gt;For consistency, it is recommended to always use query methods.&lt;/p&gt;
&lt;p&gt;One thing need to pay attention is, do not forget the DefaultIfEmpty() invocation, because one Product object is OUTER JOINed with a group of Category objects, and that group might be null. Without DefaultIfEmpty(), OUTER JOIN cannot be applied, and the query will be translated into INNER JOIN.&lt;/p&gt;
&lt;h3&gt;Association (OUTER JOIN)&lt;/h3&gt;
&lt;p&gt;A simpler implementation of OUTER JOIN is using the table association. For example,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
var results = source.Where(product =&amp;gt; product.UnitPrice &amp;lt; 10)
                    .OrderBy(product =&amp;gt; product.ProductName)
                    .Select(product =&amp;gt; new 
                        { 
                            ProductName = product.ProductName, 
                            CategoryName = product.Category.CategoryName 
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is translated to the same SQL above.&lt;/p&gt;
&lt;p&gt;Here is another sample using table association to implement OUTER JOIN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
var results = source.Where(product =&amp;gt; product.Category.CategoryName == &quot;Beverages&quot;)
                    .Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN [dbo].[Categories] AS [t1] ON [t1].[CategoryID] = [t0].[CategoryID]
WHERE [t1].[CategoryName] = @p0&apos;,N&apos;@p0 nvarchar(4000)&apos;,@p0=N&apos;Beverages&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CROSS JOIN&lt;/h3&gt;
&lt;p&gt;A typical usage of CROSS JOIN is in many-to-many scenarios. Many-to-many scenarios usually involves 3 table: 2 tables are associated related through a relationship table. For example, below Employees table and Territories table’s relationship are represented by the EmployeeTerritories relationship table:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_26EAA326.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CROSS JOIN can be implemented by SelectMany(). The following query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Category&amp;gt; source = database.Employees;
var results = source.SelectMany(
    employee =&amp;gt; employee.EmployeeTerritories,
    (employee, employeeTerritory) =&amp;gt; new
        {
            FirstName = employee.FirstName,
            LastName = employee.LastName,
            TerritoryDescription = employeeTerritory.Territory.TerritoryDescription
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is equal to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from employee in source
              from territory in employee.EmployeeTerritories
              select new
              {
                  FirstName = employee.FirstName,
                  LastName = employee.LastName,
                  TerritoryDescription = territory.Territory.TerritoryDescription
              };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;because, as fore mentioned, 2 “from”s will be compiled into SelectMany().&lt;/p&gt;
&lt;p&gt;So it is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t0].[FirstName], [t0].[LastName], [t2].[TerritoryDescription]
FROM [dbo].[Employees] AS [t0]
CROSS JOIN [dbo].[EmployeeTerritories] AS [t1]
INNER JOIN [dbo].[Territories] AS [t2] ON [t2].[TerritoryID] = [t1].[TerritoryID]
WHERE [t1].[EmployeeID] = [t0].[EmployeeID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Firstly Employees table CROSS JOINs the relationship table EmployeeTerritories, then INNER JOINs the Territories.&lt;/p&gt;
&lt;h3&gt;Self JOIN&lt;/h3&gt;
&lt;p&gt;Self JOIN is somehow more interesting. Take a look at the above Employees table:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_58959AAE.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There is a foreign key within this table, from EmployeeID to ReportTo:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_7A31C37F.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is the model of Employee table:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_134D1DB8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The above foreign key is mapped as an association:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_424F598F.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So a self JOIN can be performed on Employees table and Employees table through this foreign key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Employee&amp;gt; source = database.Employees;
var results = source.SelectMany(
    manager =&amp;gt; manager.Employees, 
    (manager, employee) =&amp;gt; new
        {
            Manager = manager.FirstName + &quot; &quot; + manager.LastName,
            Employee = employee.FirstName + &quot; &quot; + employee.LastName
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT ([t0].[FirstName] + @p0) + [t0].[LastName] AS [Manager], ([t1].[FirstName] + @p1) + [t1].[LastName] AS [Employee]
FROM [dbo].[Employees] AS [t0], [dbo].[Employees] AS [t1]
WHERE [t1].[ReportsTo] = [t0].[EmployeeID]&apos;,N&apos;@p0 nvarchar(4000),@p1 nvarchar(4000)&apos;,@p0=N&apos; &apos;,@p1=N&apos; &apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Grouping and aggregation (GROUP BY / aggregate functions / HAVING )&lt;/h2&gt;
&lt;p&gt;In SQL, GROUP BY works with aggregation. However, the concept of grouping is different in LINQ to SQL, and aggregating is optional. LINQ to SQL grouping just reorganize items into IGrouping&amp;lt;Tkey, TElement&amp;gt;s, which is the same as LINQ to Objects grouping:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IGrouping&amp;lt;out TKey, out TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, 
                                                         IEnumerable
    {
        TKey Key { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Grouping can be implemented by GroupBy():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    IQueryable&amp;lt;IGrouping&amp;lt;string, string&amp;gt;&amp;gt; groups = source.GroupBy(
        product =&amp;gt; product.ProductName.Substring(0, 1), // For TKey of IGrouping.
        product =&amp;gt; product.ProductName); // For TElement of IGrouping.

    foreach (IGrouping&amp;lt;string, string&amp;gt; group in groups)
    {
        Console.Write(&quot;Group {0}: &quot;, group.Key);
        foreach (string productName in group) // Iterates items in the group.
        {
            Console.Write(&quot;[{0}] &quot;, productName);
        }

        Console.WriteLine();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Group A: [Alice Mutton] [Aniseed Syrup] Group B: [Boston Crab Meat] Group C: [Camembert Pierrot] [Carnarvon Tigers] [Chai] [Chang] [Chartreuse verte] [Chef Anton&apos;s Cajun Seasoning] [Chef Anton&apos;s Gumbo Mix] [Chocolade] [Côte de Blaye] Group E: [Escargots de Bourgogne] Group F: [Filo Mix] [Flotemysost] Group G: [Geitost] [Genen Shouyu] [Gnocchi di nonna Alice] [Gorgonzola Telino] [Grandma&apos;s Boysenberry Spread] [Gravad lax] [Guaraná Fantástica] [Gudbrandsdalsost] [Gula Malacca] [Gumbär Gummibärchen] [Gustaf&apos;s Knäckebröd] Group I: [Ikura] [Inlagd Sill] [Ipoh Coffee] Group J: [Jack&apos;s New England Clam Chowder] Group K: [Konbu] Group L: [Lakkalikööri] [Laughing Lumberjack Lager] [Longlife Tofu] [Louisiana Fiery Hot Pepper Sauce] [Louisiana Hot Spiced Okra] Group M: [Manjimup Dried Apples] [Mascarpone Fabioli] [Maxilaku] [Mishi Kobe Niku] [Mozzarella di Giovanni] Group N: [Nord-Ost Matjeshering] [Northwoods Cranberry Sauce] [NuNuCa Nuß-Nougat-Creme] Group O: [Original Frankfurter grüne Soße] [Outback Lager] Group P: [Pâté chinois] [Pavlova] [Perth Pasties] Group Q: [Queso Cabrales] [Queso Manchego La Pastora] Group R: [Raclette Courdavault] [Ravioli Angelo] [Rhönbräu Klosterbier] [Röd Kaviar] [Rogede sild] [Rössle Sauerkraut] Group S: [Sasquatch Ale] [Schoggi Schokolade] [Scottish Longbreads] [Singaporean Hokkien Fried Mee] [Sir Rodney&apos;s Marmalade] [Sir Rodney&apos;s Scones] [Sirop d&apos;érable] [Spegesild] [Steeleye Stout] Group T: [Tarte au sucre] [Teatime Chocolate Biscuits] [Thüringer Rostbratwurst] [Tofu] [Tourtière] [Tunnbröd] Group U: [Uncle Bob&apos;s Organic Dried Pears] Group V: [Valkoinen suklaa] [Vegie-spread] Group W: [Wimmers gute Semmelknödel] Group Z: [Zaanse koeken]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This query produces a simple grouping in LINQ to SQL. Obviously, there is no aggregating, so there is no way to translate the query into GROUP BY. Here LINQ to SQL does the 2 things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;queries all keys (CategoryIDs), each key stands for one group;&lt;/li&gt;
&lt;li&gt;for each key (CategoryID), queries the items Products table, and put the queried items into an IGrouping&amp;lt;Tkey, TElement&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the final query result is a collection of groups.&lt;/p&gt;
&lt;p&gt;This is translated to the following tens of SQL queries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Queries all keys, each key stands for a group
exec sp_executesql N&apos;SELECT [t1].[value] AS [Key]
FROM (
    SELECT SUBSTRING([t0].[ProductName], @p0 + 1, @p1) AS [value]
    FROM [dbo].[Products] AS [t0]
    ) AS [t1]
GROUP BY [t1].[value]&apos;,N&apos;@p0 int,@p1 int&apos;,@p0=0,@p1=1

-- Queries the items for the first key &apos;A&apos;.
exec sp_executesql N&apos;SELECT [t0].[ProductName]
FROM [dbo].[Products] AS [t0]
WHERE ((@x1 IS NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NULL)) OR ((@x1 IS NOT NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NOT NULL) AND (@x1 = SUBSTRING([t0].[ProductName], @p0 + 1, @p1)))&apos;,N&apos;@p0 int,@p1 int,@x1 nvarchar(4000)&apos;,@p0=0,@p1=1,@x1=N&apos;A&apos;

-- Queries the items for the second key &apos;B&apos;.
exec sp_executesql N&apos;SELECT [t0].[ProductName]
FROM [dbo].[Products] AS [t0]
WHERE ((@x1 IS NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NULL)) OR ((@x1 IS NOT NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NOT NULL) AND (@x1 = SUBSTRING([t0].[ProductName], @p0 + 1, @p1)))&apos;,N&apos;@p0 int,@p1 int,@x1 nvarchar(4000)&apos;,@p0=0,@p1=1,@x1=N&apos;B&apos;

-- ...

-- Queries the items for the last key &apos;Z&apos;.
exec sp_executesql N&apos;SELECT [t0].[ProductName]
FROM [dbo].[Products] AS [t0]
WHERE ((@x1 IS NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NULL)) OR ((@x1 IS NOT NULL) AND (SUBSTRING([t0].[ProductName], @p0 + 1, @p1) IS NOT NULL) AND (@x1 = SUBSTRING([t0].[ProductName], @p0 + 1, @p1)))&apos;,N&apos;@p0 int,@p1 int,@x1 nvarchar(4000)&apos;,@p0=0,@p1=1,@x1=N&apos;Z&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GROUP BY / aggregate functions&lt;/h3&gt;
&lt;p&gt;When &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms173454.aspx&quot;&gt;aggregate function&lt;/a&gt; is provided in grouping, it is able to translate the query to GROUP BY. Take COUNT as example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    IQueryable&amp;lt;Product&amp;gt; source = database.Products;
    var groups = source.GroupBy(
        // The key of each group.
        product =&amp;gt; product.CategoryID,

        // Count() aggregates items of each group into one single value.
        (key, products) =&amp;gt; new 
            { 
                Key = key, 
                Count = products.Count() 
            });

    foreach (var group in groups)
    {
        Console.WriteLine(&quot;Category {0}: {1} Products&quot;, group.Key, group.Count);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT COUNT(*) AS [Count], [t0].[CategoryID] AS [Key]
FROM [dbo].[Products] AS [t0]
GROUP BY [t0].[CategoryID]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Category 1: 12 Products Category 2: 12 Products Category 3: 13 Products Category 4: 10 Products Category 5: 7 Products Category 6: 6 Products Category 7: 5 Products Category 8: 12 Products&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;HAVING&lt;/h3&gt;
&lt;p&gt;When filtering a GROUP BY:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var groups = source.GroupBy(
                        product =&amp;gt; product.CategoryID,
                        (key, products) =&amp;gt; new 
                            { 
                                Key = key, 
                                Count = products.Count() 
                            })
                   .Where(group =&amp;gt; group.Count &amp;gt; 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to a WHERE query, which wraps the GROUP BY query inside:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t1].[CategoryID] AS [Key], [t1].[value] AS [Count]
FROM (
    SELECT COUNT(*) AS [value], [t0].[CategoryID]
    FROM [dbo].[Products] AS [t0]
    GROUP BY [t0].[CategoryID]
    ) AS [t1]
WHERE [t1].[value] &amp;gt; @p0&apos;,N&apos;@p0 int&apos;,@p0=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which works the same as HAVING:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT COUNT(*) AS value, CategoryID
FROM Products AS t0
GROUP BY CategoryID
HAVING (COUNT(*) &amp;gt; 10)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a lot of interesting posts on the Internet talking about translating LINQ to SQL queries into HAVING, like &lt;a href=&quot;http://blogs.msdn.com/vbteam/archive/2007/12/18/converting-sql-to-linq-part-5-group-by-and-having-bill-horst.aspx&quot;&gt;this one&lt;/a&gt; from &lt;a href=&quot;http://blogs.msdn.com/vbteam/default.aspx&quot;&gt;Microsoft VB team&lt;/a&gt;, &lt;a href=&quot;http://weblogs.asp.net/vikram/archive/2009/09/17/linq-having-clause-and-group-by-with-condition.aspx&quot;&gt;this one&lt;/a&gt;, &lt;a href=&quot;http://www.aspfree.com/c/a/.NET/Grouping-and-Aggregating-When-Querying-LINQ-to-SQL/4/&quot;&gt;this one&lt;/a&gt;, and &lt;a href=&quot;http://www.aspfree.com/c/a/.NET/Grouping-and-Aggregating-When-Querying-LINQ-to-SQL/4/&quot;&gt;this one&lt;/a&gt;, etc. Actually, none of the queries they provided is translated to HAVING.&lt;/p&gt;
&lt;h2&gt;Set (DISTINCT / UNION / EXISTS)&lt;/h2&gt;
&lt;p&gt;In the 5 set query method of IQueryable&amp;lt;T&amp;gt;, Zip() is not supported in LINQ to SQL. The other 4 works.&lt;/p&gt;
&lt;h3&gt;DISTINCT&lt;/h3&gt;
&lt;p&gt;DISTINCT can be implemented by invoking Distinct() query method. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
IQueryable&amp;lt;int?&amp;gt; results = source.Where(product =&amp;gt; product.UnitPrice &amp;gt; 100)
                                    .Select(product =&amp;gt; product.CategoryID)
                                    .Distinct();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT DISTINCT [t0].[CategoryID]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[UnitPrice] &amp;gt; @p0&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=100.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;UNION&lt;/h3&gt;
&lt;p&gt;UNION can be implemented by Union(). Please notice UNION includes a DISTINCT calculation in SQL and so that the same in LINQ to SQL. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Supplier&amp;gt; source = database.Suppliers;
IQueryable&amp;lt;Order&amp;gt; source2 = database.Orders;

Console.WriteLine(source.Count()); // 29

Console.WriteLine(source2.Count()); // 830

IQueryable&amp;lt;string&amp;gt; results = source.Select(supplier =&amp;gt; supplier.City)
                                   .Union(source2.Select(order =&amp;gt; order.ShipCity));
Console.WriteLine(results.Count()); // 94
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT COUNT(*) AS [value]
FROM [dbo].[Suppliers] AS [t0]

SELECT COUNT(*) AS [value]
FROM [dbo].[Orders] AS [t0]

SELECT COUNT(*) AS [value]
FROM (
    SELECT [t0].[City]
    FROM [dbo].[Suppliers] AS [t0]
    UNION
    SELECT [t1].[ShipCity]
    FROM [dbo].[Orders] AS [t1]
    ) AS [t2]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;EXISTS&lt;/h3&gt;
&lt;p&gt;EXISTS can be implemented by Intersect().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Customer&amp;gt; source = database.Customers;
IQueryable&amp;lt;Supplier&amp;gt; source2 = database.Suppliers;
IQueryable&amp;lt;string&amp;gt; results = source.Select(customer =&amp;gt; customer.CompanyName)
                                    .Intersect(source2.Select(
                                        supplier =&amp;gt; supplier.CompanyName));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT DISTINCT [t0].[CompanyName]
FROM [dbo].[Customers] AS [t0]
WHERE EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Suppliers] AS [t1]
    WHERE [t0].[CompanyName] = [t1].[CompanyName]
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;NOT EXISTS&lt;/h3&gt;
&lt;p&gt;Except() is opposite of Intersect().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;string&amp;gt; results = source.Select(customer =&amp;gt; customer.CompanyName)
                                    .Except(source2.Select(
                                        supplier =&amp;gt; supplier.CompanyName));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT DISTINCT [t0].[CompanyName]
FROM [dbo].[Customers] AS [t0]
WHERE NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Suppliers] AS [t1]
    WHERE [t0].[CompanyName] = [t1].[CompanyName]
    ))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Partitioning (TOP / ROW_NUMBER() / BETWEEN AND)&lt;/h2&gt;
&lt;p&gt;The partitioning is very simple via LINQ to SQL.&lt;/p&gt;
&lt;h3&gt;TOP&lt;/h3&gt;
&lt;p&gt;The following code queries the most expensive 10 products:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
var results = source.Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        })
                    .OrderByDescending(item =&amp;gt; item.UnitPrice)
                    .Take(10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT TOP (10) [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
ORDER BY [t0].[UnitPrice] DESC
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ROW_NUMBER()&lt;/h3&gt;
&lt;p&gt;The Skip() is implemented by generating an extra ROW_NUMBER field. The following query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        })
                    .OrderByDescending(item =&amp;gt; item.UnitPrice)
                    .Skip(10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t1].[ProductName], [t1].[UnitPrice]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[UnitPrice] DESC) AS [ROW_NUMBER], [t0].[ProductName], [t0].[UnitPrice]
    FROM [dbo].[Products] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] &amp;gt; @p0
ORDER BY [t1].[ROW_NUMBER]&apos;,N&apos;@p0 int&apos;,@p0=10
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;BETWEEN AND&lt;/h3&gt;
&lt;p&gt;Skip().Take() immediately implements pagination:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Select(product =&amp;gt; new
                        {
                            ProductName = product.ProductName,
                            UnitPrice = product.UnitPrice
                        })
                    .OrderByDescending(item =&amp;gt; item.UnitPrice)
                    .Skip(20).Take(10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT [t1].[ProductName], [t1].[UnitPrice]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[UnitPrice] DESC) AS [ROW_NUMBER], [t0].[ProductName], [t0].[UnitPrice]
    FROM [dbo].[Products] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]&apos;,N&apos;@p0 int,@p1 int&apos;,@p0=20,@p1=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A Page() method is implemented in another post: &lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Concatenation (UNION ALL)&lt;/h2&gt;
&lt;p&gt;There is only one concatenation query method, Concat().&lt;/p&gt;
&lt;h3&gt;UNION ALL&lt;/h3&gt;
&lt;p&gt;The UNION ALL can be implemented by Concate().&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Customer&amp;gt; source = database.Customers;
IQueryable&amp;lt;Supplier&amp;gt; source2 = database.Suppliers;
IQueryable&amp;lt;string&amp;gt; results = source.Select(customer =&amp;gt; customer.CompanyName)
                                   .Concat(source2.Select(
                                       supplier =&amp;gt; supplier.CompanyName));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [t2].[CompanyName]
FROM (
    SELECT [t0].[CompanyName]
    FROM [dbo].[Customers] AS [t0]
    UNION ALL
    SELECT [t1].[CompanyName]
    FROM [dbo].[Suppliers] AS [t1]
    ) AS [t2]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Qualifiers (CASE / EXISTS)&lt;/h2&gt;
&lt;p&gt;The qualifiers are all translated to CASE and EXISTS.&lt;/p&gt;
&lt;h3&gt;CASE / EXISTS&lt;/h3&gt;
&lt;p&gt;This is an All() example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products;
bool result = source.All(product =&amp;gt; product.UnitPrice &amp;lt; 300);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    (CASE 
        WHEN NOT (EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[Products] AS [t1]
            WHERE (
                (CASE 
                    WHEN [t1].[UnitPrice] &amp;lt; @p0 THEN 1
                    ELSE 0
                 END)) = 0
            )) THEN 1
        WHEN NOT NOT (EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[Products] AS [t1]
            WHERE (
                (CASE 
                    WHEN [t1].[UnitPrice] &amp;lt; @p0 THEN 1
                    ELSE 0
                 END)) = 0
            )) THEN 0
        ELSE NULL
     END) AS [value]&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=300.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is an Any() example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool result = source.Any(product =&amp;gt; product.UnitPrice &amp;lt; 300);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this one is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    (CASE 
        WHEN EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[Products] AS [t0]
            WHERE [t0].[UnitPrice] &amp;lt; @p0
            ) THEN 1
        ELSE 0
     END) AS [value]&apos;,N&apos;@p0 decimal(33,4)&apos;,@p0=300.0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other overload of Any()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool result = source.Any();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    (CASE 
        WHEN EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[Products] AS [t0]
            ) THEN 1
        ELSE 0
     END) AS [value]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And Contains():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool result = source.Select(product=&amp;gt;product.ProductID).Contains(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is translated to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec sp_executesql N&apos;SELECT 
    (CASE 
        WHEN EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[Products] AS [t0]
            WHERE [t0].[ProductID] = @p0
            ) THEN 1
        ELSE 0
     END) AS [value]&apos;,N&apos;@p0 int&apos;,@p0=1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Other queries&lt;/h2&gt;
&lt;p&gt;The other queries, OfType() and Cast() are not covered in detail. Because they are more like LINQ to Objects calculation when translated to SQL.&lt;/p&gt;
</content:encoded></item><item><title>Playing with the CPU Usage Curve</title><link>https://dixin.github.io/posts/playing-with-the-cpu-usage-curve/</link><guid isPermaLink="true">https://dixin.github.io/posts/playing-with-the-cpu-usage-curve/</guid><description>In the book “”, which talks about Microsoft interview questions, there is a interesting section: Control the CPU curve of [Windows Task Manag</description><pubDate>Sun, 11 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the book “&lt;a href=&quot;http://www.china-pub.com/38070&quot;&gt;The Beauty Of Programming&lt;/a&gt;”, which talks about Microsoft interview questions, there is a interesting section: Control the CPU curve of &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_Task_Manager&quot;&gt;Windows Task Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_4837AD31.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The above image is from the book.&lt;/p&gt;
&lt;p&gt;Nowadays, when someone buys a mainstream CPU, it should be dual core by default. &lt;a href=&quot;http://www.dell.com/us/en/home/notebooks/laptop-alienware-m17x/pd.aspx?refid=laptop-alienware-m17x&amp;amp;cs=19&amp;amp;s=dhs&quot;&gt;My laptop&lt;/a&gt; has a quad core &lt;a href=&quot;http://processorfinder.intel.com/details.aspx?sSpec=SLGEJ&quot;&gt;Q9000&lt;/a&gt; CPU.&lt;/p&gt;
&lt;p&gt;Control the CPU curve in a multi-core CPU by make a thread spin / sleep is different from solo core CPU. For example, the spin a thread cause 100% CPU usage on solo core CPU, but cause 50% CPU usage in a dual core CPU.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_506BD2C8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Thread affinity&lt;/h2&gt;
&lt;p&gt;On a multi-core CPU, Windows shares time-slice from a random core to the thread. This AssignCurrentThreadInCpu() method is defined to help assign a thread to a specified CPU:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class NativeMethods
{
    public static void AssignCurrentThreadInCpu(int cpuIndex)
    {
        SetThreadAffinityMask(GetCurrentThread(), new IntPtr(1 &amp;lt;&amp;lt; cpuIndex));
    }

    [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Unicode)]
    internal static extern IntPtr SetThreadAffinityMask(
        IntPtr hThread,
        IntPtr dwThreadAffinityMask);

    [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Unicode)]
    internal static extern IntPtr GetCurrentThread();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Draw curve on specified CPU&lt;/h2&gt;
&lt;p&gt;This reusable method is used to draw CPU curve:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void DrawCpu(
    int timePerPeriod,
    int timePerFrame, Func&amp;lt;int, int, double&amp;gt; getCpuUsage)
{
    if (timePerFrame &amp;lt;= 0)
    {
        throw new ArgumentOutOfRangeException(&quot;timePerPeriod&quot;);
    }

    if (timePerFrame &amp;lt;= 0)
    {
        throw new ArgumentOutOfRangeException(&quot;timePerFrame&quot;);
    }

    int frameCountPerPeriod = timePerPeriod / timePerFrame;
    if (frameCountPerPeriod &amp;lt; 1)
    {
        throw new InvalidOperationException();
    }

    while (true)
    {
        for (int frameIndex = 0; frameIndex &amp;lt; frameCountPerPeriod; frameIndex++)
        {
            // If the target CPU usage is 70%,
            double cpuUsage = getCpuUsage(frameIndex, frameCountPerPeriod);
            if (cpuUsage &amp;lt; 0 || cpuUsage &amp;gt; 1)
            {
                throw new InvalidOperationException();
            }

            // the thread spins for 70% of the time,
            double busyTimePerFrame = timePerFrame * cpuUsage;
            double busyStartTime = Environment.TickCount;
            while (Environment.TickCount - busyStartTime &amp;lt;= busyTimePerFrame)
            {
            }

            // and sleeps for the rest 30% of time.
            int idleTimePerFrame = (int)(timePerFrame - busyTimePerFrame);
            Thread.Sleep(idleTimePerFrame);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It takes an Func&amp;lt;int, int, double&amp;gt; parameter (x, y) =&amp;gt; z to calculate that, in one period, at the xth frame of the total y frames, the cpu usage should be z.&lt;/p&gt;
&lt;p&gt;Now it is ready to draw a specific curve on a specific CPU:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static void Main()
{
    Thread thread0 = new Thread(() =&amp;gt;
    {
        NativeMethods.AssignCurrentThreadInCpu(0);
        DrawCpu(
            20 * 1000, // One period is 20 seconds.
            500, // One frame takes 0.5 seconds.
            (index, count) =&amp;gt; // Calculates the CPU usage.
                Math.Sin((2 * Math.PI) * ((double)index / count)) / 2 + 0.5);
    });
    Thread thread1 = new Thread(() =&amp;gt;
    {
        NativeMethods.AssignCurrentThreadInCpu(1);
        DrawCpu(20 * 1000, 500, (index, count) =&amp;gt; 0.5);
    });
    Thread thread2 = new Thread(() =&amp;gt;
    {
        NativeMethods.AssignCurrentThreadInCpu(2);
        DrawCpu(
            20 * 1000, 
            500,
            (index, count) =&amp;gt; (double)index / (count - 1));
    });
    Thread thread3 = new Thread(() =&amp;gt;
    {
        NativeMethods.AssignCurrentThreadInCpu(3);
        DrawCpu(
            20 * 1000, 
            500,
            (index, count) =&amp;gt; index &amp;lt; count / 2 ? 0 : 1);
    });
    
    thread0.Start();
    thread1.Start();
    thread2.Start();
    thread3.Start();

    Console.Read(); // Exits.
    thread0.Abort();
    thread1.Abort();
    thread2.Abort();
    thread3.Abort();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the above code draws the following curves in Task Manager:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_1BEB0080.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This solution has an flaw that, it assumes one managed thread runs on one Windows thread. This solution is not 100% stable because a managed thread can also run on a fiber.&lt;/p&gt;
</content:encoded></item><item><title>The Volume In Windows Media Center</title><link>https://dixin.github.io/posts/the-volume-in-windows-media-center/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-volume-in-windows-media-center/</guid><description>I developed a tool for  in 2008 in , and I got a very cool Windows Media Center remote controller. Sin</description><pubDate>Sun, 11 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I developed a tool for &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_Media_Center&quot;&gt;Windows Media Center&lt;/a&gt; in 2008 in &lt;a href=&quot;/posts/default&quot;&gt;Redmond&lt;/a&gt;, and I got a very cool Windows Media Center remote controller. Since then I became a fun of it. Windows Media Center + remote controller makes my &lt;a href=&quot;http://en.wikipedia.org/wiki/Alienware&quot;&gt;Alienware&lt;/a&gt; &lt;a href=&quot;http://www.dell.com/us/en/home/notebooks/laptop-alienware-m17x/pd.aspx?refid=laptop-alienware-m17x&amp;amp;cs=19&amp;amp;s=dhs&quot;&gt;M17x&lt;/a&gt; into a powerful &lt;a href=&quot;http://en.wikipedia.org/wiki/Home_cinema&quot;&gt;home theatre&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_2105FA6F.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The volume control feature might cause a usability issue because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it is synchronized with Windows volume;&lt;/li&gt;
&lt;li&gt;its degrees are inconsistent with Windows. In Windows, the full volume is 100, while in Windows Media Center it is 50.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_3623DA4A.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So consider the following scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User need to remember: when seeing 50 in Windows volume, it means half of full volume, while 50 means full volume in Windows Media Center;&lt;/li&gt;
&lt;li&gt;When user change Windows volume into X, the Windows Media Center volume is synchronized and displays the value X / 2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am wondering why it is necessary to design like this?&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (3) Expression Tree</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-3-expression-tree/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-3-expression-tree/</guid><description>\]</description><pubDate>Tue, 06 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;In LINQ to Objects, lamda expressions are used everywhere as anonymous method, like Where():&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;while in LINQ to SQL, mostly lambda expressions are used as expression tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Anonymous method vs. expression tree&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;previous post&lt;/a&gt; explained that the same lambda expression (like “number =&amp;gt; number &amp;gt; 0&quot;) can be compiled into anonymous method, or expression tree. When invoking the second Where() above, if a lambda expression is passed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products; // Products table of Northwind database.
// Queryable.Where() is choosed by compiler.
IQueryable&amp;lt;Product&amp;gt; products = source.Where(
    product =&amp;gt; product.Category.CategoryName == &quot;Beverages&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;obviously it is compiled into an expression tree.&lt;/p&gt;
&lt;h2&gt;Expression tree for LINQ to SQL&lt;/h2&gt;
&lt;p&gt;Why expression tree is needed in LINQ to SQL? To understand this, check LINQ to Objects first. LINQ to Objects query methods always require anonymous method. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
    this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
{
    foreach (TSource item in source)
    {
        if (predicate(item))
        {
            yield return item;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a Func&amp;lt;TSource, bool&amp;gt; anonymous method is passed in, it can be applied on each TSource item of the data source, and returns a bool value indicating this item should be yielded (true) or should be dropped (false).&lt;/p&gt;
&lt;p&gt;However, if such a method is passed to LINQ to SQL query method, it cannot mean anything for SQL Server. A .NET method (a bunch of IL code) cannot directly work on any data item stored in SQL Server database. Instead, domain-specified code, T-SQL, are required to manipulate data in SQL Server.&lt;/p&gt;
&lt;p&gt;How about passing a expression tree? This &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;previous post&lt;/a&gt; explained that expression tree is a abstract syntax tree representing the structure of some C# code, so it is able to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;traverse the tree to get the represented algorithm (like predicting whether the data item is greater than a constant 0, etc.),&lt;/li&gt;
&lt;li&gt;then translate the algorithm into some SQL-domain-specific operation, like a T-SQL query statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So this is the power of C# lambda expression:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It can be C# anonymous method, which is able to work on .NET data, like in LINQ to Objects scenarios;&lt;/li&gt;
&lt;li&gt;It can be expression tree, representing the structure of C# code, which is able to traversed, understood, and translated into another domain-specific code:
&lt;ul&gt;
&lt;li&gt;In LINQ to SQL, the expression trees are translated to specific T-SQL code, which work on SQL data;&lt;/li&gt;
&lt;li&gt;In LINQ to Wikipedia, the expression trees are translated to specific HTTP request of a specific Web service URI, which work on Wikipedia data;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is why expression tree is required in LINQ to SQL, and all the other scenarios of using LINQ query against non-.NET data.&lt;/p&gt;
&lt;h2&gt;Translate expression tree to T-SQL code&lt;/h2&gt;
&lt;p&gt;How to write LINQ to SQL queries? How does LINQ to SQL queries implemented? &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;This post&lt;/a&gt; has explained how to traverse and translate the following simple expression trees with basic arithmetical calculations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infixExpression =
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By modify the traverse code and translate code a little bit, it can be easily translated to T-SQL and executed in SQL Server.&lt;/p&gt;
&lt;p&gt;In T-SQL, arithmetical calculations are infix expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class InorderVisitor : SimpleExpressionVisitor&amp;lt;char&amp;gt;
{
    public InorderVisitor(LambdaExpression expression)
        : base(expression)
    {
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitAdd(BinaryExpression add)
    {
        return this.VisitBinary(add, &quot;+&quot;); // (left + right)
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitConstant(ConstantExpression constant)
    {
        return constant.Value.ToString();
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitDivide(BinaryExpression divide)
    {
        return this.VisitBinary(divide, &quot;/&quot;); // (left / right)
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitMultiply(BinaryExpression multiply)
    {
        return this.VisitBinary(multiply, &quot;*&quot;); // (left * right)
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitParameter(ParameterExpression parameter)
    {
        // parameterName -&amp;gt; @parameterName
        return string.Format(CultureInfo.InvariantCulture, &quot;@{0}&quot;, parameter.Name);
    }

    protected override IEnumerable&amp;lt;char&amp;gt; VisitSubtract(BinaryExpression subtract)
    {
        return this.VisitBinary(subtract, &quot;-&quot;); // (left - right)
    }

    private IEnumerable&amp;lt;char&amp;gt; VisitBinary(BinaryExpression binary, string infix)
    {
        return string.Format(
            CultureInfo.InvariantCulture,
            &quot;({0} {1} {2})&quot;, // (left infix right)
            this.VisitNode(binary.Left),
            infix,
            this.VisitNode(binary.Right));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above inorder traversing just replaces parameterName with @parameterName, which is required by SQL Server.&lt;/p&gt;
&lt;p&gt;Now emit a method to open the SQL connection, execute translated T-SQL, and return the result from SQL Server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SqlTranslator&amp;lt;TDelegate&amp;gt; : SimpleExpressionTranslator&amp;lt;TDelegate, char&amp;gt;
    where TDelegate : class
{
    private string _connection;

    public SqlTranslator(Expression&amp;lt;TDelegate&amp;gt; expression, string connection)
        : base(expression, () =&amp;gt; new InorderVisitor(expression))
    {
        this._connection = connection;
    }

    protected override void Emit(ILGenerator ilGenerator)
    {
        // Dictionary&amp;lt;string, double&amp;gt; dictionary = new Dictionary&amp;lt;string, double&amp;gt;();
        ilGenerator.DeclareLocal(typeof(Dictionary&amp;lt;string, double&amp;gt;));
        ilGenerator.Emit(
            OpCodes.Newobj,
            typeof(Dictionary&amp;lt;string, double&amp;gt;).GetConstructor(new Type[0]));
        ilGenerator.Emit(OpCodes.Stloc_0);

        for (int i = 0; i &amp;lt; this._expression.Parameters.Count; i++)
        {
            // dictionary.Add(&quot;@&quot; + this._expression.Parameters[i].Name, args[i]);
            ilGenerator.Emit(OpCodes.Ldloc_0);
            ilGenerator.Emit(
                OpCodes.Ldstr, 
                string.Format(
                    CultureInfo.InvariantCulture, 
                    &quot;@{0}&quot;, this._expression.Parameters[i].Name));
            ilGenerator.Emit(OpCodes.Ldarg_S, i);
            ilGenerator.Emit(
                OpCodes.Callvirt,
                typeof(Dictionary&amp;lt;string, double&amp;gt;).GetMethod(
                    &quot;Add&quot;, 
                    new Type[] { typeof(string), typeof(double) }));
        }

        // SqlTranslator&amp;lt;TDelegate&amp;gt;.Query(connection, sql, dictionary);
        ilGenerator.Emit(OpCodes.Ldstr, this._connection);
        ilGenerator.Emit(
            OpCodes.Ldstr, 
            string.Format(
                CultureInfo.InvariantCulture, 
                &quot;SELECT {0}&quot;, this._visitor.VisitBody()));
        ilGenerator.Emit(OpCodes.Ldloc_0);
        ilGenerator.Emit(
            OpCodes.Call,
            this.GetType().GetMethod(
                &quot;Query&quot;, 
                BindingFlags.Static | BindingFlags.NonPublic, 
                null, 
                new Type[] { typeof(string), typeof(string), 
                    typeof(IEnumerable&amp;lt;KeyValuePair&amp;lt;string, double&amp;gt;&amp;gt;) }, 
                null));

        // Returns the result.
        ilGenerator.Emit(OpCodes.Ret);
    }

    internal static double Query(
        string connection, 
        string sql, 
        IEnumerable&amp;lt;KeyValuePair&amp;lt;string, double&amp;gt;&amp;gt; parameters)
    {
        using (SqlConnection sqlConnection = new SqlConnection(connection))
        using (SqlCommand command = new SqlCommand(sql, sqlConnection))
        {
            sqlConnection.Open();
            foreach (KeyValuePair&amp;lt;string, double&amp;gt; parameter in parameters)
            {
                command.Parameters.AddWithValue(parameter.Key, parameter.Value);
            }

            return (double)command.ExecuteScalar();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is ready to rock:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infixExpression =
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

SqlTranslator&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; sqlTranslator =
    new SqlTranslator&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt;(
        infixExpression,
        @&quot;Data Source=localhost;Integrated Security=True&quot;);
Func&amp;lt;double, double, double, double, double, double&amp;gt; sqlQueryMethod = 
    sqlTranslator.GetExecutor();
double sqlResult = sqlQueryMethod(1, 2, 3, 4, 5);
Console.WriteLine(sqlResult); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the SQL Server profiler is tracing, it shows this T-SQL executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EXEC sp_executesql N&apos;SELECT (((@a + @b) - ((@c * @d) / 2)) + (@e * 3))&apos;, N&apos;@a float, @b float, @c float, @d float, @e float&apos;, @a = 1, @b = 2, @c = 3, @d = 4, @e = 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, please notice what happened is: some program written by C# is easily translated into another domain-specific language (T-SQL), which executes in that specific domain (SQL Server), and returns result to C# code.&lt;/p&gt;
&lt;h2&gt;Expression tree types&lt;/h2&gt;
&lt;p&gt;The following extension method DerivedIn() for System.Type uses LINQ to Objects to query derived types in specified assemblies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class TypeExtensions
{
    public static IEnumerable&amp;lt;Type&amp;gt; DerivedIn(this Type type, params string[] assemblyStrings)
    {
        if (type == null)
        {
            throw new ArgumentNullException(&quot;type&quot;);
        }

        if (assemblyStrings == null || assemblyStrings.Length &amp;lt; 1)
        {
            throw new ArgumentNullException(&quot;assemblyStrings&quot;);
        }

        return type.DerivedIn(assemblyStrings.Select(
            assemblyString =&amp;gt; Assembly.Load(assemblyString)).ToArray());
    }

    public static IEnumerable&amp;lt;Type&amp;gt; DerivedIn(this Type type, params Assembly[] assemblies)
    {
        if (type == null)
        {
            throw new ArgumentNullException(&quot;type&quot;);
        }

        if (assemblies == null || assemblies.Length &amp;lt; 1)
        {
            throw new ArgumentNullException(&quot;assemblies&quot;);
        }

        if (type.IsValueType)
        {
            return Enumerable.Empty&amp;lt;Type&amp;gt;();
        }

        return assemblies
            .SelectMany(assembly =&amp;gt; assembly.GetExportedTypes())
            .Where(item =&amp;gt; item != type &amp;amp;&amp;amp; item.IsAssingableTo(type));
    }

    public static bool IsAssingableTo(this Type from, Type to)
    {
        if (from == null)
        {
            throw new ArgumentNullException(&quot;from&quot;);
        }

        if (to == null)
        {
            throw new ArgumentNullException(&quot;to&quot;);
        }

        if (!to.IsGenericTypeDefinition)
        {
            // to is not generic type definition.
            return to.IsAssignableFrom(from);
        }

        if (to.IsInterface)
        {
            // type is generic interface definition.
            return from.GetInterfaces().Any(
                        @interface =&amp;gt; @interface.IsGenericType &amp;amp;&amp;amp;
                            @interface.GetGenericTypeDefinition() == to);
        }

        // to is generic class definition.
        if (!from.IsClass || from == typeof(object) || from.BaseType == typeof(object))
        {
            return false;
        }

        for (Type current = from; current != typeof(object); current = current.BaseType)
        {
            if (current.IsGenericType &amp;amp;&amp;amp; current.GetGenericTypeDefinition() == to)
            {
                return true;
            }
            else if (current.IsGenericTypeDefinition &amp;amp;&amp;amp; current == to)
            {
                return true;
            }
        }

        return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code invokes this DerivedIn() method to print derived types of System.Linq.Expresions.Expression types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (Type item in typeof(System.Linq.Expressions.Expression)
    .DerivedIn(&quot;System.Core&quot;))
{
    Console.WriteLine(item.FullName);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are 26 Expression derived types in .NET:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.Expressions.Expression
&lt;ul&gt;
&lt;li&gt;System.Linq.Expressions.BinaryExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.BlockExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.ConditionalExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.ConstantExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.DebugInfoExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.DefaultExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.DynamicExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.GotoExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.IndexExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.InvocationExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.LabelExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.LambdaExpression
&lt;ul&gt;
&lt;li&gt;System.Linq.Expressions.Expression`1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.ListInitExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.LoopExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.MemberExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.MemberInitExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.MethodCallExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.NewArrayExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.NewExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.ParameterExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.RuntimeVariablesExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.SwitchExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.TryExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.TypeBinaryExpression&lt;/li&gt;
&lt;li&gt;System.Linq.Expressions.UnaryExpression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The underlined types are delivered with Expression Trees v1 in .NET 3.5.&lt;/p&gt;
&lt;h2&gt;Expression tree for DLR&lt;/h2&gt;
&lt;p&gt;Actually, expression related APIs in &lt;a href=&quot;http://en.wikipedia.org/wiki/Dynamic_Language_Runtime&quot;&gt;DLR&lt;/a&gt; is even much richer. The above CLR stuff can be considered a implementation of subset of DLR expression trees.&lt;/p&gt;
&lt;p&gt;Currently, DLR involves only 2 dynamic language:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python (&lt;a href=&quot;http://en.wikipedia.org/wiki/IronPython&quot;&gt;IronPython&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ruby (&lt;a href=&quot;http://en.wikipedia.org/wiki/IronRuby&quot;&gt;IronRuby&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The other languages are dropped / removed, like &lt;a href=&quot;http://dlr.codeplex.com/Thread/View.aspx?ThreadId=58121&quot;&gt;Managed JSCript&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/IronScheme&quot;&gt;IronScheme&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Visual_Basic_.NET#Visual_Basic_.27VBx.27_.28VB_10.0.29&quot;&gt;VBx&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;Very typically, in IronRuby (Click &lt;a href=&quot;http://ironruby.codeplex.com/releases/view/41854&quot;&gt;here&lt;/a&gt; to download IronRuby.dll, or click &lt;a href=&quot;http://dlr.codeplex.com/releases/view/34834&quot;&gt;here&lt;/a&gt; to download the source code and build IronRuby.dll 0.9.1.0):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int count = typeof(IronRuby.Compiler.Ast.Expression).DerivedIn(&quot;IronRuby&quot;).Count();
Console.WriteLine(count); // 64.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These 60+ IronRuby 0.9.1.0 expression trees are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Expression
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.AliasStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.AndExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ArrayConstructor&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.AssignmentExpression
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.MemberAssignmentExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ParallelAssignmentExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.SimpleAssignmentExpression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.BlockExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Body&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.CallExpression
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.MethodCall&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.SuperCall&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.YieldCall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.CaseExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ConditionalExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ConditionalJumpExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ConditionalStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.DeclarationExpression
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.MethodDeclaration&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ModuleDeclaration
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ClassDeclaration&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.SingletonDeclaration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.EncodingExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ErrorExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Finalizer&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ForLoopExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.HashConstructor&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.IfExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Initializer&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.IsDefinedExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.JumpStatement
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.BreakStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.NextStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RedoStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RetryStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ReturnStatement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.LeftValue
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ArrayItemAccess&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.AttributeAccess&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.CompoundLeftValue&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Variable
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ClassVariable&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.ConstantVariable&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.GlobalVariable&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.InstanceVariable&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.LocalVariable&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Placeholder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.Literal&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.MatchExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.NotExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.OrExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RangeCondition&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RangeExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RegexMatchReference&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RegularExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RegularExpressionCondition&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.RescueExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.SelfReference&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.StringConstructor&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.StringLiteral
&lt;ul&gt;
&lt;li&gt;IronRuby.Compiler.Ast.SymbolLiteral&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.UndefineStatement&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.UnlessExpression&lt;/li&gt;
&lt;li&gt;IronRuby.Compiler.Ast.WhileLoopExpression&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What the DLR languages’ compilers do is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compile the dynamic language code into abstract syntax tree (AST) as data structure, which is represented by the above Expression-derived types;&lt;/li&gt;
&lt;li&gt;based on the abstract syntax tree, generate IL code which runs on CLR.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, the following IronPython code (&lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/cc163344.aspx&quot;&gt;copied from MSDN&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def yo(yourname):
   text = &quot;hello, &quot;
   return text + yourname

print yo(&quot;bill&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is compiled into such AST data structure:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/ironpythonast_6DDD856C.gif&quot; alt=&quot;ironpython-ast&quot; title=&quot;ironpython-ast&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now it is Ok to use fore mentioned technology to emit IL and execute.&lt;/p&gt;
&lt;p&gt;Just like &lt;a href=&quot;http://blogs.msdn.com/hugunin/&quot;&gt;Jim Hugunin&lt;/a&gt; said in &lt;a href=&quot;http://blogs.msdn.com/hugunin/archive/2007/05/15/dlr-trees-part-1.aspx&quot;&gt;his post&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The key implementation trick in the DLR is using these kinds of trees to pass code around as data and to keep code in an easily analyzable and mutable form as long as possible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now expression trees, provided in LINQ, build up a bridge to dynamic programming and metaprogramming:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Much more recently, this idea has resurfaced as one of the central features in C# 3 and VB.NET 9 that enable LINQ. Linq uses these &quot;expression trees&quot; to capture the semantics of a given block of code in a sufficiently abstract way that it can be optimized to run in different contexts. For example, the DLINQ SQL interfaces can convert that code into a SQL query that will be optimized by the database engine on the back-end. More radical projects like PLINQ are exploring how to take these same kinds of trees and rearrange the code to execute in parallel and on multiple cores when possible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As noticeable, different expression tree systems are built for CLR languages (like C#, etc.) and DLR languages (like Ruby, etc). The reason is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because our trees were untyped, we didn&apos;t believe that they shared much in common with the always strongly typed expression trees in C# 3 and we went about designing these trees as something completely independent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For more detail of expression trees in .NET 4.0, please &lt;a href=&quot;http://dlr.codeplex.com/releases/view/34834&quot;&gt;download&lt;/a&gt; this document “Expression Trees v2 Spec”.&lt;/p&gt;
&lt;h2&gt;Visualize expression tree while debugging&lt;/h2&gt;
&lt;p&gt;Since expression tree is required by LINQ to SQL and LINQ to AnyDomainOtherThanDotNet, so the question is, how to debug expression tree?&lt;/p&gt;
&lt;h3&gt;Text Visualizer&lt;/h3&gt;
&lt;p&gt;Visual Studio 2010 has a built-in Text Visualizer for expression tree:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_65A97777.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Please check MSDN for &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ee725345(VS.100).aspx&quot;&gt;the meanings of symbols&lt;/a&gt;, like $, etc.&lt;/p&gt;
&lt;h3&gt;LINQ to SQL query visualizer&lt;/h3&gt;
&lt;p&gt;In the Visual Studio 2010 local samples, typically:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033\CSharpSamples.zip\LinqSamples\QueryVisualizer\&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;there is the source code of a LINQ to SQL query visualizer. Build it into LinqToSqlQueryVisualizer.dll, and copy it to the Visual Studio 2010 visualizers folder, typically:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Documents\Visual Studio 2010\Visualizers\&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then it can be used while debugging LINQ to SQL:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_430538FC.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The expression and translated T-SQL are both displayed, and the T-SQL can be executed just-in-time by clicking the “Execute” button. This is very useful for debugging expression trees in LINQ to SQL.&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (2) IQueryable&lt;T&gt;</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-2-iqueryable-lt-t-gt/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-2-iqueryable-lt-t-gt/</guid><description>\]</description><pubDate>Mon, 29 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;The core of LINQ to Objects is IEnumerable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-linq-to-objects-3-query-methods&quot;&gt;Query methods&lt;/a&gt; are designed for IEnumerable&amp;lt;T&amp;gt; as &lt;a href=&quot;/posts/understanding-csharp-3-0-features-5-extension-method&quot;&gt;extension methods&lt;/a&gt;, like Where(), Select(), etc.;&lt;/li&gt;
&lt;li&gt;Query methods are designed to be fluent, LINQ to Objects queries can be written in &lt;a href=&quot;/posts/understanding-linq-to-objects-1-programming-paradigm&quot;&gt;declarative paradigm&lt;/a&gt; via &lt;a href=&quot;/posts/understanding-linq-to-objects-2-method-chaining&quot;&gt;method chaining&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Query methods are designed to be &lt;a href=&quot;/posts/understanding-linq-to-objects-6-deferred-execution&quot;&gt;deferred execution&lt;/a&gt; as long as &lt;a href=&quot;/posts/understanding-linq-to-objects-7-query-methods-internals&quot;&gt;possible&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since most of the .NET collections implements IEnumerable&amp;lt;T&amp;gt;, LINQ to Objects query can be applied on them.&lt;/p&gt;
&lt;p&gt;By contrast, the core of LINQ to SQL is IQueryable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;IQueryable and IQueryable&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;IQueryable and IQueryable&amp;lt;T&amp;gt; are used to build specific query against a specific data source, like SQL Server, etc.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IQueryable : IEnumerable
    {
        Type ElementType { get; }

        Expression Expression { get; }

        IQueryProvider Provider { get; }
    }

    public interface IQueryable&amp;lt;out T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IQueryable, IEnumerable
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check this post for the meaning of out keyword.&lt;/p&gt;
&lt;p&gt;The ElementType property is easy to understand. Generally speaking, an IQueryable&amp;lt;T&amp;gt; is an IEnumerable&amp;lt;T&amp;gt; with an expression and query provider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Expression property returns an Expression object to express the meaning of the current query;&lt;/li&gt;
&lt;li&gt;Provider property returns an IQueryProvider, which is able to execute the current query on the specific data source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The concept of expression and query provider will be covered in later posts. This post will concentrate on IQueryable&amp;lt;T&amp;gt; itself.&lt;/p&gt;
&lt;h2&gt;IQueryable and IQueryable&amp;lt;T&amp;gt; extensions&lt;/h2&gt;
&lt;p&gt;Just like a bunch of extension methods for IEnumerable and IEnumerable&amp;lt;T&amp;gt; are defined on System.Linq.Enumerable class, the System.Linq.Queryable class contians the extension methods for IQueryable and IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;620&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Category&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;System.Linq.Enumerable&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;System.Linq.Queryable&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Restriction&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Where, &amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;OfType&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Where, &amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;OfType&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Projection&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Select, SelectMany&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Select, SelectMany&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Ordering&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Join, GroupJoin&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Join, GroupJoin&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Grouping&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Aggregation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Aggregate, Count, LongCount, Sum, Min, Max, Average&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Aggregate, Count, LongCount, Sum, Min, Max, Average&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Partitioning&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Take, Skip, TakeWhile, SkipWhile&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Take, Skip, TakeWhile, SkipWhile&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Cancatening&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Concat&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Concat&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Set&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Distinct, Union, Intersect, Except, Zip&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Distinct, Union, Intersect, Except, Zip&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Conversion&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;ToSequence, ToArray, ToList, ToDictionary, ToLookup, &amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;Cast&amp;lt;/span&amp;gt;, &amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;AsEnumerable&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;&amp;lt;span style=&quot;text-decoration: underline;&quot;&amp;gt;Cast&amp;lt;/span&amp;gt;, {AsQueryable}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Equality&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;SequenceEqual&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;SequenceEqual&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Elements&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAt, ElementAtOrDefault, DefaultIfEmpty&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAt, ElementAtOrDefault, DefaultIfEmpty&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Generation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;[Range], [Repeat], [Empty]&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;95&quot;&amp;gt;Qualifiers&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;260&quot;&amp;gt;Any, All, Contains&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;263&quot;&amp;gt;Any, All, Contains&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;The underlined methods are extension methods for the non-generic IEnumerbale and IQueryable interfaces. Methods in [] are normal static methods. And the AsQueryable() methods in {} are also special, they are extension methods for IEnumerable and IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;Please notice that, since IQuerayable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;’s extension methods are also IQuerayable&amp;lt;T&amp;gt;’s extension methods, like ToArray(), etc.&lt;/p&gt;
&lt;h2&gt;Table&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;In LINQ to SQL, most of the time, the query works on (the model of) SQL data table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Table&amp;lt;Product&amp;gt; source = database.Products; // Products table of Northwind database.
IQueryable&amp;lt;string&amp;gt; results = source.Where(product =&amp;gt;
                                            product.Category.CategoryName == &quot;Beverages&quot;)
                                   .Select(product =&amp;gt; product.ProductName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The actual type of (the model of) Products table is Table&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Database(Name = &quot;Northwind&quot;)]
public partial class NorthwindDataContext : DataContext
{
    public Table&amp;lt;Product&amp;gt; Products
    {
        get
        {
            return this.GetTable&amp;lt;Product&amp;gt;();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, Table&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Linq
{
    public sealed class Table&amp;lt;TEntity&amp;gt; : IQueryable&amp;lt;TEntity&amp;gt;, IQueryable, 
                                         IEnumerable&amp;lt;TEntity&amp;gt;, IEnumerable,
                                         ITable&amp;lt;TEntity&amp;gt;, ITable,
                                         IQueryProvider, 
                                         IListSource
        where TEntity : class
    {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So all the above query methods are applicable for Table&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;IEnumerable&amp;lt;T&amp;gt; extensions vs. IQueryable&amp;lt;T&amp;gt; extensions&lt;/h2&gt;
&lt;p&gt;In the above table, two kinds of Where() extension methods are applicable for IQueryable&amp;lt;T&amp;gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where() extension method for IQueryable&amp;lt;T&amp;gt;, defined in Queryable class;&lt;/li&gt;
&lt;li&gt;Where() extension method for IEnumerable&amp;lt;T&amp;gt;, defind in Queryable class, since IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are difference from the signatures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Data.Linq
{
    public static class Enumerable
    {
        // This is also Available for IQueryable&amp;lt;T&amp;gt;,
        // because IQueryable&amp;lt;T&amp;gt; implements IEnumerable&amp;lt;T&amp;gt;.
        public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate)
        {
            // ...
        }
    }

    public static class Queryable
    {
        public static IQueryable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(
            this IQueryable&amp;lt;TSource&amp;gt; source, Expression&amp;lt;Func&amp;lt;TSource, bool&amp;gt;&amp;gt; predicate)
        {
            // ...
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice that the above Where() method invocation satisfies both of the signatures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source.Where(product =&amp;gt; product.Category.CategoryName == &quot;Beverages&quot;).Select(...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this invocation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;source argument: it is a Table&amp;lt;T&amp;gt; object, and Table&amp;lt;T&amp;gt; implements both IQueryable&amp;lt;T&amp;gt; and IEnumerable&amp;lt;T&amp;gt;;&lt;/li&gt;
&lt;li&gt;predicate argument: The predicate is written as lambda expression, accorsing to &lt;a href=&quot;/posts/understanding-csharp-3-0-features-6-lambda-expression&quot;&gt;this post&lt;/a&gt;, lambda expression (product =&amp;gt; product.Category.CategoryName == &quot;Beverages&quot;) can be compiled into either anonymous method (Func&amp;lt;Product, bool&amp;gt;) or expression tree (Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How does the compiler choose the 2 satisfied Where() methods? Because Queryable.Where()’s first parameter is an IQueryable&amp;lt;T&amp;gt; object, and second parameter is also Ok, it is considered to be a stronger match, and it is choosed by compiler.&lt;/p&gt;
&lt;p&gt;Because Queryable.Where() returns an IQueryable&amp;lt;T&amp;gt;, then, again, Queryable.Select() is choosed by compiler instead of Enumerable.Select().&lt;/p&gt;
&lt;p&gt;So the above qeury is equal to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IQueryable&amp;lt;Product&amp;gt; source = database.Products; // Products table of Northwind database.
// Queryable.Where() is choosed by compiler.
IQueryable&amp;lt;Product&amp;gt; products = source.Where(product =&amp;gt;
                                            product.Category.CategoryName == &quot;Beverages&quot;);
// Queryable.Select() is choosed by compiler.
IQueryable&amp;lt;string&amp;gt; results = products.Select(product =&amp;gt; product.ProductName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By checking all the duplicated extension mrethods betwwen IEnumerable&amp;lt;T&amp;gt; and IQueryable&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt; extension methods evolve the signatures by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;replacing all IEnumerable&amp;lt;T&amp;gt; parameter with IQueryable&amp;lt;T&amp;gt; parameter;&lt;/li&gt;
&lt;li&gt;replacing all function parameter with expression tree parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The expression tree parameter will be explained in the next post.&lt;/p&gt;
</content:encoded></item><item><title>Naming in Visual Studio 2010 advertisement</title><link>https://dixin.github.io/posts/naming-in-visual-studio-2010-advertisement/</link><guid isPermaLink="true">https://dixin.github.io/posts/naming-in-visual-studio-2010-advertisement/</guid><description>A great advertisement for Visual Studio 2010 has been released. Click  to dow</description><pubDate>Sun, 28 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A great advertisement for Visual Studio 2010 has been released. Click &lt;a href=&quot;http://content2.catalog.video.msn.com/e2/ds/zh-cn/CMG_China/ZHCN_Microsoft/575b01f8-2730-40d3-b87f-1a16d7412c1c.wmv&quot;&gt;here&lt;/a&gt; to download.&lt;/p&gt;
&lt;p&gt;In this video, it looks like the boy is coding a WinForm application with C#:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_462F777F.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Are these &lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;Hungary notations&lt;/a&gt;?&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to SQL (1) Object-Relational Mapping</title><link>https://dixin.github.io/posts/understanding-linq-to-sql-1-object-relational-mapping/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-sql-1-object-relational-mapping/</guid><description>\]</description><pubDate>Sun, 28 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-relational_mapping&quot;&gt;Wikipedia&lt;/a&gt;, Object-relational mapping is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_programming&quot;&gt;programming&lt;/a&gt; technique for converting data between incompatible &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_system&quot;&gt;type systems&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Relational_database&quot;&gt;relational databases&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-oriented&quot;&gt;object-oriented&lt;/a&gt; programming languages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the LINQ to SQL sample code at the beginning of this series:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    var results = from product in database.Products
                  where product.Category.CategoryName == &quot;Beverages&quot;
                  select new
                  {
                      product.ProductName,
                      product.UnitPrice
                  };
    foreach (var item in results)
    {
        Console.WriteLine(
            &quot;{0}: {1}&quot;, 
            item.ProductName, 
            item.UnitPrice.ToString(CultureInfo.InvariantCulture));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to &lt;a href=&quot;/posts/understanding-csharp-3-0-features-7-query-expression&quot;&gt;this post&lt;/a&gt;, the above query expression will be compiled to query methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = database.Products.Where(product =&amp;gt; product.Category.CategoryName == &quot;Beverages&quot;)
                               .Select(product =&amp;gt; new
                                                      {
                                                          product.ProductName,
                                                          product.UnitPrice
                                                      });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is querying the ProductName and UnitPrice fields of the Products table in the Northwind database, which belong to the specified CategoryName. To work with SQL Server representations (fields, tables, databases) in C# representations (object models), the mappings between SQL representations and C# representations need to be created. LINQ to SQL provides an Object-relational mapping designer tool to create those objects models automatically.&lt;/p&gt;
&lt;h2&gt;Create C# models from SQL schema&lt;/h2&gt;
&lt;p&gt;The easiest way of modeling is to use Visual Studio IDE. This way works with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server 2000&lt;/li&gt;
&lt;li&gt;SQL Server 2005&lt;/li&gt;
&lt;li&gt;SQL Server 2008&lt;/li&gt;
&lt;li&gt;SQL Server 2008 R2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take the &lt;a href=&quot;http://go.microsoft.com/fwlink/?linkid=30196&quot;&gt;Northwind database&lt;/a&gt; as an example. First, setup a data connection to the Northwind database:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_16BE86DC.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then, create a “LINQ to SQL Classes” item to the project:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_32AC45F9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By creating a Northwind.dbml file, the O/R designer is opened:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_057A836C.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Since the above query works with the Products table and the Categories table, just drag the 2 tables and drop to the O/R designer:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_00D452E5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In the designer, the modeling is done. Please notice that the foreign key between Categories table and Products table is recognized, and the corresponding association is created in the designer.&lt;/p&gt;
&lt;p&gt;Now the object models are ready to rock. Actually the designer has automatically created the following C# code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Category class: represents each record in Categories table;
&lt;ul&gt;
&lt;li&gt;CategoryID property (an int): represents the CategoryID field; So are the other properties shown above;&lt;/li&gt;
&lt;li&gt;Products propery (a collection of Product object): represents the associated many records in Products table&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Product class: represents each record in Products table;
&lt;ul&gt;
&lt;li&gt;ProductID property (an int): represents the ProductID field; So are the other properties shown above;&lt;/li&gt;
&lt;li&gt;Category propery (a Category object): represents the associated one records in Products table;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NorthwindDataContext class: represents the Northwind database;
&lt;ul&gt;
&lt;li&gt;Categories property (a collection of the Category objects): represents the Categories table;&lt;/li&gt;
&lt;li&gt;Products property (a collection of the Product objects): represents the Products table;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides, database, tables, fields, other SQL stuff can also be modeled by this O/R designer:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_7380D056.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;732&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;SQL representation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;C# representation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;Sample&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Database&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;DataContext derived class&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;NothwindDataContext&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Table, View&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;DataContext derived class’s property&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;NothwindDataContext.Categories&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Record&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;Entity class&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;Category&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Field&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;Entity class’s property&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;Category.CategoryName&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Foreign key&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;Association between entity classes&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;Category.Products&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;191&quot;&amp;gt;Stored procedure, function&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;253&quot;&amp;gt;DataContext derived class’s method&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;286&quot;&amp;gt;NothwindDataContext.SalesByCategory()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;Another way to generate the models is to use the command line tool &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386987.aspx&quot;&gt;SqlMetal.exe&lt;/a&gt;. Please check MSDN for &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb399400.aspx&quot;&gt;details of code generation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And, please notice that, the Category entity class is generated from the Categories table. Here plural name is renamed to singular name, because a Category object is the mapping of one record of Categories table. This can be configured in Visual Studio:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_406769FD.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Implement the mapping&lt;/h2&gt;
&lt;p&gt;Now take a look at how the SQL representations are mapped to C# representations.&lt;/p&gt;
&lt;p&gt;The Northwind.dbml is nothing but an XML file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;!-- [Northwind] database is mapped to NorthwindDataContext class. --&amp;gt;
&amp;lt;Database Name=&quot;Northwind&quot; Class=&quot;NorthwindDataContext&quot; xmlns=&quot;http://schemas.microsoft.com/linqtosql/dbml/2007&quot;&amp;gt;
    &amp;lt;!-- Connection string --&amp;gt;
    &amp;lt;Connection Mode=&quot;WebSettings&quot; ConnectionString=&quot;Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True&quot; SettingsObjectName=&quot;System.Configuration.ConfigurationManager.ConnectionStrings&quot; SettingsPropertyName=&quot;NorthwindConnectionString&quot; Provider=&quot;System.Data.SqlClient&quot; /&amp;gt;

    &amp;lt;!-- Categories property is a member of NorthwindDataContext class. --&amp;gt;
    &amp;lt;Table Name=&quot;dbo.Categories&quot; Member=&quot;Categories&quot;&amp;gt;
        &amp;lt;!-- [Categories] table is mapped to Category class. --&amp;gt;
        &amp;lt;Type Name=&quot;Category&quot;&amp;gt;
            &amp;lt;!-- [CategoryID] (SQL Int) field is mapped to CategoryID property (C# int). --&amp;gt;
            &amp;lt;Column Name=&quot;CategoryID&quot; Type=&quot;System.Int32&quot; DbType=&quot;Int NOT NULL IDENTITY&quot; IsPrimaryKey=&quot;true&quot; IsDbGenerated=&quot;true&quot; CanBeNull=&quot;false&quot; /&amp;gt;
            &amp;lt;!-- [CategoryName] (SQL NVarChar(15)) field is mapped to CategoryName property (C# string). --&amp;gt;
            &amp;lt;Column Name=&quot;CategoryName&quot; Type=&quot;System.String&quot; DbType=&quot;NVarChar(15) NOT NULL&quot; CanBeNull=&quot;false&quot; /&amp;gt;
            &amp;lt;!-- Other fields. --&amp;gt;
            &amp;lt;Column Name=&quot;Description&quot; Type=&quot;System.String&quot; DbType=&quot;NText&quot; CanBeNull=&quot;true&quot; UpdateCheck=&quot;Never&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;Picture&quot; Type=&quot;System.Data.Linq.Binary&quot; DbType=&quot;Image&quot; CanBeNull=&quot;true&quot; UpdateCheck=&quot;Never&quot; /&amp;gt;
            &amp;lt;!-- [Categories] is associated with [Products] table via a foreign key.
            So Category class has a Products peoperty to represent the associated many Product objects. --&amp;gt;
            &amp;lt;Association Name=&quot;Category_Product&quot; Member=&quot;Products&quot; ThisKey=&quot;CategoryID&quot; OtherKey=&quot;CategoryID&quot; Type=&quot;Product&quot; /&amp;gt;
        &amp;lt;/Type&amp;gt;
    &amp;lt;/Table&amp;gt;

    &amp;lt;!-- Products property is a member of NorthwindDataContext class. --&amp;gt;
    &amp;lt;Table Name=&quot;dbo.Products&quot; Member=&quot;Products&quot;&amp;gt;
        &amp;lt;!-- [Products] table is mapped to Product class. --&amp;gt;
        &amp;lt;Type Name=&quot;Product&quot;&amp;gt;
            &amp;lt;!-- Fields. --&amp;gt;
            &amp;lt;Column Name=&quot;ProductID&quot; Type=&quot;System.Int32&quot; DbType=&quot;Int NOT NULL IDENTITY&quot; IsPrimaryKey=&quot;true&quot; IsDbGenerated=&quot;true&quot; CanBeNull=&quot;false&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;ProductName&quot; Type=&quot;System.String&quot; DbType=&quot;NVarChar(40) NOT NULL&quot; CanBeNull=&quot;false&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;SupplierID&quot; Type=&quot;System.Int32&quot; DbType=&quot;Int&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;CategoryID&quot; Type=&quot;System.Int32&quot; DbType=&quot;Int&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;QuantityPerUnit&quot; Type=&quot;System.String&quot; DbType=&quot;NVarChar(20)&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;UnitPrice&quot; Type=&quot;System.Decimal&quot; DbType=&quot;Money&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;UnitsInStock&quot; Type=&quot;System.Int16&quot; DbType=&quot;SmallInt&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;UnitsOnOrder&quot; Type=&quot;System.Int16&quot; DbType=&quot;SmallInt&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;ReorderLevel&quot; Type=&quot;System.Int16&quot; DbType=&quot;SmallInt&quot; CanBeNull=&quot;true&quot; /&amp;gt;
            &amp;lt;Column Name=&quot;Discontinued&quot; Type=&quot;System.Boolean&quot; DbType=&quot;Bit NOT NULL&quot; CanBeNull=&quot;false&quot; /&amp;gt;
            &amp;lt;!-- [Products] is associated with [Products] table via a foreign key.
            So Product class has a Category peoperty to represent the associated one Category object. --&amp;gt;
            &amp;lt;Association Name=&quot;Category_Product&quot; Member=&quot;Category&quot; ThisKey=&quot;CategoryID&quot; OtherKey=&quot;CategoryID&quot; Type=&quot;Category&quot; IsForeignKey=&quot;true&quot; /&amp;gt;
        &amp;lt;/Type&amp;gt;
    &amp;lt;/Table&amp;gt;
&amp;lt;/Database&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It describes how the SQL stuff are mapped to C# stuff.&lt;/p&gt;
&lt;p&gt;A Northwind.dbml.layout file is created along with the dbml. It is also an XML, describing how the O/R designer should visualize the objects models:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;ordesignerObjectsDiagram dslVersion=&quot;1.0.0.0&quot; absoluteBounds=&quot;0, 0, 11, 8.5&quot; name=&quot;Northwind&quot;&amp;gt;
    &amp;lt;DataContextMoniker Name=&quot;/NorthwindDataContext&quot; /&amp;gt;
    &amp;lt;nestedChildShapes&amp;gt;
        &amp;lt;!-- Category class --&amp;gt;
        &amp;lt;classShape Id=&quot;81d67a31-cd80-4a91-84fa-5d4dfa2e8694&quot; absoluteBounds=&quot;0.75, 1.5, 2, 1.5785953776041666&quot;&amp;gt;
            &amp;lt;DataClassMoniker Name=&quot;/NorthwindDataContext/Category&quot; /&amp;gt;
            &amp;lt;nestedChildShapes&amp;gt;
                &amp;lt;!-- Properties --&amp;gt;
                &amp;lt;elementListCompartment Id=&quot;a261c751-8ff7-471e-9545-cb385708d390&quot; absoluteBounds=&quot;0.765, 1.96, 1.9700000000000002, 1.0185953776041665&quot; name=&quot;DataPropertiesCompartment&quot; titleTextColor=&quot;Black&quot; itemTextColor=&quot;Black&quot; /&amp;gt;
            &amp;lt;/nestedChildShapes&amp;gt;
        &amp;lt;/classShape&amp;gt;
        
        &amp;lt;!-- Product class --&amp;gt;
        &amp;lt;classShape Id=&quot;59f11c67-f9d4-4da9-ad0d-2288402ec016&quot; absoluteBounds=&quot;3.5, 1, 2, 2.7324039713541666&quot;&amp;gt;
            &amp;lt;DataClassMoniker Name=&quot;/NorthwindDataContext/Product&quot; /&amp;gt;
            &amp;lt;nestedChildShapes&amp;gt;
                &amp;lt;!-- Properties --&amp;gt;
                &amp;lt;elementListCompartment Id=&quot;6c1141a2-f9a9-4660-8730-bed7fa15bc27&quot; absoluteBounds=&quot;3.515, 1.46, 1.9700000000000002, 2.1724039713541665&quot; name=&quot;DataPropertiesCompartment&quot; titleTextColor=&quot;Black&quot; itemTextColor=&quot;Black&quot; /&amp;gt;
            &amp;lt;/nestedChildShapes&amp;gt;
        &amp;lt;/classShape&amp;gt;
        
        &amp;lt;!-- Association arrow --&amp;gt;
        &amp;lt;associationConnector edgePoints=&quot;[(2.75 : 2.28929768880208); (3.5 : 2.28929768880208)]&quot; fixedFrom=&quot;Algorithm&quot; fixedTo=&quot;Algorithm&quot;&amp;gt;
            &amp;lt;AssociationMoniker Name=&quot;/NorthwindDataContext/Category/Category_Product&quot; /&amp;gt;
            &amp;lt;nodes&amp;gt;
                &amp;lt;!-- From Category class --&amp;gt;
                &amp;lt;classShapeMoniker Id=&quot;81d67a31-cd80-4a91-84fa-5d4dfa2e8694&quot; /&amp;gt;
                &amp;lt;!-- To Product class --&amp;gt;
                &amp;lt;classShapeMoniker Id=&quot;59f11c67-f9d4-4da9-ad0d-2288402ec016&quot; /&amp;gt;
            &amp;lt;/nodes&amp;gt;
        &amp;lt;/associationConnector&amp;gt;
    &amp;lt;/nestedChildShapes&amp;gt;
&amp;lt;/ordesignerObjectsDiagram&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A Northwind.designer.cs is also created, containing the auto generated C# code.&lt;/p&gt;
&lt;p&gt;This is how the NorthwindDataContext looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Database(Name = &quot;Northwind&quot;)]
public partial class NorthwindDataContext : DataContext
{
    public Table&amp;lt;Category&amp;gt; Categories
    {
        get
        {
            return this.GetTable&amp;lt;Category&amp;gt;();
        }
    }

    public Table&amp;lt;Product&amp;gt; Products
    {
        get
        {
            return this.GetTable&amp;lt;Product&amp;gt;();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the Category class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;dbo.Categories&quot;)]
public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged
{
    private int _CategoryID;

    private EntitySet&amp;lt;Product&amp;gt; _Products;

    [Column(Storage = &quot;_CategoryID&quot;, AutoSync = AutoSync.OnInsert, 
        DbType = &quot;Int NOT NULL IDENTITY&quot;, IsPrimaryKey = true, IsDbGenerated = true)]
    public int CategoryID
    {
        get
        {
            return this._CategoryID;
        }
        set
        {
            if ((this._CategoryID != value))
            {
                this.OnCategoryIDChanging(value);
                this.SendPropertyChanging();
                this._CategoryID = value;
                this.SendPropertyChanged(&quot;CategoryID&quot;);
                this.OnCategoryIDChanged();
            }
        }
    }

    // Other properties.

    [Association(Name = &quot;Category_Product&quot;, Storage = &quot;_Products&quot;, 
        ThisKey = &quot;CategoryID&quot;, OtherKey = &quot;CategoryID&quot;)]
    public EntitySet&amp;lt;Product&amp;gt; Products
    {
        get
        {
            return this._Products;
        }
        set
        {
            this._Products.Assign(value);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Products looks similar.&lt;/p&gt;
&lt;h2&gt;Customize the mapping&lt;/h2&gt;
&lt;p&gt;Since the mapping info are simply stored in the XML file and C# code, they can be customized in the O/R designer easily:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_02E12BE1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After renaming Category class to CategoryEntity, the XML and C# is refined automatically:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;Database Name=&quot;Northwind&quot; Class=&quot;NorthwindDataContext&quot; xmlns=&quot;http://schemas.microsoft.com/linqtosql/dbml/2007&quot;&amp;gt;
    &amp;lt;Table Name=&quot;dbo.Categories&quot; Member=&quot;CategoryEntities&quot;&amp;gt;
        &amp;lt;Type Name=&quot;CategoryEntity&quot;&amp;gt;
            &amp;lt;!-- Fields --&amp;gt;
        &amp;lt;/Type&amp;gt;
    &amp;lt;/Table&amp;gt;
    &amp;lt;Table Name=&quot;dbo.Products&quot; Member=&quot;Products&quot;&amp;gt;
        &amp;lt;Type Name=&quot;Product&quot;&amp;gt;
            &amp;lt;!-- Fields --&amp;gt;
            &amp;lt;Association Name=&quot;Category_Product&quot; Member=&quot;CategoryEntity&quot; Storage=&quot;_Category&quot; ThisKey=&quot;CategoryID&quot; OtherKey=&quot;CategoryID&quot; Type=&quot;CategoryEntity&quot; IsForeignKey=&quot;true&quot; /&amp;gt;
        &amp;lt;/Type&amp;gt;
    &amp;lt;/Table&amp;gt;
&amp;lt;/Database&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Database(Name = &quot;Northwind&quot;)]
public partial class NorthwindDataContext : DataContext
{
    public Table&amp;lt;CategoryEntity&amp;gt; CategoryEntities { get; }
}

[Table(Name = &quot;dbo.Categories&quot;)]
public partial class CategoryEntity : INotifyPropertyChanging, INotifyPropertyChanged
{
}

[Table(Name = &quot;dbo.Products&quot;)]
public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
{
    [Association(Name = &quot;Category_Product&quot;, Storage = &quot;_Category&quot;,
        ThisKey = &quot;CategoryID&quot;, OtherKey = &quot;CategoryID&quot;, IsForeignKey = true)]
    public CategoryEntity CategoryEntity { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Properties, associations, and inheritances and also be customized:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_59F616D7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For example, The ProductID property can be renamed to ProductId to &lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;be compliant to .NET Framework Design Guidelines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;More options are available to customize the data context, entities, and properties:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_504DA8A1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Please notice this mapping is one way mapping, from SQL Server to C#. When the mapping information is changed in O/R designer, SQL Server is not affected at all.&lt;/p&gt;
&lt;p&gt;And, LINQ to SQL is designed to provide a simple O/R mapping, not supporting advenced functionalities, like &lt;a href=&quot;http://connect.microsoft.com/VisualStudio/feedback/details/299807/single-table-inheritance-in-the-linq-to-sql-is-a-poor-option&quot;&gt;multi-table inheritance&lt;/a&gt;, etc. &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb386919.aspx&quot;&gt;According to MSDN&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The single-table mapping strategy is the simplest representation of inheritance and provides good performance characteristics for many different categories of queries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Please check &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb399352.aspx&quot;&gt;this link&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2&gt;Work with the models&lt;/h2&gt;
&lt;p&gt;The auto generated models are very easy and extensible.&lt;/p&gt;
&lt;h3&gt;Partial class&lt;/h3&gt;
&lt;p&gt;All the generated C# classes are partial classes. For example, it is very easy to add a NorthwindDataContext,cs file and a Category.cs file to the project, and write the extension code.&lt;/p&gt;
&lt;h3&gt;Partial method&lt;/h3&gt;
&lt;p&gt;There are also a lot of partial method in the generated code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Database(Name = &quot;Northwind&quot;)]
public partial class NorthwindDataContext : DataContext
{
    #region Extensibility Method Definitions

    partial void OnCreated();
    partial void InsertCategory(Category instance);
    partial void UpdateCategory(Category instance);
    partial void DeleteCategory(Category instance);
    partial void InsertProduct(Product instance);
    partial void UpdateProduct(Product instance);
    partial void DeleteProduct(Product instance);

    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, the OnCreated() can be implemented in the NorthwindDataContext,cs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class NorthwindDataContext
{
    // OnCreated will be invoked by constructors.
    partial void OnCreated()
    {
        // The default value is 30 seconds.
        this.CommandTimeout = 40;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the Northwind is constructed, the OnCreated() is invoked, and the custom code is executed.&lt;/p&gt;
&lt;p&gt;So are the entities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;dbo.Categories&quot;)]
public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged
{
    #region Extensibility Method Definitions

    partial void OnLoaded();
    partial void OnValidate(ChangeAction action);
    partial void OnCreated();
    partial void OnCategoryIDChanging(int value);
    partial void OnCategoryIDChanged();
    partial void OnCategoryNameChanging(string value);
    partial void OnCategoryNameChanged();
    partial void OnDescriptionChanging(string value);
    partial void OnDescriptionChanged();
    partial void OnPictureChanging(Binary value);
    partial void OnPictureChanged();

    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, the OnValidated() is very useful for the data correction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;dbo.Categories&quot;)]
public partial class Category
{
    partial void OnValidate(ChangeAction action)
    {
        switch (action)
        {
            case ChangeAction.Delete:
                // Validates the object when deleted.
                break;
            case ChangeAction.Insert:
                // Validates the object when inserted.
                break;
            case ChangeAction.None:
                // Validates the object when not submitted.
                break;
            case ChangeAction.Update:
                // Validates the object when updated.
                if (string.IsNullOrWhiteSpace(this._CategoryName))
                {
                    throw new ValidationException(&quot;CategoryName is invalid.&quot;);
                }
                break;
            default:
                break;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the category object (representing a record in Categories table) is updated, the custom code checking the CategoryName will be executed.&lt;/p&gt;
&lt;p&gt;And, because each entity class’s Xxx property’s setter involves OnXxxChanging() partial method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;dbo.Categories&quot;)]
public partial class CategoryEntity : INotifyPropertyChanging, INotifyPropertyChanged
{
    [Column(Storage = &quot;_CategoryName&quot;, DbType = &quot;NVarChar(15) NOT NULL&quot;, CanBeNull = false)]
    public string CategoryName
    {
        get
        {
            return this._CategoryName;
        }
        set
        {
            if ((this._CategoryName != value))
            {
                this.OnCategoryNameChanging(value);
                this.SendPropertyChanging();
                this._CategoryName = value;
                this.SendPropertyChanged(&quot;CategoryName&quot;);
                this.OnCategoryNameChanged();
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Validation can be also done in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class CategoryEntity
{
    partial void OnCategoryNameChanging(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentOutOfRangeException(&quot;value&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;INotifyPropertyChanging and INotifyPropertyChanged interfaces&lt;/h3&gt;
&lt;p&gt;Each auto generated entity class implements INotifyPropertyChanging and INotifyPropertyChanged interfaces:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.ComponentModel
{
    public interface INotifyPropertyChanging
    {
        event PropertyChangingEventHandler PropertyChanging;
    }

    public interface INotifyPropertyChanged
    {
        event PropertyChangedEventHandler PropertyChanged;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, in the above auto generated CategoryName code, after setting the CategoryName, SendPropertyChanged() is invoked, passing the propery name “CategoryName” as argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;dbo.Categories&quot;)]
public partial class CategoryEntity : INotifyPropertyChanging, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void SendPropertyChanged(String propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very useful to track changes of the entity object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Category category = database.Categories.Single(item =&amp;gt; item.CategoryName = &quot;Beverages&quot;);
    category.PropertyChanged += (_, e) =&amp;gt;
        {
            Console.Write(&quot;Propery {0} is changed&quot;, e.PropertyName);
        };

    // Work with the category object.
    category.CategoryID = 100;
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is used for change tracking by DataContext, which will be explained later.&lt;/p&gt;
&lt;h2&gt;Programmatically access the mapping information&lt;/h2&gt;
&lt;p&gt;The mapping information is stored in DataContext.Mapping as a MetaModel object. Here is an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class DataContextExtensions
{
    public static Type GetEntityType(this DataContext database, string tableName)
    {
        return database.Mapping.GetTables()
                               .Single(table =&amp;gt; table.TableName.Equals(
                                   tableName, StringComparison.Ordinal))
                               .RowType
                               .Type;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The method queries the mapping information with the table name, and returns the entity type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (NorthwindDataContext database = new NorthwindDataContext())
{
    Type categoryType = database.GetEntityType(&quot;dbo.Categories&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Create SQL schema from C# models&lt;/h2&gt;
&lt;p&gt;Usually, many people design the SQL database first, then model it with the O/R designer, and write code to work with the C# object models. But this is not required. It is totally Ok to create &lt;a href=&quot;http://en.wikipedia.org/wiki/Plain_Old_CLR_Object&quot;&gt;POCO&lt;/a&gt; models first without considering the SQL stuff:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Category
{
    public int CategoryID { get; set; }

    public string CategoryName { get; set; }

    public EntitySet&amp;lt;Product&amp;gt; Products { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is already able to start coding with this kind of models.&lt;/p&gt;
&lt;p&gt;Later, there are 2 ways to integrate the C# program with SQL Server database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generate object models from designed SQL Server database;&lt;/li&gt;
&lt;li&gt;Decorate POCO models with mapping attributes, Invoke CreateDatabase() method of DataContext to create the expected database schema in SQL Server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, the C# models can be polluted with O/R mapping knowledge like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Table(Name = &quot;Categories&quot;)]
public class Category
{
    [Column(DbType = &quot;Int NOT NULL IDENTITY&quot;, IsPrimaryKey = true)]
    public int CategoryId { get; set; }

    [Column(DbType = &quot;NVarChar(15) NOT NULL&quot;)]
    public string CategoryName { get; set; }

    [Association(Name = &quot;Category_Products&quot;,
        ThisKey = &quot;CategoryId&quot;, OtherKey = &quot;CategoryId&quot;)]
    public EntitySet&amp;lt;Product&amp;gt; Products { get; set; }
}

[Table(Name = &quot;Products&quot;)]
public class Product
{
    [Column(DbType = &quot;Int NOT NULL IDENTITY&quot;, IsPrimaryKey = true)]
    public int ProductId { get; set; }

    [Column(DbType = &quot;NVarChar(40) NOT NULL&quot;)]
    public string ProductName { get; set; }

    [Column(DbType = &quot;Int&quot;)]
    public int CategoryId { get; set; }

    [Association(Name = &quot;Category_Products&quot;, IsForeignKey = true,
        ThisKey = &quot;CategoryId&quot;, OtherKey = &quot;CategoryId&quot;)]
    public Category Category { get; set; }
}

[Database(Name = &quot;SimpleNorthwind&quot;)]
public class SimpleNorthwindDataContext : DataContext
{
    public SimpleNorthwindDataContext(IDbConnection connection)
        : base(connection)
    {
    }

    public Table&amp;lt;Category&amp;gt; Categories { get; set; }

    public Table&amp;lt;Product&amp;gt; Products { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it is ready to create database schema in SQL server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using (SimpleNorthwindDataContext database = new SimpleNorthwindDataContext(new SqlConnection(
    @&quot;Data Source=localhost;Initial Catalog=SimpleNorthwind;Integrated Security=True&quot;)))
{
    if (database.DatabaseExists())
    {
        database.DeleteDatabase();
    }

    database.CreateDatabase();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Isn’t this easy? This is the generated SimpleNorthwind database in SQL Server:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_6265F3DC.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Understanding LINQ to Objects (8) The Design Of IEnumerable&lt;T&gt;</title><link>https://dixin.github.io/posts/understanding-linq-to-objects-8-the-design-of-ienumerable-lt-t-gt/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-objects-8-the-design-of-ienumerable-lt-t-gt/</guid><description>\]</description><pubDate>Sat, 20 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Currently in .NET, iterator pattern is implemented via IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; (or IEnumerable and IEnumerator):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections
{
    // Represents a collection which can be iterated.
    public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }

    // Represents an iterator which is used to iterate that collection.
    public interface IEnumerator
    {
        object Current { get; }

        bool MoveNext();

        void Reset();
    }
}

namespace System.Collections.Generic
{
    // T is covariant.
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }

    // T is covariant.
    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The meaning of out keyword is explained in another post &lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For years I have different ideas on the design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first problem is, why they are called enumerable and enumerator? Iteratable and iterator sounds natural enough;&lt;/li&gt;
&lt;li&gt;The second problem is, why IEnumerable IEnumerable&amp;lt;T&amp;gt; have Current properties? According to &lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613&quot;&gt;Framework Design Guidelines&lt;/a&gt;, they should be designed as methods, because they returns different values for each invocation (similar with Guid.NewGuid()).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my opinion, the following design should be more perfect:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections
{
    public interface IIteratable
    {
        IIterator GetEnumerator();
    }

    public interface IIterator
    {
        object GetCurrent();

        bool MoveNext();

        void Reset();
    }
}

namespace System.Collections.Generic
{
    public interface IIteratable&amp;lt;out T&amp;gt; : IIteratable
    {
        IIterator&amp;lt;T&amp;gt; GetEnumerator();
    }

    public interface IIterator&amp;lt;out T&amp;gt; : IDisposable, IIterator
    {
        T GetCurrent();
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding LINQ to Objects (3) Iterator Pattern and foreach</title><link>https://dixin.github.io/posts/understanding-linq-to-objects-3-iterator-pattern-and-foreach/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-linq-to-objects-3-iterator-pattern-and-foreach/</guid><description>\] - \]</description><pubDate>Sun, 14 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=LINQ%20to%20Objects&quot;&gt;LINQ to Objects&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;LINQ to Objects provides fluent query methods in a functional paradigm. All these queries work with IEnumerable&amp;lt;T&amp;gt; sequence, and the values in the sequence will be processed with either deferred execution or immediate execution. To sequentially access the values in an IEnumerable&amp;lt;T&amp;gt; sequence, &lt;a href=&quot;http://en.wikipedia.org/wiki/Iterator_pattern&quot;&gt;iterator pattern&lt;/a&gt; is widely used in .NET and is also a built-in feature of C# language.&lt;/p&gt;
&lt;h2&gt;Iteration pattern&lt;/h2&gt;
&lt;p&gt;Iteration pattern includes a sequence and an iterator. In .NET, they are like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Sequence
{
    public Iterator GetEnumerator() =&amp;gt; new Iterator();
}

public class Iterator
{
    public bool MoveNext() =&amp;gt; false;

    public object Current { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the generic version is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Sequence&amp;lt;T&amp;gt;
{
    public Iterator&amp;lt;T&amp;gt; GetEnumerator() =&amp;gt; new Iterator&amp;lt;T&amp;gt;();
}

public class Iterator&amp;lt;T&amp;gt;
{
    public bool MoveNext() =&amp;gt; false;

    public T Current { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above sequence/Iterator classes demonstrate the minimum requirements of using a foreach loop to iterate and access each value in the container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The container should have
&lt;ul&gt;
&lt;li&gt;a GetEnumerable method, which returns an iterator with:
&lt;ul&gt;
&lt;li&gt;a MoveNext method returns a boolean value to indicate if there are still a value that can be puuled.&lt;/li&gt;
&lt;li&gt;a Current property with a getter, which returns the current value to be pulled from the container when MoveNext returns true.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The foreach and in keywords&lt;/h2&gt;
&lt;p&gt;Now foreach loop can be compiled for above non-generic and generic containers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class IteratorPattern
{
    public static void ForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; processValue)
    {
        foreach (T value in sequence)
        {
            processValue(value);
        }
    }

    public static void ForEach&amp;lt;T&amp;gt;(Sequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; processValue)
    {
        foreach (T value in sequence)
        {
            processValue(value);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These foreach loops are compiled to while loops, and GetEnumeraotor/MoveNext/Current calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void CompiledForEach&amp;lt;T&amp;gt;(Sequence sequence, Action&amp;lt;T&amp;gt; next)
{
    Iterator iterator = sequence.GetEnumerator();
    try
    {
        while (iterator.MoveNext())
        {
            T value = (T)iterator.Current;
            next(value);
        }
    }
    finally
    {
        (iterator as IDisposable)?.Dispose();
    }
}

public static void CompiledForEach&amp;lt;T&amp;gt;(Sequence&amp;lt;T&amp;gt; sequence, Action&amp;lt;T&amp;gt; next)
{
    Iterator&amp;lt;T&amp;gt; iterator = sequence.GetEnumerator();
    try
    {
        while (iterator.MoveNext())
        {
            T value = iterator.Current;
            next(value);
        }
    }
    finally
    {
        (iterator as IDisposable)?.Dispose();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The difference is, the non-generic Iterator’s Current property returns an object, it has to be explicitly casted to type T specified in the foreach loop, which is a chance to fail.&lt;/p&gt;
&lt;h2&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;&lt;/h2&gt;
&lt;p&gt;To implements iterator pattern, IEnumerable for sequence and IEnumerator for iterator are built in .NET from the beginning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections
{
    public interface IEnumerable // Sequence.
    {
        IEnumerator GetEnumerator();
    }

    public interface IEnumerator // Iterator.
    {
        object Current { get; }

        bool MoveNext();

        void Reset(); // Only for COM interoperability.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.NET 2.0 introduced generics, so IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; are added:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public interface IDisposable
    {
        void Dispose();
    }
}

namespace System.Collections.Generic
{
    public interface IEnumerable&amp;lt;T&amp;gt; : IEnumerable // Sequence.
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }

    public interface IEnumerator&amp;lt;T&amp;gt; : IDisposable, IEnumerator // Iterator.
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Later, .NET 4.0 introduces covariance and contravariance. T is covariant for generic interfaces IEnumerable&amp;lt;T&amp;gt; and IEnumerable&amp;lt;T&amp;gt;. So they became:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable // Sequence.
    {
        IEnumerator&amp;lt;T&amp;gt; GetEnumerator();
    }

    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator // Iterator.
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a type implements IEnumerable&amp;lt;T&amp;gt;, its instance is guaranteed to be able to work in foreach loop.&lt;/p&gt;
&lt;p&gt;S0 there are quite a few terms around iterator pattern, and here is a summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IEnumerable/IEnumerable&amp;lt;T&amp;gt;: represents sequence, also called container, aggregate object, etc.&lt;/li&gt;
&lt;li&gt;IEnumerator/IEnumerator&amp;lt;T&amp;gt;: represents iterator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It might be more straightforward if these interfaces were named IItorable/IIterator, just like &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn858237.aspx&quot;&gt;in JavaScript&lt;/a&gt;. Just keep in mind C#’s foreach is a syntactic sugar for iterator pattern, or the enumerable/enumerator pattern (Actually, &lt;a href=&quot;/posts/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern&quot;&gt;C# 5.0’s async/await syntactic sugar follows a similar awaitable/awaitor pattern&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;foreach loop vs. for loop&lt;/h3&gt;
&lt;p&gt;As fore mentioned, array T[] implements IEnumerable&amp;lt;T&amp;gt; if it is single dimensional and zero–lower bound. foreach loop for array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; next)
{
    foreach (T value in array)
    {
        next(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will be compiled into a for loop for better performance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void CompiledForEach&amp;lt;T&amp;gt;(T[] array, Action&amp;lt;T&amp;gt; next)
{
    for (int index = 0; index &amp;lt; array.Length; index++)
    {
        T value = array[index];
        next(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so is string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ForEach(string @string, Action&amp;lt;char&amp;gt; next)
{
    foreach (char value in @string)
    {
        next(value);
    }
}

public static void CompiledForEach(string @string, Action&amp;lt;char&amp;gt; next)
{
    for (int index = 0; index &amp;lt; @string.Length; index++)
    {
        char value = @string[index];
        next(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Non-generic vs. generic sequence&lt;/h3&gt;
&lt;p&gt;IEnumerable&amp;lt;T&amp;gt; is stronger-typed and should always be preferred. However, for above historical reason, some types in .NET only implement IEnumerable. To inspect these types, just need to query the IEnumerable types, and the IEnumerable&amp;lt;T&amp;gt; types, then use Except query method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;Type&amp;gt; NonGenericSequences(Assembly assembly)
{
    Type nonGenericEnumerable = typeof(IEnumerable);
    Type genericEnumerable = typeof(IEnumerable&amp;lt;&amp;gt;);
    return assembly
        .ExportedTypes
        .Where(type =&amp;gt; type != nonGenericEnumerable &amp;amp;&amp;amp; nonGenericEnumerable.GetTypeInfo().IsAssignableFrom(type))
        .Except(assembly
            .ExportedTypes
            .Where(type =&amp;gt; type != genericEnumerable &amp;amp;&amp;amp; type.IsAssignableTo(genericEnumerable)))
        .OrderBy(type =&amp;gt; type.FullName);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here Type.IsAssignableFrom is a method provided by .NET. It only works for non-generic types, and closed generic types like typeof(IEnumerable&amp;lt;string&amp;gt;). So another IsAssignableTo extension method has to be created for open generic types like typeof(IEnumerable&amp;lt;&amp;gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class TypeExtensions
{
    public static bool IsAssignableTo(this Type from, Type to)
    {
        if (to.GetTypeInfo().IsAssignableFrom(from))
        {
            return true;
        }

        if (!to.GetTypeInfo().IsGenericTypeDefinition)
        {
            return false;
        }

        if (from.GetTypeInfo().IsGenericType &amp;amp;&amp;amp; from.GetGenericTypeDefinition() == to)
        {
            return true; // Collection&amp;lt;int&amp;gt; is assignable to Collection&amp;lt;&amp;gt;.
        }

        if (to.GetTypeInfo().IsInterface &amp;amp;&amp;amp; from.GetTypeInfo().GetInterfaces().Any(
            @interface =&amp;gt; @interface.GetTypeInfo().IsGenericType &amp;amp;&amp;amp; @interface.GetGenericTypeDefinition() == to))
        {
            return true; // Collection&amp;lt;&amp;gt;/Collection&amp;lt;int&amp;gt; assignable to IEnumerable&amp;lt;&amp;gt;/ICollection&amp;lt;&amp;gt;.
        }

        Type baseOfFrom = from.GetTypeInfo().BaseType;
        return baseOfFrom != null &amp;amp;&amp;amp; IsAssignableTo(baseOfFrom, to);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code queries non-generic sequences in mscorlib.dll and System.dll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void NonGenericSequences()
{
    foreach (Type nonGenericSequence in NonGenericSequences(typeof(object).GetTypeInfo().Assembly)) // mscorlib.dll.
    {
        Trace.WriteLine(nonGenericSequence.FullName);
    }
    // System.Array
    // System.Collections.ArrayList
    // System.Collections.BitArray
    // System.Collections.CollectionBase
    // System.Collections.DictionaryBase
    // System.Collections.Hashtable
    // System.Collections.ICollection
    // System.Collections.IDictionary
    // System.Collections.IList
    // System.Collections.Queue
    // System.Collections.ReadOnlyCollectionBase
    // System.Collections.SortedList
    // System.Collections.Stack
    // System.Resources.IResourceReader
    // System.Resources.ResourceReader
    // System.Resources.ResourceSet
    // System.Runtime.Remoting.Channels.BaseChannelObjectWithProperties
    // System.Runtime.Remoting.Channels.BaseChannelSinkWithProperties
    // System.Runtime.Remoting.Channels.BaseChannelWithProperties
    // System.Security.AccessControl.AuthorizationRuleCollection
    // System.Security.AccessControl.CommonAcl
    // System.Security.AccessControl.DiscretionaryAcl
    // System.Security.AccessControl.GenericAcl
    // System.Security.AccessControl.RawAcl
    // System.Security.AccessControl.SystemAcl
    // System.Security.NamedPermissionSet
    // System.Security.Permissions.KeyContainerPermissionAccessEntryCollection
    // System.Security.PermissionSet
    // System.Security.Policy.ApplicationTrustCollection
    // System.Security.Policy.Evidence
    // System.Security.ReadOnlyPermissionSet

    foreach (Type nonGenericSequence in NonGenericSequences(typeof(Uri).GetTypeInfo().Assembly)) // System.dll.
    {
        nonGenericSequence.FullName.WriteLine();
    }
    // System.CodeDom.CodeAttributeArgumentCollection
    // System.CodeDom.CodeAttributeDeclarationCollection
    // System.CodeDom.CodeCatchClauseCollection
    // System.CodeDom.CodeCommentStatementCollection
    // System.CodeDom.CodeDirectiveCollection
    // System.CodeDom.CodeExpressionCollection
    // System.CodeDom.CodeNamespaceCollection
    // System.CodeDom.CodeNamespaceImportCollection
    // System.CodeDom.CodeParameterDeclarationExpressionCollection
    // System.CodeDom.CodeStatementCollection
    // System.CodeDom.CodeTypeDeclarationCollection
    // System.CodeDom.CodeTypeMemberCollection
    // System.CodeDom.CodeTypeParameterCollection
    // System.CodeDom.CodeTypeReferenceCollection
    // System.CodeDom.Compiler.CompilerErrorCollection
    // System.CodeDom.Compiler.TempFileCollection
    // System.Collections.Specialized.HybridDictionary
    // System.Collections.Specialized.IOrderedDictionary
    // System.Collections.Specialized.ListDictionary
    // System.Collections.Specialized.NameObjectCollectionBase
    // System.Collections.Specialized.NameObjectCollectionBase + KeysCollection
    // System.Collections.Specialized.NameValueCollection
    // System.Collections.Specialized.OrderedDictionary
    // System.Collections.Specialized.StringCollection
    // System.Collections.Specialized.StringDictionary
    // System.ComponentModel.AttributeCollection
    // System.ComponentModel.ComponentCollection
    // System.ComponentModel.Design.DesignerCollection
    // System.ComponentModel.Design.DesignerOptionService + DesignerOptionCollection
    // System.ComponentModel.Design.DesignerVerbCollection
    // System.ComponentModel.EventDescriptorCollection
    // System.ComponentModel.IBindingList
    // System.ComponentModel.IBindingListView
    // System.ComponentModel.ListSortDescriptionCollection
    // System.ComponentModel.PropertyDescriptorCollection
    // System.ComponentModel.TypeConverter + StandardValuesCollection
    // System.Configuration.ConfigXmlDocument
    // System.Configuration.SchemeSettingElementCollection
    // System.Configuration.SettingElementCollection
    // System.Configuration.SettingsAttributeDictionary
    // System.Configuration.SettingsContext
    // System.Configuration.SettingsPropertyCollection
    // System.Configuration.SettingsPropertyValueCollection
    // System.Configuration.SettingsProviderCollection
    // System.Diagnostics.CounterCreationDataCollection
    // System.Diagnostics.EventLogEntryCollection
    // System.Diagnostics.EventLogPermissionEntryCollection
    // System.Diagnostics.InstanceDataCollection
    // System.Diagnostics.InstanceDataCollectionCollection
    // System.Diagnostics.PerformanceCounterPermissionEntryCollection
    // System.Diagnostics.ProcessModuleCollection
    // System.Diagnostics.ProcessThreadCollection
    // System.Diagnostics.TraceListenerCollection
    // System.Net.Configuration.AuthenticationModuleElementCollection
    // System.Net.Configuration.BypassElementCollection
    // System.Net.Configuration.ConnectionManagementElementCollection
    // System.Net.Configuration.WebRequestModuleElementCollection
    // System.Net.CookieCollection
    // System.Net.CredentialCache
    // System.Net.WebHeaderCollection
    // System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection
    // System.Security.Authentication.ExtendedProtection.ServiceNameCollection
    // System.Security.Cryptography.AsnEncodedDataCollection
    // System.Security.Cryptography.OidCollection
    // System.Security.Cryptography.X509Certificates.X509Certificate2Collection
    // System.Security.Cryptography.X509Certificates.X509CertificateCollection
    // System.Security.Cryptography.X509Certificates.X509ChainElementCollection
    // System.Security.Cryptography.X509Certificates.X509ExtensionCollection
    // System.Text.RegularExpressions.CaptureCollection
    // System.Text.RegularExpressions.GroupCollection
    // System.Text.RegularExpressions.MatchCollection
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, most of these types can be converted to generic sequence by OfType query method.&lt;/p&gt;
&lt;h2&gt;EnumerableAssert class&lt;/h2&gt;
&lt;p&gt;In Microsoft’s unit test framework &lt;a href=&quot;https://en.wikipedia.org/wiki/MSTest&quot;&gt;MSTest&lt;/a&gt;, there are only 3 &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms182530.aspx&quot;&gt;built-in assert classes&lt;/a&gt; provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assert: for general purpose.&lt;/li&gt;
&lt;li&gt;StringAssert: for string.&lt;/li&gt;
&lt;li&gt;CollectionAssert: for ICollection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After understanding the IEnumerable&amp;lt;T&amp;gt;/IEnumerator&amp;lt;T&amp;gt; pattern in .NET, an EnumerableAssert class can be defined for IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class EnumerableAssert
{
    public static void AreSequentialEqual&amp;lt;T&amp;gt;(
        IEnumerable&amp;lt;T&amp;gt; expected,
        IEnumerable&amp;lt;T&amp;gt; actual,
        IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
        string message = null,
        params object[] parameters)
    {
        if (expected == null &amp;amp;&amp;amp; actual == null)
        {
            return;
        }

        message = string.IsNullOrEmpty(message) ? string.Empty : $&quot;{message} &quot;;
        if (expected == null)
        {
            Assert.IsNull(
                actual,
                $&quot;{message}Expected sequence is null, but actual sequence is not null.&quot;,
                parameters);
            return;
        }

        Assert.IsNotNull(
            actual,
            $&quot;{message}Expected sequence is not null, but actual sequence is null.&quot;,
            parameters);

        comparer = comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default;
        using (IEnumerator&amp;lt;T&amp;gt; expectedItorator = expected.GetEnumerator())
        using (IEnumerator&amp;lt;T&amp;gt; actualIterator = actual.GetEnumerator())
        {
            int expectedIndex = 0;
            for (; expectedItorator.MoveNext(); expectedIndex++)
            {
                Assert.IsTrue(
                    actualIterator.MoveNext(),
                    $&quot;{message}Expected sequence has more than {expectedIndex} value(s), but actual sequence has {expectedIndex} value(s).&quot;,
                    parameters);

                T expectedValue = expectedItorator.Current;
                T actualValue = actualIterator.Current;
                Assert.IsTrue(
                    comparer.Equals(expectedValue, actualValue),
                    $&quot;{message}Expected and actual sequences&apos; values are not equal at index {expectedIndex}. Expected value is {expectedValue}, but actual value is {actualValue}.&quot;,
                    parameters);
            }

            Assert.IsFalse(
                actualIterator.MoveNext(),
                $&quot;{message}Expected sequence has {expectedIndex} value(s), but actual sequence has more than {expectedIndex} value(s).&quot;,
                parameters);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a few other assert methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void IsEmpty&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.IsTrue(actual.IsEmpty(), message, parameters);
}

public static void IsNullOrEmpty&amp;lt;T&amp;gt;
    (IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters) =&amp;gt;
        Assert.IsTrue(actual.IsNullOrEmpty(), message, parameters);

public static void Any&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.IsTrue(actual.Any(), message, parameters);
}

public static void Single&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.AreEqual(1, actual.Count(), message, parameters);
}

public static void Multiple&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    using (IEnumerator&amp;lt;T&amp;gt; iterator = actual.GetEnumerator())
    {
        Assert.IsTrue(iterator.MoveNext() &amp;amp;&amp;amp; iterator.MoveNext(), message, parameters);
    }
}

public static void Contains&amp;lt;T&amp;gt;(
    T expected,
    IEnumerable&amp;lt;T&amp;gt; actual,
    IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
    string message = null,
    params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.IsTrue(actual.Contains(expected, comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default), message, parameters);
}

public static void DoesNotContain&amp;lt;T&amp;gt;(
    T expected,
    IEnumerable&amp;lt;T&amp;gt; actual,
    IEqualityComparer&amp;lt;T&amp;gt; comparer = null,
    string message = null,
    params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.IsFalse(actual.Contains(expected, comparer ?? EqualityComparer&amp;lt;T&amp;gt;.Default), message, parameters);
}

public static void Count&amp;lt;T&amp;gt;(
    int expected, IEnumerable&amp;lt;T&amp;gt; actual, string message = null, params object[] parameters)
{
    Assert.IsNotNull(actual, message, parameters);
    Assert.AreEqual(expected, actual.Count(), message, parameters);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These methods, especially AreSequentialEqual, will be used in this tutorial later.&lt;/p&gt;
</content:encoded></item><item><title>The protocol of AJAX</title><link>https://dixin.github.io/posts/the-protocol-of-ajax/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-protocol-of-ajax/</guid><description>This is a true story. This morning I went to office by train of Beijing subway, and 4 developers were sitting next to me and talking about Web development and their Web product. After a while, someone</description><pubDate>Tue, 09 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is a true story. This morning I went to office by train of Beijing subway, and 4 developers were sitting next to me and talking about Web development and their Web product. After a while, someone asked an interesting question: What is the protocol of AJAX?&lt;/p&gt;
&lt;p&gt;Dev A said, “Its protocol is XML.”&lt;/p&gt;
&lt;p&gt;Dev B argued, “No. The protocol should be Silverlight.”&lt;/p&gt;
&lt;p&gt;Dev C was confused, “As I remember, it should be something sounds like HttpSilverlight.”&lt;/p&gt;
&lt;p&gt;D spoke like a dev lead, “No you all didn’t get the point. AJAX itself is a kind of protocol. So, the protocol of AJAX is just AJAX.”&lt;/p&gt;
&lt;p&gt;So finally, they made the agreement.&lt;/p&gt;
</content:encoded></item><item><title>Introducing LINQ (3) Programming Paradigms</title><link>https://dixin.github.io/posts/introducing-linq-3-programming-paradigms/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-3-programming-paradigms/</guid><description>\] - \]</description><pubDate>Tue, 02 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=Introducing%20LINQ&quot;&gt;Introducing LINQ&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Programming paradigm is the fundamental style of programming.&lt;/p&gt;
&lt;h2&gt;Imperative vs. declarative&lt;/h2&gt;
&lt;h3&gt;LINQ&lt;/h3&gt;
&lt;p&gt;This is the fore mentioned example of collection processing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class Imperative
{
    public static List&amp;lt;Person&amp;gt; FilterAndOrderByAge(IEnumerable&amp;lt;Person&amp;gt; source)
    {
        List&amp;lt;Person&amp;gt; results = new List&amp;lt;Person&amp;gt;();
        foreach (Person person in source)
        {
            if (person.Age &amp;gt;= 18)
            {
                results.Add(person);
            }
        }

        Comparison&amp;lt;Person&amp;gt; personComparison = delegate(Person a, Person b)
            {
                int ageComparison = 0 - a.Age.CompareTo(b.Age);
                return ageComparison != 0
                    ? ageComparison
                    : string.Compare(a.Name, b.Name, StringComparison.Ordinal);
            };
        results.Sort(personComparison);

        return results;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the same processing with LINQ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class LinqToObjects
{
    public static IEnumerable&amp;lt;Person&amp;gt; FilterAndOrderByAge(IEnumerable&amp;lt;Person&amp;gt; source)
    {
        return from person in source
               where person.Age &amp;gt;= 18
               orderby person.Age descending, person.Name
               select person;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their styles/paradigms are very different:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first method has a &lt;a href=&quot;https://en.wikipedia.org/wiki/Imperative_programming&quot;&gt;imperative style/paradigm&lt;/a&gt;: it focuses on how to implement the query by providing the explicit steps of the algorithm.&lt;/li&gt;
&lt;li&gt;The second method has &lt;a href=&quot;https://en.wikipedia.org/wiki/Declarative_programming&quot;&gt;declarative style/paradigm&lt;/a&gt;: it declares what is the query, like &quot;orderby person.Age descending&quot;. It is abstract. It does not provide the steps of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Sorting_algorithm&quot;&gt;sorting algorithm&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Imperative and declarative programming paradigms are different philosophies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Imperative paradigm is about thinking from bottom up. It explicitly provides each action to be taken, and a sequence of action can be a “bigger” action, and so on. Computation is to execute these actions.
&lt;ul&gt;
&lt;li&gt;Object oriented programming of C# is a typical imperative paradigm.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Declarative paradigm is about thinking from top down. It is higher level, more abstract, has clear correspondence to mathematical logic, where can be considered as theories of a formal logic, and computations can be considered as deductions in that logic space. As a higher level and more abstract paradigm, it usually minimize or eliminate &lt;a href=&quot;https://en.wikipedia.org/wiki/Side_effect_(computer_science)&quot;&gt;side effects&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Functional_programming&quot;&gt;Functional programming&lt;/a&gt; is a typical declarative paradigm, and it is the major topic of LINQ.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SQL&lt;/h3&gt;
&lt;p&gt;As fore mentioned, LINQ is SQL-like. The following SQL query is very declarative:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT [ProductName], [UnitPrice] FROM [Products] ORDER BY [UnitPrice] DESC
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;XAML&lt;/h3&gt;
&lt;p&gt;Another declarative example is XAML. Compare C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Button button = new Button();
button.Content = &quot;Submit&quot;;
button.HorizontalAlignment = HorizontalAlignment.Left;
button.VerticalAlignment = VerticalAlignment.Top;
button.Margin = new Thickness(10, 10, 0, 0);
button.Width = 75;
button.Click += this.Submit;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with the following XAML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Button Content=&quot;Submit&quot; HorizontalAlignment=&quot;Left&quot; VerticalAlignment=&quot;Top&quot; Margin=&quot;10,10,0,0&quot; Width=&quot;75&quot; Click=&quot;Submit&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above C# is imperative and above XAML is declarative.&lt;/p&gt;
&lt;h3&gt;HTML&lt;/h3&gt;
&lt;p&gt;Another controversial topic is HTML. In &lt;a href=&quot;http://www.amazon.com/CLR-Via-C-Pro-Developer/dp/0735621632&quot;&gt;CLR via C# 2nd edition&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Jeffrey_Richter&quot;&gt;Jeffrey Richter&lt;/a&gt; said (This paragraph is removed in the &lt;a href=&quot;http://www.amazon.com/CLR-via-Pro-Developer-Jeffrey-Richter/dp/0735627045&quot;&gt;3rd edition&lt;/a&gt;),&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An example of declarative programming is when a person creates a text file and explicitly enters HTML tags into the file by using an editor such as Notepad.exe. In this scenario, the HTML tags act as instructions that are eventually processed by the Internet browser so that it can lay out the page in a window. The HTML tags are declaring how the program (Web page) should be displayed and operate, and it&apos;s the programmer who decides what tags to use and where. Many hard-core programmers don&apos;t consider HTML programming to be real programming, but I do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Similar to C# vs. XAML, if comparing with &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var img = document.CreateElement(&quot;img&quot;);
img.src = &quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_b.jpg&quot;;
img.style.width = &quot;300px&quot;;
img.style.height = &quot;200px&quot;;
img.title = &quot;Microsoft Way&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;img src=&quot;https://farm3.staticflickr.com/2875/9215169916_f8fa57c3da_b.jpg&quot; style=&quot;width: 300px; height: 200px;&quot; title=&quot;Microsoft Way&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then HTML is the declarative.&lt;/p&gt;
&lt;h2&gt;Programming paradigms and languages&lt;/h2&gt;
&lt;p&gt;Imperative, declarative, object-oriented, functional, ... There are &lt;a href=&quot;https://en.wikipedia.org/wiki/Programming_paradigm&quot;&gt;many paradigms for programming&lt;/a&gt;. The common paradigms can be categorized as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Declarative_programming&quot;&gt;Declarative programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Dataflow_programming&quot;&gt;Dataflow programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Reactive_programming&quot;&gt;Reactive programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Functional_programming&quot;&gt;Functional programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Event-driven_programming&quot;&gt;Event-driven programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Generic_programming&quot;&gt;Generic programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Imperative_programming&quot;&gt;Imperative programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Object-oriented_programming&quot;&gt;Object-oriented programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Class-based_programming&quot;&gt;Class-based programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Prototype-based_programming&quot;&gt;Prototype-based programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Procedural_programming&quot;&gt;Procedural programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Metaprogramming&quot;&gt;Metaprogramming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Reflection_(computer_programming)&quot;&gt;Reflective programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Attribute-oriented_programming&quot;&gt;Attribute-oriented programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Parallel_computing&quot;&gt;Parallel programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Structured_programming&quot;&gt;Structured programming&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Aspect-oriented_programming&quot;&gt;Aspect-oriented programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One programming language can adopt several paradigms. Take C as an example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C is typically used as procedural;&lt;/li&gt;
&lt;li&gt;It can also &lt;a href=&quot;http://www.planetpdf.com/codecuts/pdfs/ooc.pdf&quot;&gt;be used in object-oriented programming&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another example is JavaScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JavaScript is imperative by default, it is
&lt;ul&gt;
&lt;li&gt;Procedural&lt;/li&gt;
&lt;li&gt;Prototype-based&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It is also &lt;a href=&quot;http://www.ibm.com/developerworks/web/library/wa-javascript.html?S_TACT=105AGX52&amp;amp;S_CMP=cn-a-web&quot;&gt;elegantly functional&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And finally, C# is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Declarative (attribute, regular expression, data annotation, code contracts, …)
&lt;ul&gt;
&lt;li&gt;Reactive (&lt;a href=&quot;http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx&quot;&gt;Rx&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Functional (lambda expression, higher-order function, LINQ, …)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event-driven (event)&lt;/li&gt;
&lt;li&gt;Generic&lt;/li&gt;
&lt;li&gt;Imperative (by default)
&lt;ul&gt;
&lt;li&gt;Class-based Object-oriented (class)&lt;/li&gt;
&lt;li&gt;Procedural (static class, static method, using static)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Metaprogramming (code DOM, expression tree, IL emit, compiler as a service)
&lt;ul&gt;
&lt;li&gt;Reflective (reflection)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Parallel (TPL, Parallel LINQ)&lt;/li&gt;
&lt;li&gt;Structured
&lt;ul&gt;
&lt;li&gt;Aspect-oriented (&lt;a href=&quot;https://msdn.microsoft.com/en-us/magazine/gg490353.aspx&quot;&gt;Unity&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to Microsoft and &lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;Anders Hejlsberg&lt;/a&gt;, C#/.NET is powerful and productive, work in many different scenarios.&lt;/p&gt;
&lt;h2&gt;Declarative C#&lt;/h2&gt;
&lt;p&gt;C# 3.0+ introduced a lot of syntax to make it more declarative. For example, the object initializer collection initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Person&amp;gt; team = new List&amp;lt;Person&amp;gt;();
Person anna = new Person();
anna.Age = 25;
anna.Name = &quot;Anna&quot;;
team.Add(anna);
Person bob = new Person();
bob.Age = 30;
bob.Name = &quot;Bob&quot;;
team.Add(bob);
Person charlie = new Person();
charlie.Age = 35;
charlie.Name = &quot;Charlie&quot;;
team.Add(charlie);
Person dixin = new Person();
dixin.Age = 30;
dixin.Name = &quot;Dixin&quot;;
team.Add(charlie);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comparing to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Person&amp;gt; team = new List&amp;lt;Person&amp;gt;
    {
        new Person() { Age = 25, Name = &quot;Anna&quot; }, 
        new Person() { Age = 30, Name = &quot;Bob&quot; }, 
        new Person() { Age = 35, Name = &quot;Charlie&quot; }, 
        new Person() { Age = 30, Name = &quot;Dixin&quot; }, 
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the first code snippet is more imperative, and the second is more declarative. Actually, there are many other declarative aspects in C# programming.&lt;/p&gt;
&lt;h3&gt;Attribute&lt;/h3&gt;
&lt;p&gt;Actually, declarative programming in C# is not something brand new. C# has attributes from the beginning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[HandleError]
public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return this.View();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Regular expression&lt;/h3&gt;
&lt;p&gt;Regular expressions can be considered declarative:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.ComponentModel.DataAnnotations
{
    using System.Text.RegularExpressions;

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
    public sealed class EmailAddressAttribute : DataTypeAttribute
    {
        private static readonly Regex emailRegex = new Regex(
            &quot;^((([a-z]|\\d|[!#\\$%&amp;amp;&apos;\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&amp;amp;&apos;\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$&quot;,
            RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);

        public EmailAddressAttribute()
            : base(DataType.EmailAddress)
        {
            this.ErrorMessage = DataAnnotationsResources.EmailAddressAttribute_Invalid;
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }

            string text = value as string;
            return text != null &amp;amp;&amp;amp; emailRegex.Match(text).Length &amp;gt; 0;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Data annotation&lt;/h3&gt;
&lt;p&gt;Data Annotation is intuitively declarative:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.NameRequired))]
    [StringLength(1, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.InvalidName))]
    public string Name { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.AgeRequired))]
    [Range(0, 123, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.InvalidAge))] // https://en.wikipedia.org/wiki/Oldest_people
    public int Age { get; set; }

    [EmailAddress(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = nameof(Resources.InvalidEmail))]
    public string Email { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Code contracts&lt;/h3&gt;
&lt;p&gt;C# 3.0 and 4.0 introduced &lt;a href=&quot;http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx&quot;&gt;code contracts&lt;/a&gt;, which is also declarative:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    private readonly string name;

    private readonly int age;

    public Person(string name, int age)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(!string.IsNullOrWhiteSpace(name));
        Contract.Requires&amp;lt;ArgumentOutOfRangeException&amp;gt;(age &amp;gt;= 0);

        this.name = name;
        this.age = age;
    }

    public string Name
    {
        [Pure]
        get
        {
            Contract.Ensures(!string.IsNullOrWhiteSpace(Contract.Result&amp;lt;string&amp;gt;()));

            return this.name;
        }
    }

    public int Age
    {
        [Pure]
        get
        {
            Contract.Ensures(Contract.Result&amp;lt;int&amp;gt;() &amp;gt;= 0);

            return this.age;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;LINQ and Functional C#&lt;/h3&gt;
&lt;p&gt;Above LinqToObjects.FilterAndOrderByAge method implementation is equivalent to (actually is compiled to):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class LinqToObjects
{
    public static IEnumerable&amp;lt;Person&amp;gt; FilterAndOrderByAge(IEnumerable&amp;lt;Person&amp;gt; source)
    {
        return source
            .Where(person =&amp;gt; person.Age &amp;gt;= 18)
            .OrderByDescending(person =&amp;gt; person.Age)
            .ThenBy(person =&amp;gt; person.Name);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This LINQ to Objects program is functional, and purely functional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Type inference&lt;/li&gt;
&lt;li&gt;Extension method&lt;/li&gt;
&lt;li&gt;Lambda expression as anonymous function&lt;/li&gt;
&lt;li&gt;Higher order function&lt;/li&gt;
&lt;li&gt;Query expression/Query method&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since C# 3.0, more and more language features has been added to C#, which make C# more and more functional. Besides above features, there are more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Auto property, auto property initializer, getter only auto property&lt;/li&gt;
&lt;li&gt;Object initializer, collection initializer, index initializer, extension Add in collection initializers&lt;/li&gt;
&lt;li&gt;Anonymous type&lt;/li&gt;
&lt;li&gt;Partial class, partial interface, partial method&lt;/li&gt;
&lt;li&gt;Lambda expression as expression tree, expression-bodied members&lt;/li&gt;
&lt;li&gt;Async lambda expression&lt;/li&gt;
&lt;li&gt;Covariance and contravariance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, these language features will be explained in detail.&lt;/p&gt;
</content:encoded></item><item><title>Resolving The nvlddmkm.sys Blue Screen Issue</title><link>https://dixin.github.io/posts/resolving-the-nvlddmkm-sys-blue-screen-issue/</link><guid isPermaLink="true">https://dixin.github.io/posts/resolving-the-nvlddmkm-sys-blue-screen-issue/</guid><description>I started to use ATI discrete graphic cards since 2002. At the end of 2009, I got my first pair of NVIDIA cards,  ,</description><pubDate>Sat, 30 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I started to use ATI discrete graphic cards since 2002. At the end of 2009, I got my first pair of NVIDIA cards, &lt;a href=&quot;http://www.notebookcheck.net/NVIDIA-GeForce-GTX-260M-SLI.18909.0.html&quot;&gt;GTX260M SLI&lt;/a&gt; , and recently I after I upgraded the driver to &lt;a href=&quot;http://www.nvidia.com/object/notebook_winvista_win7_x64_195.62_whql.html&quot;&gt;the latest 195 release&lt;/a&gt;, I encountered the blue screen failure on my laptop with Windows 7.&lt;/p&gt;
&lt;p&gt;According to the blue screen, it is caused by nvlddmkm.sys. This is a file installed by the driver. By search the Windows directory, there are four nvlddmkm.sys files installed. And these two files has different signing time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C:\Windows\System32\DriverStore\FileRepository\nv_lh.inf_amd64_neutral_bc69f20e3115af59\nvlddmkm.sys&lt;/li&gt;
&lt;li&gt;C:\Windows\winsxs\amd64_nv_lh.inf_31bf3856ad364e35_6.1.7600.16385_none_4a5c7d78e486512b\nvlddmkm.sys&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/nvlddmkm.sys_1196FDC4.gif&quot; alt=&quot;nvlddmkm.sys&quot; title=&quot;nvlddmkm.sys&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The other two files has newer signing time:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/nvlddmkm.sysnewer_2011F9E9.gif&quot; alt=&quot;nvlddmkm.sys-newer&quot; title=&quot;nvlddmkm.sys-newer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So I guess this is the reason of the blue screen: the driver installer has abug that, when upgrading the driver, the installer doesn’t upgrade all nvlddmkm.sys files. And the solution is just replace the two old files. Up to now, the blue screen never appear again.&lt;/p&gt;
</content:encoded></item><item><title>The Order Issue of XAML Attributes</title><link>https://dixin.github.io/posts/the-order-issue-of-xaml-attributes/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-order-issue-of-xaml-attributes/</guid><description>When programming Silverlight, it is neccessary to pay attention to the order of the XAML element’s attributes. Here is a simple example.</description><pubDate>Thu, 17 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When programming Silverlight, it is neccessary to pay attention to the order of the XAML element’s attributes. Here is a simple example.&lt;/p&gt;
&lt;p&gt;Here is the ListBox in the XAML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ListBox SelectedItem=&quot;{Binding SelectedItem}&quot; ItemsSource=&quot;{Binding Items}&quot; x:Name=&quot;listBox&quot;&amp;gt;
    &amp;lt;ListBox.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;TextBlock Text=&quot;{Binding}&quot; /&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ListBox.ItemTemplate&amp;gt;
&amp;lt;/ListBox&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the the data binding in the code-behind:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public MainPage()
{
    this.InitializeComponent();

    this.listBox.DataContext = new Data();
}

public class Data
{
    public int[] Items
    {
        get
        {
            return new int[] { 0, 1, 2, 3 };
        }
    }

    public int SelectedItem
    {
        get
        {
            return 2;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We hope 4 items appear in this ListBox, and the third one is selected. But it won’t work as expected:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_4C692BD9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The third item is not selected because the SelectedItem attribute is binded before ItemsSource. So when SelectedItem is set, there is no ItemsSource to check.&lt;/p&gt;
&lt;p&gt;The solution is to swap the two attributes, put ItemsSource before SelectedItem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ListBox ItemsSource=&quot;{Binding Items}&quot; SelectedItem=&quot;{Binding SelectedItem}&quot; x:Name=&quot;listBox&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the control works:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_78A5B2BD.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The conclusion is, the XAML attributes are order-sensitive. I am wondering whether this is by design…&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Features (10) Query Expression</title><link>https://dixin.github.io/posts/understanding-csharp-features-10-query-expression/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-10-query-expression/</guid><description>\] - \]</description><pubDate>Wed, 16 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;C# query expression defines a SQL-like query. The following is a query expression working on an IEnumerable&amp;lt;int&amp;gt; sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LinqToObjects
{
    public static IEnumerable&amp;lt;int&amp;gt; Positive(IEnumerable&amp;lt;int&amp;gt; source)
    {
        return from value in source
               where value &amp;gt; 0
               select value;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following query expression works on a IQeuryable&amp;lt;T&amp;gt; sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string[] ProductNames(string categoryName)
{
    using (AdventureWorksDataContext adventureWorks = new AdventureWorksDataContext())
    {
        IQueryable&amp;lt;string&amp;gt; query =
            from product in adventureWorks.Products
            where product.ProductSubcategory.ProductCategory.Name == categoryName
            orderby product.ListPrice ascending
            select product.Name; // Define query.
        return query.ToArray(); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Syntax&lt;/h2&gt;
&lt;p&gt;The syntax of C# query expression is like SQL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from [Type] identifier in source
[from [Type] identifier in source]
[join [Type] identifier in source on expression equals expression [into identifier]]
[let identifier = expression]
[where predicate]
[orderby ordering [ascending | descending][, ordering [ascending | descending], …]]
select expression | group expression by key [into identifier]
[continueation]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which involves query keywords:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;from&lt;/li&gt;
&lt;li&gt;in&lt;/li&gt;
&lt;li&gt;join, on, equals&lt;/li&gt;
&lt;li&gt;let&lt;/li&gt;
&lt;li&gt;where&lt;/li&gt;
&lt;li&gt;orderby, ascending, descending&lt;/li&gt;
&lt;li&gt;select&lt;/li&gt;
&lt;li&gt;group, by&lt;/li&gt;
&lt;li&gt;into&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These syntax and examples will be explained in detail later.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;Query expression is translated (compiled) to query methods (also called query operators) at compile time:&lt;/p&gt;
&lt;p&gt;&amp;lt;table border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; width=&quot;672&quot;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;Query expression&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Query method&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;single from clause with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;multiple from clauses with select clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;SelectMany&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;T in from/join clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Cast&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause without into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Join&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;join clause with into&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupJoin&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;let clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Select&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;where clauses&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Where&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with or without ascending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderBy, ThenBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;orderby clause with descending&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;OrderByDescending, ThenByDescending&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;group clause&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;GroupBy&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;297&quot;&amp;gt;into with continuation&amp;lt;/td&amp;gt;&amp;lt;td valign=&quot;top&quot; width=&quot;373&quot;&amp;gt;Nested query&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;For example, the above 2 query expressions are compiled into query method calls:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LinqToObjects
{
    public static IEnumerable&amp;lt;int&amp;gt; Positive(IEnumerable&amp;lt;int&amp;gt; source)
    {
        return source.Where(value =&amp;gt; value &amp;gt; 0);
    }
}

public static partial class LinqToSql
{
    public static string[] ProductNames(string categoryName)
    {
        using (NorthwindDataContext database = new NorthwindDataContext())
        {
            IQueryable&amp;lt;string&amp;gt; query = database.Products
                .Where(product =&amp;gt; product.Category.CategoryName == categoryName)
                .Select(product =&amp;gt; product.ProductName); // Define query.
            return query.ToArray(); // Execute query.
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Positive method, source is an IEnumerable&amp;lt;T&amp;gt;, so query expression is compiled to:
&lt;ul&gt;
&lt;li&gt;a Where query method call on IEnumerbale&amp;lt;T&amp;gt;. The Where method of IEnumerable&amp;lt;T&amp;gt; has:
&lt;ul&gt;
&lt;li&gt;a Func&amp;lt;T, bool&amp;gt; parameter, the where clause is compiled to a anonymous method, which can be represented by a lambda expression: value =&amp;gt; value &amp;gt; 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In ProductNames method, database.Products is an IQueryable&amp;lt;Product&amp;gt;, so query expression is compiled to:
&lt;ul&gt;
&lt;li&gt;a Where query method call on IQueryable&amp;lt;Product&amp;gt;. The Where method of IQueryable&amp;lt;Product&amp;gt; has a:
&lt;ul&gt;
&lt;li&gt;Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; parameter, so the where clause is compiled to a expression tree, which can be represented by a lambda expression: product =&amp;gt; product.Category.CategoryName == categoryName&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;a Select query method call on IQueryable&amp;lt;Product&amp;gt;. The Select method of IQueryable&amp;lt;Product&amp;gt; has a:
&lt;ul&gt;
&lt;li&gt;Expression&amp;lt;Func&amp;lt;Product, TResult&amp;gt;&amp;gt; parameter. Here TResult is string, because product.ProductName is slected, so the select clause is compiled to an Expression&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt; expression tree, which can be represented by a lambda expression: product =&amp;gt; product.ProductName&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If completely desuagring above extension methods and lambda expression syntax, the query expressions in Positive is actually compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class CompiledLinqToObjects
{
    [CompilerGenerated]
    private static Func&amp;lt;int, bool&amp;gt; cachedAnonymousMethodDelegate;

    [CompilerGenerated]
    private static bool Positive0(int value)
    {
        return value &amp;gt; 0;
    }

    public static IEnumerable&amp;lt;int&amp;gt; Positive(IEnumerable&amp;lt;int&amp;gt; source)
    {
        return Enumerable.Where(
            source,
            cachedAnonymousMethodDelegate ?? (cachedAnonymousMethodDelegate = Positive0));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the query expression in ProductNames is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class CompiledLinqToSql
{
    [CompilerGenerated]
    private sealed class Closure
    {
        internal string categoryName;
    }

    internal static string[] ProductNames(string categoryName)
    {
        Closure closure = new Closure { categoryName = categoryName };
        AdventureWorks adventureWorks = new AdventureWorks();

        try
        {
            ParameterExpression product = Expression.Parameter(typeof(Product), &quot;product&quot;);

            // Define query
            IQueryable&amp;lt;string&amp;gt; query = Queryable.Select(
                Queryable.Where(
                    adventureWorks.Products, 
                    Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(
                        Expression.Equal( // =&amp;gt; product.ProductSubCategory.ProductCategory.Name == closure.categoryName
                            Expression.Property(
                                Expression.Property( // product.ProductSubCategory.ProductCategory.Name
                                    Expression.Property(product, &quot;ProductSubCategory&quot;), // product.ProductSubCategory
                                    &quot;ProductCategory&quot;), // ProductSubCategory.ProductCategory
                                &quot;Name&quot;), // ProductCategory.Name
                            Expression.Field( // Or Expression.Constant(categoryName) works too.
                                Expression.Constant(closure), &quot;categoryName&quot;), // closure.categoryName
                            false,
                            typeof(string).GetMethod(&quot;op_Equals&quot;)), // ==
                        product)),
                Expression.Lambda&amp;lt;Func&amp;lt;Product, string&amp;gt;&amp;gt;( // product =&amp;gt; product.ProductName
                    Expression.Property(product, &quot;ProductName&quot;), // =&amp;gt; product.ProductName
                    product)); // product =&amp;gt;

            // Execute query.
            return query.ToArray();
        }
        finally
        {
            adventureWorks.Dispose();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In ProductNames method, the categoryName parameter is wrapped into a Closure class.&lt;/p&gt;
&lt;h2&gt;Query expression pattern&lt;/h2&gt;
&lt;p&gt;To enable above query keyword, the source for query expression must provide some certain methods. The following classes demonstrate those methods for full support of above query keywords:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class Source
{
    public abstract Source&amp;lt;T&amp;gt; Cast&amp;lt;T&amp;gt;();
}

public abstract class Source&amp;lt;T&amp;gt; : Source
{
    public abstract Source&amp;lt;T&amp;gt; Where(Func&amp;lt;T, bool&amp;gt; predicate);

    public abstract Source&amp;lt;TResult&amp;gt; Select&amp;lt;TResult&amp;gt;(Func&amp;lt;T, TResult&amp;gt; selector);

    public abstract Source&amp;lt;TResult&amp;gt; SelectMany&amp;lt;TSelector, TResult&amp;gt;(
        Func&amp;lt;T, Source&amp;lt;TSelector&amp;gt;&amp;gt; selector,
        Func&amp;lt;T, TSelector, TResult&amp;gt; resultSelector);

    public abstract Source&amp;lt;TResult&amp;gt; Join&amp;lt;TInner, TKey, TResult&amp;gt;(
        Source&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, TInner, TResult&amp;gt; resultSelector);

    public abstract Source&amp;lt;TResult&amp;gt; GroupJoin&amp;lt;TInner, TKey, TResult&amp;gt;(
        Source&amp;lt;TInner&amp;gt; inner,
        Func&amp;lt;T, TKey&amp;gt; outerKeySelector,
        Func&amp;lt;TInner, TKey&amp;gt; innerKeySelector,
        Func&amp;lt;T, Source&amp;lt;TInner&amp;gt;, TResult&amp;gt; resultSelector);

    public abstract OrderedSource&amp;lt;T&amp;gt; OrderBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    public abstract OrderedSource&amp;lt;T&amp;gt; OrderByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    public abstract Source&amp;lt;SoourceGroup&amp;lt;TKey, T&amp;gt;&amp;gt; GroupBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    public abstract Source&amp;lt;SoourceGroup&amp;lt;TKey, TElement&amp;gt;&amp;gt; GroupBy&amp;lt;TKey, TElement&amp;gt;(
        Func&amp;lt;T, TKey&amp;gt; keySelector,
        Func&amp;lt;T, TElement&amp;gt; elementSelector);
}

public abstract class OrderedSource&amp;lt;T&amp;gt; : Source&amp;lt;T&amp;gt;
{
    public abstract OrderedSource&amp;lt;T&amp;gt; ThenBy&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);

    public abstract OrderedSource&amp;lt;T&amp;gt; ThenByDescending&amp;lt;TKey&amp;gt;(Func&amp;lt;T, TKey&amp;gt; keySelector);
}

public abstract class SoourceGroup&amp;lt;TKey, T&amp;gt; : Source&amp;lt;T&amp;gt;
{
    public abstract TKey Key { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the query methods are all demonstrated as instance methods. Actually either instance or extension methods will work. .NET provides built-in query methods as extension methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Linq.Enumerable class contains the extension methods for IEnumerable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;System.Linq.Queryable class contains the extension methods for IQueryable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The built-in query methods are all for sequences - either IEnumerable&amp;lt;T&amp;gt; or IQueryable&amp;lt;T&amp;gt;. However, the query expression pattern applies to anything (any CLR type). To demonstrate &lt;a href=&quot;http://www.infoq.com/interviews/LINQ-Erik-Meijer&quot;&gt;this great flexibility&lt;/a&gt;, a query method can be implemented for int (System.Int32 type):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Int32Extensions
{
    public static TResult Select&amp;lt;TResult&amp;gt;(this int value, Func&amp;lt;int, TResult&amp;gt; selector) =&amp;gt; selector(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Select method follows the Select signature in above query expression pattern. Also, notice in above compilation table, Select query method can be compiled from the select query keyword. As a result, int (System.Int32 type) now can be queried by LINQ query expression with select clause:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void QueryExpression()
{
    int query1 = from zero in default(int) // 0
                 select zero; // 0

    string query2 = from three in 1 + 2 // 3
                    select (three + 4).ToString(CultureInfo.InvariantCulture); // &quot;7&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks a little too fancy. Actually, at compile time, they become just calls to above Select extension method for int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void QueryMethod()
{
    int query1 = Int32Extensions.Select(default(int), zero =&amp;gt; zero);

    string query2 = Int32Extensions.Select(
        (1 + 2), three =&amp;gt; (three + 4).ToString(CultureInfo.InvariantCulture)); // &quot;7&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a Where query method is implemented for int, then the where keyword can be used in LINQ queries to int, and so on.&lt;/p&gt;
&lt;p&gt;Here the experiment with Select can go a little further. Select’s int argument can be replaced with any type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ObjectExtensions
{
    public static TResult Select&amp;lt;TSource, TResult&amp;gt;(this TSource value, Func&amp;lt;TSource, TResult&amp;gt; selector) =&amp;gt; selector(value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then similarly there is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string query = from newGuild in Guid.NewGuid()
               select newGuild.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which will be compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string query = ObjectExtensions.Select(Guid.NewGuid(), newGuild =&amp;gt; newGuild.ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This powerful design makes LINQ query syntax possible for any data type.&lt;/p&gt;
&lt;p&gt;Some tool, like &lt;a href=&quot;https://www.jetbrains.com/resharper&quot;&gt;Resharper&lt;/a&gt;, a powerful &lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/EA4AC039-1B5C-4D11-804E-9BEDE2E63ECF&quot;&gt;extension for Visual Studio&lt;/a&gt;, can compile query expressions to query methods at design time:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Understand.0-Features-7-Query-Expression_14776/image_2.png&quot;&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Windows-Live-Writer/Understand.0-Features-7-Query-Expression_14776/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is very useful to find out the truth of LINQ query.&lt;/p&gt;
&lt;h2&gt;Query expression vs. query method&lt;/h2&gt;
&lt;p&gt;Regarding query expression is compiled to query method calls, either of them can be used when coding a LINQ query. In this tutorial prefers query methods rather than query expression, because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Query methods are desugared from query expression, so they are closer to the “truth”.&lt;/li&gt;
&lt;li&gt;Query expressions can express some query methods, but not all the overloads of them.&lt;/li&gt;
&lt;li&gt;Consistency. Query expression does not cover all query scenarios/query overloads, then query method has to be used, so that the query ends up a mix of query expression and query methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, built-in query method Select has 2 overloads:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, bool&amp;gt; predicate);

public static IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, int, bool&amp;gt; predicate);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first Where logic can be expressed by query expression, as fore mentioned, but the second Where cannot. The following query cannot be implemented with query expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LinqToObjects
{
    public static IEnumerable&amp;lt;Person&amp;gt; Where
        (IEnumerable&amp;lt;Person&amp;gt; source) =&amp;gt; source.Where((person, index) =&amp;gt; person.Age &amp;gt;= 18 &amp;amp;&amp;amp; index%2 == 0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example is, query expression cannot page the query results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string[] ProductNames(string categoryName, int pageSize, int pageIndex)
{
    using (AdventureWorksDataContext adventureWorks = new AdventureWorksDataContext())
    {
        IQueryable&amp;lt;string&amp;gt; query =
            (from product in adventureWorks.Products
             where product.ProductSubcategory.ProductCategory.Name == categoryName
             orderby product.ListPrice ascending
             select product.Name)
            .Skip(pageSize * checked(pageIndex - 1))
            .Take(pageSize); // Define query.
        return query.ToArray(); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Query methods look more consistent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static string[] ProductNames2(string categoryName, int pageSize, int pageIndex)
{
    using (AdventureWorksDataContext adventureWorks = new AdventureWorksDataContext())
    {
        IQueryable&amp;lt;string&amp;gt; query = adventureWorks
            .Products
            .Where(product =&amp;gt; product.ProductSubcategory.ProductCategory.Name == categoryName)
            .OrderBy(product =&amp;gt; product.ListPrice)
            .Select(product =&amp;gt; product.Name)
            .Skip(pageSize * checked(pageIndex - 1))
            .Take(pageSize); // Define query.
        return query.ToArray(); // Execute query.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Query expression will be explained in detail in a later chapter. It is also essentially a powerful tool to build functional workflow, which will also be explained in another chapter.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Features (9) Partial Method</title><link>https://dixin.github.io/posts/understanding-csharp-features-9-partial-method/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-9-partial-method/</guid><description>\] - \]</description><pubDate>Wed, 16 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;The partial keyword&lt;/h2&gt;
&lt;p&gt;The partial keyword is introduced since C# 2.0. It enables class/struct/interface definition to be split to multiple code files at design time. For example, When creating a WinForm application project in VisualStudio, a form definition is typically like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class MainForm : Form
{
    public MainForm()
    {
        this.InitializeComponent();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The InitializeCompoment method is auto generated in the MainForm.Designer.cs file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;partial class MainForm
{
    #region Windows Form Designer generated code

    private void InitializeComponent()
    {
        this.SuspendLayout();
        // 
        // MainForm
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(282, 255);
        this.Name = &quot;MainForm&quot;;
        this.Text = &quot;Form1&quot;;
        this.ResumeLayout(false);
    }

    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The partial class improves the productivity when a type has some code implemented by developer, some other code auto generated.&lt;/p&gt;
&lt;p&gt;C# 3.0 introduces partial methods. For example, In LINQ to SQL dbml, The MSLinqToSQLGenerator generates definition like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class WebOSUser : INotifyPropertyChanging, INotifyPropertyChanged
{
    partial void OnValidate(ChangeAction action);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here partial method OnValidate can be optionally implemented by developer in another place:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class WebOSUser
{
    partial void OnValidate(ChangeAction action)
    {
        switch (action)
        {
            case ChangeAction.Delete:
                // Validates object when deleting.
                break;

            case ChangeAction.Insert:
                // Validates object when inserting.
                break;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If implemented this OnValidate method will be invoked when the WebOSUser entity instance is being validated.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;Apparently partial method must be declared within a partial class/struct, which can have a method implementation.&lt;/p&gt;
&lt;p&gt;Partial method consists of a declaration and an optional implementation. At compile time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the implementation is not provided, compiler removes the definition declaration, and all the invocations;&lt;/li&gt;
&lt;li&gt;If the implementation is provided, this partial method is compiled into a normal private method.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the above reasons, access modifiers and attributes are not allow on partial method.&lt;/p&gt;
&lt;p&gt;For the same reason, partial method must return void. Otherwise, when implementing declaration is not provided, there is no way to compile or remove the partial method declaration and invocation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;partial int PartialMethod();

private static void Main()
{
    int result = PartialMethod();
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Features (5) Lambda Expression, Anonymous Function and Expression Tree</title><link>https://dixin.github.io/posts/understanding-csharp-features-5-lambda-expression/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-5-lambda-expression/</guid><description>\] - \]</description><pubDate>Sun, 29 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;C# &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb397687.aspx&quot;&gt;lambda expression&lt;/a&gt; is a syntax to create delegates or expression trees. It is a very powerful syntactic sugar making C# functional. In this part, “Lambda expression” simply means “C# lambda expression”. The native concept of lambda expression will be fully covered in later chapter.&lt;/p&gt;
&lt;p&gt;At syntax level, a lambda expression can be simply viewed as a function or method without name, which looks like method parameter(s) =&amp;gt; method body, or method parameter(s) =&amp;gt; method return value. the =&amp;gt; operator is called lambda operator and reads “go to”.&lt;/p&gt;
&lt;h2&gt;Lambda expression as anonymous function&lt;/h2&gt;
&lt;h3&gt;Delegate and named method&lt;/h3&gt;
&lt;p&gt;In C#, a delegate definition can be viewed as a method type definition (method signature):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a named method (either static or instance method) has exactly the same signature as above Func&amp;lt;int, bool&amp;gt;, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static bool IsPositive(int int32)
{
    return int32 &amp;gt; 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then delegate can be instantiated by calling the constructor with the named method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = new Func&amp;lt;int, bool&amp;gt;(IsPositive);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this tutorial, to avoid confusion, above Func&amp;lt;int, bool&amp;gt; is called delegate type, and the isPositive variable is called delegate instance.&lt;/p&gt;
&lt;p&gt;The above constructor call syntax new Func&amp;lt;int, bool&amp;gt;(…) can be omitted, so that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = IsPositive;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is as nature as defining any other variable with a value, like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Type instanceVariable = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is an example of function’s &lt;a href=&quot;https://en.wikipedia.org/wiki/First-class_citizen&quot;&gt;first-class citizenship&lt;/a&gt; in C# language.&lt;/p&gt;
&lt;h3&gt;Anonymous method&lt;/h3&gt;
&lt;p&gt;C# 2.0 introduced a syntactic sugar, anonymous method, enabling methods to be defined inline, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Anonymous
{
    public static void AnonymousMethod()
    {
        Func&amp;lt;int, bool&amp;gt; isPositive = delegate(int int32)
            {
                return int32 &amp;gt; 0;
            };

        AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
            {
                Trace.WriteLine(e.ExceptionObject);
            };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No named static method or named instance method is defined at design time. But at compile time, above anonymous delegates will be compiled to named methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class CompiledAnonymous
{
    [CompilerGenerated]
    private static Func&amp;lt;int, bool&amp;gt; cachedAnonymousMethodDelegate0;

    [CompilerGenerated]
    private static UnhandledExceptionEventHandler cachedAnonymousMethodDelegate1;

    [CompilerGenerated]
    private static bool AnonymousMethod0(int int32)
    {
        return int32 &amp;gt; 0;
    }

    [CompilerGenerated]
    private static void AnonymousMethod1(object sender, UnhandledExceptionEventArgs e)
    {
        Trace.WriteLine(e.ExceptionObject);
    }

    internal static void AnonymousMethod()
    {
        Func&amp;lt;int, bool&amp;gt; isPositive = cachedAnonymousMethodDelegate0
            ?? (cachedAnonymousMethodDelegate0 = new Func&amp;lt;int, bool&amp;gt;(AnonymousMethod0));
        AppDomain.CurrentDomain.UnhandledException += cachedAnonymousMethodDelegate1
            ?? (cachedAnonymousMethodDelegate1 = new UnhandledExceptionEventHandler(AnonymousMethod1));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides named methods, C# compiler also generates cache fields for the delegate instance, so that if AnonymousMethod is called multiple times, the delegate instantiation happens only once.&lt;/p&gt;
&lt;h3&gt;Lambda expression&lt;/h3&gt;
&lt;p&gt;In C# 3.0+, above anonymous method’s inline definition can be further simplified with lambda expression syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void Lambda()
{
    Func&amp;lt;int, bool&amp;gt; isPositive = (int int32) =&amp;gt;
        {
            return int32 &amp;gt; 0;
        };

    AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) =&amp;gt;
        {
            Trace.WriteLine(e.ExceptionObject);
        };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lambda expression can be further shortened:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the type of parameter can be inferred (for example, from Func&amp;lt;int, bool&amp;gt;), the type declaration of parameter (int) can be omitted;&lt;/li&gt;
&lt;li&gt;When lambda expression has one parameter, the parentheses ( ) can be omitted;&lt;/li&gt;
&lt;li&gt;When the body of the lambda expression has only one return statement, the brackets { } and “return” keyword can be omitted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the above lambda expressions can be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void ExpressionLambda()
{
    Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;

    AppDomain.CurrentDomain.UnhandledException += (sender, e) =&amp;gt; Trace.WriteLine(e.ExceptionObject);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These lambda expressions are also called expression lambda.&lt;/p&gt;
&lt;p&gt;When having more than one statements in the body, the the brackets { } and “return” are required:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void StatementLambda()
{
    Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt;
        {
            Console.WriteLine(int32);
            return int32 &amp;gt; 0;
        };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is called statement lambda.&lt;/p&gt;
&lt;p&gt;In C#, anonymous method and lambda expression can be also called &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb882516.aspx&quot;&gt;anonymous function&lt;/a&gt;. C# usually uses the term &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms173114.aspx&quot;&gt;method&lt;/a&gt; instead of function, but this does not matter. Method and function are identical concepts in C#.&lt;/p&gt;
&lt;h3&gt;Anonymous function&lt;/h3&gt;
&lt;p&gt;Generally, &lt;a href=&quot;https://en.wikipedia.org/wiki/Anonymous_function&quot;&gt;anonymous function&lt;/a&gt; is a function not bound to an identifier. The C# anonymous function is just an alias term for anonymous method and lambda expression. Either anonymous method or lambda expression can be used directly, without being bound to any delegate instance, or involving any named method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void CallAnonymousMethod()
{
    bool positive = new Func&amp;lt;int, bool&amp;gt;(delegate (int int32) { return int32 &amp;gt; 0; })(1);

    new Action&amp;lt;bool&amp;gt;(delegate (bool value) { Trace.WriteLine(value); })(positive);
}

public static void CallLambda()
{
    bool positive = new Func&amp;lt;int, bool&amp;gt;(int32 =&amp;gt; int32 &amp;gt; 0)(1);

    new Action&amp;lt;bool&amp;gt;(value =&amp;gt; Trace.WriteLine(value))(positive);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where Action&amp;lt;T&amp;gt; delegate type is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate void Action&amp;lt;T&amp;gt;(T obj);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These function are anonymous and inline at design time. As fore mentioned, at compile time, they all become named methods. And these calls become normal calls to the compiler generated delegate cache fields.&lt;/p&gt;
&lt;p&gt;Here, The new Func&amp;lt;int, bool&amp;gt;(…) and new Action&amp;lt;bool&amp;gt;(…) constructor call syntax surrounding the anonymous functions are required by compiler. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(int32 =&amp;gt; int32 &amp;gt; 0)(1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C# compiler’s perspective, there is no type information for the parameter(s) and return value at all.&lt;/p&gt;
&lt;p&gt;In loosely typed languages like JavaScript, this kind of code definitely works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function (number) { return number &amp;gt; 0; })(1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very common pattern in client &lt;a href=&quot;http://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt; - isolate some code by surrounding the code with a anonymous function call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function (global, undefined) {
    &quot;use strict&quot;;

    // code.
}(this));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other strongly typed languages (typically functional programming languages), like F#, this kind of type inference is supported, so the following F# code works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(fun int32 -&amp;gt; int32 &amp;gt; 0) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and similarly, in Haskell, the following works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(\number -&amp;gt; number &amp;gt; 0) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Expression bodied method-like member&lt;/h2&gt;
&lt;p&gt;Similar to fore mentioned expression bodied property-like function member, C# 6.0 also introduced syntax called expression bodied method-like member. Now lambda expression syntactic sugar can be applied on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;static method&lt;/li&gt;
&lt;li&gt;instant method&lt;/li&gt;
&lt;li&gt;extension method&lt;/li&gt;
&lt;li&gt;operator override method&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc., as long as it has 1 single statement.&lt;/p&gt;
&lt;p&gt;These are the sample extension methods from previous part:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class StringExtensions
{
    public static bool ContainsIgnoreCase(this string value, string substring)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(value != null);

        return value.IndexOf(substring, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0;
    }

    public static bool EqualsIgnoreCase(this string a, string b)
    {
        return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    }

    public static string With(this string format, params object[] args)
    {
        return string.Format(CultureInfo.InvariantCulture, format, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now these can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class StringExtensions
{
    public static bool ContainsIgnoreCase(this string value, string substring)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(value != null);

        return value.IndexOf(substring, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0;
    }

    public static bool EqualsIgnoreCase(this string a, string b)
        =&amp;gt; string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

    public static string With(this string format, params object[] args)
        =&amp;gt; string.Format(CultureInfo.InvariantCulture, format, args);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The 2 versions are identical. This syntax does not apply to ContainsIgnoreCase method, because its body has more than 1 statement.&lt;/p&gt;
&lt;p&gt;In this tutorial, to emphasize the functional paradigm, lambda bodied methods will be in the following style:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class StringExtensions
{
    public static bool EqualsIgnoreCase
        (this string a, string b) =&amp;gt; string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

    public static string With
        (this string format, params object[] args) =&amp;gt; string.Format(CultureInfo.InvariantCulture, format, args);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that EqualsIgnoreCase method can be viewed as a Func&amp;lt;string, string, bool&amp;gt; lambda expression.&lt;/p&gt;
&lt;h2&gt;Func and Action generic delegate types&lt;/h2&gt;
&lt;p&gt;The above System.Func&amp;lt;T, TResult&amp;gt; and Action&amp;lt;T&amp;gt; delegate type definition is introduced in .NET 3.5.&lt;/p&gt;
&lt;p&gt;In .NET 3.5, this generic delegate type defined in mscorlib.dll:&lt;/p&gt;
&lt;p&gt;And these are defined in System.Core.dll:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate void Action();

    public delegate void Action&amp;lt;in T&amp;gt;(T obj);

    public delegate void Action&amp;lt;in T1, in T2&amp;gt;(T1 arg1, T2 arg2);

    public delegate void Action&amp;lt;in T1, in T2, in T3&amp;gt;(T1 arg1, T2 arg2, T3 arg3);

    public delegate void Action&amp;lt;in T1, in T2, in T3, in T4&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

    public delegate TResult Func&amp;lt;out TResult&amp;gt;();

    public delegate TResult Func&amp;lt;in T, out TResult&amp;gt;(T arg);

    public delegate TResult Func&amp;lt;in T1, in T2, out TResult&amp;gt;(T1 arg1, T2 arg2);

    public delegate TResult Func&amp;lt;in T1, in T2, in T3, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3);

    public delegate TResult Func&amp;lt;in T1, in T2, in T3, in T4, out TResult&amp;gt;(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They will be used again and again in LINQ programming.&lt;/p&gt;
&lt;p&gt;In .NET 4.0 FCL, more Action and Func generic delegate types are provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mscorlib.dll
&lt;ul&gt;
&lt;li&gt;Action with 0 - 8 type parameters (Action, Action`1 to Action`8)&lt;/li&gt;
&lt;li&gt;Func with 1 - 9 type parameters (Func`1 to Func`9)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Core.dll
&lt;ul&gt;
&lt;li&gt;Action`9 to Action`16&lt;/li&gt;
&lt;li&gt;Func`10 to Func`17&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lambda expression as expression tree&lt;/h2&gt;
&lt;p&gt;An expression tree object can be created with lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static partial class ExpressionTree
{
    internal static void ExpressionLambda()
    {
        Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above assignment statement, the right side is a lambda expression, which literally the same as the above lambda expression as anonymous method. But this time the isPositiveExpression is of type Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; instead of Func&amp;lt;int, bool&amp;gt;. An Expression&amp;lt;T&amp;gt; object is called an expression tree instead of an anonymous method.&lt;/p&gt;
&lt;h3&gt;Code as data&lt;/h3&gt;
&lt;p&gt;Above lambda expression has exactly the same syntax as anonymous function. However, its type is specified to bee Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; instead of Func&amp;lt;int, boll&amp;gt; delegate type. As a result, the lambda expression is not compiled to executable code. It is compiled to the build of a data structure called expression tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void CompiledExpressionLambda()
{
    ParameterExpression parameterExpression = Expression.Parameter(typeof(int), &quot;int32&quot;); // int32
    ConstantExpression constantExpression = Expression.Constant(0, typeof(int)); // 0
    BinaryExpression greaterThanExpression = Expression.GreaterThan(
        left: parameterExpression, right: constantExpression); // int32 &amp;gt; 0

    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
        body: greaterThanExpression, // =&amp;gt; int32 &amp;gt; 0
        parameters: parameterExpression); // int32 =&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the Expression&amp;lt;Func&amp;lt;int bool&amp;gt;&amp;gt; object represents an expression tree, the ParameterExpression, ConstantExpression, BinaryExpression objects are nodes in that tree. And they are all derived from System.Linq.Expressions.Expression class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq.Expressions
{
    public abstract partial class Expression
    {
        public virtual ExpressionType NodeType { get; }

        public virtual Type Type { get; }

        // Other members.
    }

    public class ParameterExpression : Expression
    {
        public string Name { get; }

        // Other members.
    }

    public class ConstantExpression : Expression
    {
        public object Value { get; }

        // Other members.
    }

    public class BinaryExpression : Expression
    {
        public Expression Left { get; }

        public Expression Right { get; }

        // Other members.
    }

    public abstract class LambdaExpression : Expression
    {
        public Expression Body { get; }

        public ReadOnlyCollection&amp;lt;ParameterExpression&amp;gt; Parameters { get; }

        // Other members.
    }

    public sealed class Expression&amp;lt;TDelegate&amp;gt; : LambdaExpression
    {
        public TDelegate Compile();

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each expression object is a node in the expression tree, representing a construct in the source code int32 =&amp;gt; int32 &amp;gt; 0:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_140B654C.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; (NodeType = Lambda, Type = Func&amp;lt;int, bool&amp;gt;)
|_Parameters
| |_ParameterExpression (NodeType = Parameter, Type = int)
|   |_Name = &quot;int32&quot;
|_Body
  |_BinaryExpression (NodeType = GreaterThan, Type = bool)
    |_Left
    | |_ParameterExpression (NodeType = Parameter, Type = int)
    |   |_Name = &quot;int32&quot;
    |_Right
      |_ConstantExpression (NodeType = Constant, Type = int)
        |_Value = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So .NET expression tree is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Abstract_syntax_tree&quot;&gt;abstract syntactic tree&lt;/a&gt;, representing the abstract syntactic structure of C# source code. Notice each Expression object has a NodeType property and a Type property. NodeType identifies in the tree what construct this node is, and Type is the represented .NET type. For example, above ParameterExpression is parameter node representing an int parameter in the source code, so its NodeType is Parameter and its Type is int.&lt;/p&gt;
&lt;p&gt;To summarize, the differences between&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0; // Code.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0; // Data.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;isPositive variable is a delegate instance, and can be called just like calling a method. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled as code. When isPositive is called, this code is executed.&lt;/li&gt;
&lt;li&gt;isPositiveExpression variable is an abstract syntactic tree data structure. So apparently it cannot be called like a method. The lambda expression int32 =&amp;gt; int32 &amp;gt; 0 is compiled to the building of an expression tree, where each node is a expression object. This entire tree represents the syntactic structure of anonymous function int32 =&amp;gt; int32 &amp;gt; 0. This tree’s top node is a Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; object, representing this is a lambda expression. It has 2 child nodes:
&lt;ul&gt;
&lt;li&gt;A ParameterExpression collection object, representing all the parameters of code the lambda expression. The lambda expression has 1 parameter, so this collection object contains one node:
&lt;ul&gt;
&lt;li&gt;A ParameterExpression object, representing the int parameter named “int32”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A Body node representing the lambda expression’s body, which is a BinaryExpression object, representing the body is a “&amp;gt;” (greater than) comparison of 2 operands. So it has 2 child nodes:
&lt;ul&gt;
&lt;li&gt;A reference of above ParameterExpression object, representing the left operand, the int32 parameter.&lt;/li&gt;
&lt;li&gt;A ConstantExpression object, representing the right operand 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because each node of expression tree is strong typed with rich information. it is very feasible to traverse the nodes to obtain the represented C# source code logic, and convert to the logic of another language. Here isPositiveExpression represents the C# logic to predict whether an int value is greater than a constant, and it can be converted to IL code with a &lt;a href=&quot;https://msdn.microsoft.com/library/system.reflection.emit.opcodes.cgt.aspx&quot;&gt;cgt&lt;/a&gt; instruction that compares 2 values, or SQL query’s greater-than predicate in a WHERE clause, etc..&lt;/p&gt;
&lt;h3&gt;.NET expressions&lt;/h3&gt;
&lt;p&gt;Besides above ParameterExpression, ConstantExpression, etc., .NET provides a collection of expressions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BlockExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ConditionalExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ConstantExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DebugInfoExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DefaultExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DynamicExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GotoExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IndexExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;InvocationExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LabelExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LambdaExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expression&amp;lt;TDelegate&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ListInitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LoopExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MemberExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MemberInitExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MethodCallExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NewArrayExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NewExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ParameterExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RuntimeVariablesExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SwitchExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TypeBinaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UnaryExpression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, as demonstrated above, expression can be instantiated by calling the factory methods of Expression class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract partial class Expression
{
    public static ParameterExpression Parameter(Type type, string name);

    public static ConstantExpression Constant(object value, Type type);

    public static BinaryExpression GreaterThan(Expression left, Expression right);

    public static Expression&amp;lt;TDelegate&amp;gt; Lambda&amp;lt;TDelegate&amp;gt;(Expression body, params ParameterExpression[] parameters);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expression has a lot more factory methods to cover all the expression instantiation cases:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract partial class Expression
{
    public static BinaryExpression Add(Expression left, Expression right);

    public static BinaryExpression Subtract(Expression left, Expression right);

    public static BinaryExpression Multiply(Expression left, Expression right);

    public static BinaryExpression Divide(Expression left, Expression right);

    public static BinaryExpression Equal(Expression left, Expression right);

    public static UnaryExpression ArrayLength(Expression array);

    public static UnaryExpression Not(Expression expression);

    public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse);

    public static NewExpression New(ConstructorInfo constructor, params Expression[] arguments);

    public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments);

    public static BlockExpression Block(params Expression[] expressions);

    // Other methods.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some expression can have multiple possible NodeType values. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UnaryExpression represents any unary operation with an operator and a operand. Its NodeType can be ArrayLength, Negate, Not, Convert, Decreament, Increment, Throw, UnaryPlus, etc.&lt;/li&gt;
&lt;li&gt;BinaryExpression represents any binary operation with an operator, a left operand, and a right operand, its NodeType can be Add, And, Assign, Divide, Equal, .GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, Modulo, Multiply, NotEqual, Or, Power, Subtract, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So far C# compiler only implements this “code as data” syntactic sugar for expression lambda, and it is not available to statement lambda yet. The following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StatementLambda()
{
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; statementLambda1 = int32 =&amp;gt; { return int32 &amp;gt; 0; };

    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; statementLambda2 = int32 =&amp;gt;
        {
            Console.WriteLine(int32);
            return int32 &amp;gt; 0;
        };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;results a compiler error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A lambda expression with a statement body cannot be converted to an expression tree&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These 2 expression trees has to be coded as manual building:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static void StatementLambda()
{
    // For single statement, syntactic sugar works.
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; statementLambda1 = int32 =&amp;gt; int32 &amp;gt; 0;

    // Above lambda expression is compiled to:
    ParameterExpression int32Parameter = Expression.Parameter(typeof(int), &quot;int32&quot;);
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; compiledStatementLambda1 = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
        Expression.GreaterThan(int32Parameter, Expression.Constant(0, typeof(int))), // int32 &amp;gt; 0
        int32Parameter); // int32 =&amp;gt;

    // For multiple statements, syntactic sugar is not available. The expression tree has to be built manually.
    Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; statementLambda2 = Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(
        // {
        Expression.Block(
            // Console.WriteLine(int32);
            Expression.Call(new Action&amp;lt;int&amp;gt;(Console.WriteLine).Method, int32Parameter),
            // return int32 &amp;gt; 0;
            Expression.GreaterThan(int32Parameter, Expression.Constant(0, typeof(int)))),
        // }
        int32Parameter); // int32 =&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Convert expression tree to IL&lt;/h2&gt;
&lt;p&gt;Expression tree is data - abstract syntatic tree. In C# and LINQ, expression tree is usually used to represent the abstract syntactic structure of some C# code, so that it can be compiled to some other &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;domain-specific languages&lt;/a&gt;, like SQL query, URI query, etc. To demonstrate this, a simple kind of expression tree will be used - expression tree only contains the 4 basic binary arithmetical calculation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add&lt;/li&gt;
&lt;li&gt;subtract&lt;/li&gt;
&lt;li&gt;multiply&lt;/li&gt;
&lt;li&gt;divide&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix = 
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a abstract syntactic tree representing the structure of a Func&amp;lt;double, double, double, double, double, double&amp;gt; algorithm (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 2. It is a very simple binary tree, where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;each internal node is a binary node (BinaryExpression object) representing add, subtract, multiply, or divide calculation;&lt;/li&gt;
&lt;li&gt;each leaf node is either a parameter (ParameterExpression object), or a constant (ConstantExpression object).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C#/.NET:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Above binary calculations are represented by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.linq.expressions.binaryexpression.aspx&quot;&gt;System.Linq.Expressions.BinaryExpression&lt;/a&gt; objects.&lt;/li&gt;
&lt;li&gt;Parameters are represented by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.linq.expressions.parameterexpression.aspx&quot;&gt;System.Linq.Expressions.ParameterExpression&lt;/a&gt; objects.&lt;/li&gt;
&lt;li&gt;Constants are represented by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.linq.expressions.constantexpression.aspx&quot;&gt;System.Linq.Expressions.ConstantExpression&lt;/a&gt; objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So in total there are 6 possible kinds of nodes in this kind of expression tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add: BinaryExpression { NodeType = ExpressionType.Add }&lt;/li&gt;
&lt;li&gt;subtract: BinaryExpression { NodeType = ExpressionType.Subtract }&lt;/li&gt;
&lt;li&gt;multiply: BinaryExpression { NodeType = ExpressionType.Multiply }&lt;/li&gt;
&lt;li&gt;divide: BinaryExpression { NodeType = ExpressionType.Divide}&lt;/li&gt;
&lt;li&gt;constant: ParameterExpression { NodeType = ExpressionType.Constant }&lt;/li&gt;
&lt;li&gt;parameter: ConstantExpression { NodeType = ExpressionType.Parameter }&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each node has a NodeType property representing the node type.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_4C2406F2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Traverse expression tree&lt;/h3&gt;
&lt;p&gt;Recursively traversing this tree is very easy. The following base class constructs the basic logic of traversing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class BinaryArithmeticExpressionVisitor&amp;lt;TResult&amp;gt;
{
    public TResult VisitBody(LambdaExpression expression)
    {
        return this.VisitNode(expression.Body, expression);
    }

    protected TResult VisitNode(Expression node, LambdaExpression expression)
    {
        // Processes the 6 types of node.
        switch (node.NodeType)
        {
            case ExpressionType.Add:
                return this.VisitAdd(node as BinaryExpression, expression);

            case ExpressionType.Constant:
                return this.VisitConstant(node as ConstantExpression, expression);

            case ExpressionType.Divide:
                return this.VisitDivide(node as BinaryExpression, expression);

            case ExpressionType.Multiply:
                return this.VisitMultiply(node as BinaryExpression, expression);

            case ExpressionType.Parameter:
                return this.VisitParameter(node as ParameterExpression, expression);

            case ExpressionType.Subtract:
                return this.VisitSubtract(node as BinaryExpression, expression);

            default:
                throw new ArgumentOutOfRangeException(nameof(node));
        }
    }

    protected abstract TResult VisitAdd(BinaryExpression add, LambdaExpression expression);

    protected abstract TResult VisitConstant(ConstantExpression constant, LambdaExpression expression);

    protected abstract TResult VisitDivide(BinaryExpression divide, LambdaExpression expression);

    protected abstract TResult VisitMultiply(BinaryExpression multiply, LambdaExpression expression);

    protected abstract TResult VisitParameter(ParameterExpression parameter, LambdaExpression expression);

    protected abstract TResult VisitSubtract(BinaryExpression subtract, LambdaExpression expression);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following class implements the traversal. When visiting a binary node, it logs a prefix style string “operator(left, right)”. For example, a + b will be logged as add(a, b), which can be viewed as calling add method with argument a and b.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PrefixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;string&amp;gt;
{
    protected override string VisitAdd
        (BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, &quot;add&quot;, expression);

    protected override string VisitConstant
        (ConstantExpression constant, LambdaExpression expression) =&amp;gt; constant.Value.ToString();

    protected override string VisitDivide
        (BinaryExpression divide, LambdaExpression expression) =&amp;gt; this.VisitBinary(divide, &quot;div&quot;, expression);

    protected override string VisitMultiply
        (BinaryExpression multiply, LambdaExpression expression) =&amp;gt; 
            this.VisitBinary(multiply, &quot;mul&quot;, expression);

    protected override string VisitParameter
        (ParameterExpression parameter, LambdaExpression expression) =&amp;gt; parameter.Name;

    protected override string VisitSubtract
        (BinaryExpression subtract, LambdaExpression expression) =&amp;gt; 
            this.VisitBinary(subtract, &quot;sub&quot;, expression);

    private string VisitBinary // Recursive: operator(left, right)
        (BinaryExpression binary, string @operator, LambdaExpression expression) =&amp;gt;
            $&quot;{@operator}({this.VisitNode(binary.Left, expression)}, {this.VisitNode(binary.Right, expression)})&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

PrefixVisitor prefixVisitor = new PrefixVisitor();
string prefix = prefixVisitor.VisitBody(infix); // &quot;add(sub(add(a, b), div(mul(c, d), 2)), mul(e, 3))&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The value of prefix is add(sub(add(a, b), div(mul(c, d), 2)), mul(e, 3)), which represents the semantics of expression a + b - c * d / 2 + e * 3 in a method call style.&lt;/p&gt;
&lt;h3&gt;.NET built-in expression tree traverser&lt;/h3&gt;
&lt;p&gt;.NET 4.0+ provides a built-in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor.aspx&quot;&gt;System.Linq.Expressions.ExpressionVisitor&lt;/a&gt; class in System.Core.dll. Here traversers are built from scratch for demonstration purpose.&lt;/p&gt;
&lt;h3&gt;Compile expression tree to IL at runtime&lt;/h3&gt;
&lt;p&gt;How about postfix? In postfix style, switching add(a, b) to (a, b)add looks a little less intuitive. Actually, (a, b)add can be viewed as: load a to stack, load b to stack, add 2 values on stack.&lt;/p&gt;
&lt;p&gt;Yes, this demonstrates how the computer works. The entire postfix style expression: “(((a, b)add, ((c, d)mul, 2)div)sub, (e, 3)mul)add” can be viewed as a sequence of operations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a // Load a to stack. b // Load b to stack. add // Add 2 values. c // … d mul 2 div sub e 3 mul add&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is very easy to produce this postfix style by tweaking 1 line of code from PrefixVisitor class. It is also easy to go a little further, just change the output from a string log (a, b)add to a sequence of &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_CIL_instructions&quot;&gt;IL instructions&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load a to stack to the evaluation stack&lt;/li&gt;
&lt;li&gt;Load b to stack to the evaluation stack&lt;/li&gt;
&lt;li&gt;Adds two values, and pushes the result to the evaluation stack&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IL instructions can be represented by &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcode.aspx&quot;&gt;System.Reflection.Emit.OpCode&lt;/a&gt; structs. So the output can be a sequence of instruction-argument pairs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PostfixVisitor : BinaryArithmeticExpressionVisitor&amp;lt;IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt;&amp;gt;
{
    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitAdd
        (BinaryExpression add, LambdaExpression expression) =&amp;gt; this.VisitBinary(add, OpCodes.Add, expression);

    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitConstant(
        ConstantExpression constant, LambdaExpression expression)
    {
        yield return Tuple.Create(OpCodes.Ldc_R8, (double?)constant.Value);
    }

    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitDivide
        (BinaryExpression divide, LambdaExpression expression) =&amp;gt; 
            this.VisitBinary(divide, OpCodes.Div, expression);

    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitMultiply
        (BinaryExpression multiply, LambdaExpression expression) =&amp;gt; 
            this.VisitBinary(multiply, OpCodes.Mul, expression);

    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitParameter(
        ParameterExpression parameter, LambdaExpression expression)
    {
        int index = expression.Parameters.IndexOf(parameter);
        yield return Tuple.Create(OpCodes.Ldarg_S, (double?)index);
    }

    protected override IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitSubtract
        (BinaryExpression subtract, LambdaExpression expression) =&amp;gt; 
            this.VisitBinary(subtract, OpCodes.Sub, expression);

    private IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; VisitBinary // Recursive: left, right, operator
        (BinaryExpression binary, OpCode postfix, LambdaExpression expression) =&amp;gt;
            this.VisitNode(binary.Left, expression)
                .Concat(this.VisitNode(binary.Right, expression))
                .Concat(EnumerableEx.Return(Tuple.Create(postfix, (double?)null))); // left, right, postfix
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So data becomes code. The following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void IL()
{
    Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
        (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

    PostfixVisitor postfixVisitor = new PostfixVisitor();
    IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; postfix = postfixVisitor.VisitBody(infix);
    foreach (Tuple&amp;lt;OpCode, double?&amp;gt; code in postfix)
    {
        Trace.WriteLine($&quot;{code.Item1} {code.Item2}&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ldarg.s 0 ldarg.s 1 add ldarg.s 2 ldarg.s 3 mul ldc.r8 2 div sub ldarg.s 4 ldc.r8 3 mul add&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The expression tree’s semantics is successfully represented by IL code.&lt;/p&gt;
&lt;h3&gt;Compile expression tree to executable method at runtime&lt;/h3&gt;
&lt;p&gt;To truly compile expression tree to executable code, the rest of the work is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a dynamic method&lt;/li&gt;
&lt;li&gt;Emit the IL code into that dynamic method&lt;/li&gt;
&lt;li&gt;Return that dynamic method&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This method is called dynamic because it is generated at runtime, In contrast of a method compiled into static IL code in a static assembly.&lt;/p&gt;
&lt;p&gt;The following class implements the compilation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class BinaryArithmeticCompiler
{
    private static readonly PostfixVisitor postfixVisitor = new PostfixVisitor();

    public static TDelegate Compile&amp;lt;TDelegate&amp;gt;(Expression&amp;lt;TDelegate&amp;gt; expression)
        where TDelegate : class
    {
        DynamicMethod dynamicMethod = new DynamicMethod(
            string.Empty,
            expression.ReturnType,
            expression.Parameters.Select(parameter =&amp;gt; parameter.Type).ToArray(),
            typeof(BinaryArithmeticCompiler).Module);
        EmitIL(dynamicMethod.GetILGenerator(), postfixVisitor.VisitBody(expression));
        return dynamicMethod.CreateDelegate(typeof(TDelegate)) as TDelegate;
    }

    private static void EmitIL(ILGenerator ilGenerator, IEnumerable&amp;lt;Tuple&amp;lt;OpCode, double?&amp;gt;&amp;gt; codes)
    {
        foreach (Tuple&amp;lt;OpCode, double?&amp;gt; code in codes)
        {
            if (code.Item2.HasValue)
            {
                if (code.Item1 == OpCodes.Ldarg_S)
                {
                    ilGenerator.Emit(code.Item1, (int)code.Item2.Value); // ldarg.s (int)index
                }
                else
                {
                    ilGenerator.Emit(code.Item1, code.Item2.Value); // ldc.r8 (double)constant
                }
            }
            else
            {
                ilGenerator.Emit(code.Item1); // add, sub, mul, div
            }
        }

        ilGenerator.Emit(OpCodes.Ret); // Returns the result.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code shows how to compile the expression tree into a .NET method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

Func&amp;lt;double, double, double, double, double, double&amp;gt; method = BinaryArithmeticCompiler.Compile(infix);
double result = method(1, 2, 3, 4, 5); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very powerful. By traversing a abstract syntactic tree, a .NET method is created at runtime.&lt;/p&gt;
&lt;h3&gt;.NET built-in compiler&lt;/h3&gt;
&lt;p&gt;.NET provides a built in API &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/Bb345362.aspx&quot;&gt;System.Linq.Expressions.Expression&amp;lt;TDelegate&amp;gt;.Compile()&lt;/a&gt; to compile expression tree to executable method at runtime:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;double, double, double, double, double, double&amp;gt;&amp;gt; infix =
    (a, b, c, d, e) =&amp;gt; a + b - c * d / 2 + e * 3;

Func&amp;lt;double, double, double, double, double, double&amp;gt; method = infix.Compile();
double result = method(1, 2, 3, 4, 5); // 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expression&amp;lt;TDelegate&amp;gt;.Compile() calls internal API System.Linq.Expressions.Compiler.LambdaCompiler.Compile(). There is a complete expression-tree-to-IL compiler implementation under System.Linq.Expressions.Compiler namespace.&lt;/p&gt;
&lt;h3&gt;Convert expression tree to other languages&lt;/h3&gt;
&lt;p&gt;Here expression tree is compiled to description string, and IL instructions. Later, the LINQ to Entities and LINQ to SQL chapters will revisit expression tree, where expression tree is translated to SQL queries.&lt;/p&gt;
&lt;h3&gt;Decompile anonymous method to expression tree?&lt;/h3&gt;
&lt;p&gt;Regarding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At compile time, anonymous method and expression tree can share the same syntax sugar&lt;/li&gt;
&lt;li&gt;At runtime, expression tree can be converted to method, by just calling Expression&amp;lt;TDelegate&amp;gt;.Compile()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, can a method be converted to expression tree at runtime?&lt;/p&gt;
&lt;p&gt;Theoretically, yes; practically, difficult. At runtime, when looking at a compiled method, it contains a sequence of IL instructions. It is possible to decompile IL to C# source, then use the C# source to construct expression tree. Apparently this is much more complicated.&lt;/p&gt;
&lt;h2&gt;Type inference of lambda expression&lt;/h2&gt;
&lt;p&gt;In C# lambda syntax, the parameter type(s), return type, and lambda expression type should be all inferable from the context:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Anonymous method with a int parameter, and returns a bool value.
Func&amp;lt;int, bool&amp;gt; isPositive = int32 =&amp;gt; int32 &amp;gt; 0;

// Expression tree with a int parameter, and returns a bool value.
Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; isPositiveExpression = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the var keyword cannot be used to define lambda expression. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler does not know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;is predicate3 a anonymous method (System.Delegate), or an expression tree (System.Linq.Expressions.Expression&amp;lt;TDelegate&amp;gt;)&lt;/li&gt;
&lt;li&gt;the type of parameter, return value, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;dynamic cannot be used either. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic isPositive = int32 =&amp;gt; int32 &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, dynamic is just System.Object. It does not provide any information for inference.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Features (4) Extension Method</title><link>https://dixin.github.io/posts/understanding-csharp-features-4-extension-method/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-4-extension-method/</guid><description>\] - \]</description><pubDate>Sat, 28 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Extension method is a powerful syntactic sugar in C# 3.0+, which enables fluent LINQ query.&lt;/p&gt;
&lt;h2&gt;Define and use extension method&lt;/h2&gt;
&lt;p&gt;When an extension method is defined for a type, this extension method must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;be a static method&lt;/li&gt;
&lt;li&gt;be defined in a static class&lt;/li&gt;
&lt;li&gt;have the first parameter to be that type, and add a this keyword preceded&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, here are some useful extension methods for string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class StringExtensions
{
    public static bool ContainsIgnoreCase(this string value, string substring)
    {
        Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(value != null);

        return value.IndexOf(substring, StringComparison.OrdinalIgnoreCase) &amp;gt;= 0;
    }

    public static bool EqualsIgnoreCase(this string a, string b)
    {
        return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    }

    public static string With(this string format, params object[] args)
    {
        return string.Format(CultureInfo.InvariantCulture, format, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool contains = text.ToUpperInvariant().Contains(value.ToUpperInvariant());
bool areEqual = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
string fullName = string.Format(CultureInfo.InvariantCulture, &quot;Full name: {0} {1}.&quot;, firstName, lastName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bool contains = text.ContainsIgnoreCase(value);
bool areEqual = a.EqualsIgnoreCase(b);
string fullName = &quot;Full name: {0} {1}.&quot;.With(firstName, lastName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks like some instance methods are extended to a string object.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;Extension method is just a syntactic sugar. It will be compiled to normal static method. Take above With as an example, it is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Extension]
public static string With(string format, params object[] args)
{
    return string.Format(CultureInfo.InvariantCulture, format, args);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, when compiler compiles With() method invocation on the string object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string fullName = &quot;Full name: {0} {1}.&quot;.With(firstName, lastName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it looks up for an available With() in the context. The order to look up is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;instance method in the type definition&lt;/li&gt;
&lt;li&gt;extension method in the current namespace&lt;/li&gt;
&lt;li&gt;extension method in the current namespace’s parents namespaces&lt;/li&gt;
&lt;li&gt;extension method in the other namespaces imported by “using”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once compiler finds a first match - in this case it is the extension method StringExtensions.With(), it compiles extension method call to normal static method call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string fullName = StringExtensions.With(&quot;Full name: {0} {1}.&quot;, firstName, lastName);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Static method vs. instance method&lt;/h2&gt;
&lt;p&gt;The extension method is about turning static method into instance method at design time, then turning instance method into static method at compile time. This is actually very natural. For better understanding, take a look at the following static method and instance method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Methods
{
    public static bool Same(Methods @this, Methods other)
    {
        return @this == other;
    }

    public bool SameTo(Methods other)
    {
        return this == other;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After compilation, the IL is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class public auto ansi beforefieldinit Dixin.Linq.LinqToObjects.Methods
    extends [mscorlib]System.Object
{
    .method public hidebysig static 
        bool Same (
            class LinqToObjects.Methods this,
            class LinqToObjects.Methods other
        ) cil managed 
    {
        .maxstack 2
        .locals init (
            [0] bool CS$1$0000
        )

        IL_0000: nop
        IL_0001: ldarg.0 // Loads the first argument this.
        IL_0002: ldarg.1 // Loads the second argument other.
        IL_0003: ceq
        IL_0005: stloc.0
        IL_0006: br.s IL_0008

        IL_0008: ldloc.0
        IL_0009: ret
    }

    .method public hidebysig 
        instance bool SameTo (
            class LinqToObjects.Methods other
        ) cil managed 
    {
        .maxstack 2
        .locals init (
            [0] bool CS$1$0000
        )

        IL_0000: nop
        IL_0001: ldarg.0 // Loads the first argument this.
        IL_0002: ldarg.1 // Loads the second argument other.
        IL_0003: ceq
        IL_0005: stloc.0
        IL_0006: br.s IL_0008

        IL_0008: ldloc.0
        IL_0009: ret
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The static method and instance method has exactly the same method body:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;for a static method, the arguments are exactly the parameters declared;&lt;/li&gt;
&lt;li&gt;for a instance method, the actual first argument is the this reference, and the first parameter becomes the second argument, and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, above Methods class can be viewed as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Methods
{
    public static bool Same(Methods @this, Methods other)
    {
        Methods arg0 = @this;
        Methods arg1 = other;
        return arg0 == arg1;
    }

    public bool SameTo(Methods other)
    {
        Methods arg0 = this;
        Methods arg1 = other;
        return arg0 == arg1;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, it is &lt;a href=&quot;http://www.imdb.com/title/tt0328828/&quot;&gt;perfectly natural normal thing&lt;/a&gt; that in extension method, this keyword is used for the first parameter, then this method can be used as the first parameter’s instance method.&lt;/p&gt;
&lt;h2&gt;Extension method for other types&lt;/h2&gt;
&lt;p&gt;Besides classes, extension method can be created by for structs, interfaces, delegates, etc. This is an intuitive example for interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public static class EnumerableEx
    {
        public static void ForEach&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Action&amp;lt;TSource&amp;gt; onNext)
        {
            if (source == null)
            {
                throw new ArgumentNullException(&quot;source&quot;);
            }

            if (onNext == null)
            {
                throw new ArgumentNullException(&quot;onNext&quot;);
            }

            foreach (TSource current in source)
            {
                onNext(current);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this extension method,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (string message in messages)
{
    Console.WriteLine(message);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be simplified to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;messages.ForEach(Console.WriteLine);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In LINQ, most of the query methods are extension methods for interfaces. Extension method for delegates will also be used a lot in later chapters.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# 3.0 Features (4) Anonymous Type</title><link>https://dixin.github.io/posts/understanding-csharp-3-0-features-4-anonymous-type/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-3-0-features-4-anonymous-type/</guid><description>\]</description><pubDate>Fri, 27 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;This feature provides a way to create an instance without declare the type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var mark = new 
                { 
                    Name = &quot;Mark&quot;, 
                    Age = 18 
                };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the type name is unknown at this time when writing code, this is called a anonymous type.&lt;/p&gt;
&lt;h2&gt;Compilation&lt;/h2&gt;
&lt;p&gt;At compile time, the compiler will generate the following type definition automatically:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[DebuggerDisplay(@&quot;\{ Name = {Name}, Age = {Age} }&quot;, Type=&quot;&amp;lt;Anonymous Type&amp;gt;&quot;)]
internal sealed class &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;&amp;lt;Name&amp;gt;j__TPar, &amp;lt;Age&amp;gt;j__TPar&amp;gt;
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly &amp;lt;Age&amp;gt;j__TPar &amp;lt;Age&amp;gt;i__Field;

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly &amp;lt;Name&amp;gt;j__TPar &amp;lt;Name&amp;gt;i__Field;

    [DebuggerHidden]
    public &amp;lt;&amp;gt;f__AnonymousType0(&amp;lt;Name&amp;gt;j__TPar Name, &amp;lt;Age&amp;gt;j__TPar Age)
    {
        this.&amp;lt;Name&amp;gt;i__Field = Name;
        this.&amp;lt;Age&amp;gt;i__Field = Age;
    }

    [DebuggerHidden]
    public override bool Equals(object value)
    {
        &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;&amp;lt;Name&amp;gt;j__TPar, &amp;lt;Age&amp;gt;j__TPar&amp;gt; type = 
            value as &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;&amp;lt;Name&amp;gt;j__TPar, &amp;lt;Age&amp;gt;j__TPar&amp;gt;;
        return (((type != null) &amp;amp;&amp;amp; 
            EqualityComparer&amp;lt;&amp;lt;Name&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Name&amp;gt;i__Field, type.&amp;lt;Name&amp;gt;i__Field)) &amp;amp;&amp;amp; 
            EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Age&amp;gt;i__Field, type.&amp;lt;Age&amp;gt;i__Field));
    }

    [DebuggerHidden]
    public override int GetHashCode()
    {
        int num = 0x7d068cce;
        num = (-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Name&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Name&amp;gt;i__Field);
        return ((-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Age&amp;gt;i__Field));
    }

    [DebuggerHidden]
    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(&quot;{ Name = &quot;);
        builder.Append(this.&amp;lt;Name&amp;gt;i__Field);
        builder.Append(&quot;, Age = &quot;);
        builder.Append(this.&amp;lt;Age&amp;gt;i__Field);
        builder.Append(&quot; }&quot;);
        return builder.ToString();
    }

    public &amp;lt;Age&amp;gt;j__TPar Age
    {
        get
        {
            return this.&amp;lt;Age&amp;gt;i__Field;
        }
    }

    public &amp;lt;Name&amp;gt;j__TPar Name
    {
        get
        {
            return this.&amp;lt;Name&amp;gt;i__Field;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, a lot of illegal identifiers are used to avoid being duplicated with the type name defined by the programmers. By replacing those identifiers with more readable words, it becomes clear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
internal sealed class AnonymousType0&amp;lt;TName, TAge&amp;gt;
{
    private readonly TAge _age;

    private readonly TName _name;

    public AnonymousType0(TName name, TAge age)
    {
        this._name = name;
        this._age = age;
    }

    public TAge Age
    {
        get
        {
            return this._age;
        }
    }

    public TName Name
    {
        get
        {
            return this._name;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the code at the beginning of this post is actually compiled into:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;&amp;gt;f__AnonymousType0&amp;lt;string, int&amp;gt; mark = new &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;string, int&amp;gt;(&quot;Mark&quot;, 18);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can notice that the anonymous type is atomic, all the properties are read only.&lt;/p&gt;
&lt;p&gt;If running this code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Console.WriteLine(person.GetType().Name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we can get the type name: &amp;lt;&amp;gt;f__AnonymousType0`2. But when we are writing code using anonymous type, its type definition is not generated by compiler yet. There is no way to know the type name, this is why “var” must be used here.&lt;/p&gt;
&lt;h2&gt;Typing&lt;/h2&gt;
&lt;p&gt;Anonymous types reuse the same one type definition if their:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;number of properties are the same&lt;/li&gt;
&lt;li&gt;names of properties are the same&lt;/li&gt;
&lt;li&gt;order of property are the same&lt;/li&gt;
&lt;li&gt;types of properties are the same&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var mark = new { Name = &quot;Mark&quot;, Age = 18 };
var dixin = new { Name = &quot;Dixin&quot;, Age = 18 };
Console.WriteLine(dixin.GetType() == mark.GetType()); // Prints &quot;True&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Equality&lt;/h2&gt;
&lt;p&gt;Since the compiler also generate the code overriding the object.Equals() (see the code snippet above), two instances of the same anonymous type are considered equal if their each property’s value are equal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var mark1 = new { Name = &quot;Mark&quot;, Age = 18 };
var mark2 = new { Name = &quot;Mark&quot;, Age = 18 };
Console.WriteLine(mark1.Equals(mark2)); // Prints &quot;True&quot;.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Features (1) Auto Property</title><link>https://dixin.github.io/posts/understanding-csharp-features-1-auto-property/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-1-auto-property/</guid><description>\] - \]</description><pubDate>Thu, 26 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;As the fundamental of LINQ, This chapter will explain the new language features of C# 3.0, all of which are &lt;a href=&quot;https://en.wikipedia.org/wiki/Syntactic_sugar&quot;&gt;syntactic sugars&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Auto property&lt;/h2&gt;
&lt;p&gt;Before C# 3.0, a property has be with a getter/setter body:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    private string name;

    public string Name
    {
        get { return this.name; }
        set { this.name = value; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is annoying when a class has many properties for data. So C# 3.0+ supports auto property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public string Name { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is a syntactic sugar. The compiler will generate the field definition and getter/setter body:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    [CompilerGenerated]
    private string nameBackingField;

    public string Name
    {
        [CompilerGenerated]
        get { return this.nameBackingField; }

        [CompilerGenerated]
        set { this.nameBackingField = value; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above 3 versions of Person class work the same. works the same as the first sample.&lt;/p&gt;
&lt;h2&gt;Getter only auto property&lt;/h2&gt;
&lt;p&gt;In programming, especially functional programming, it is a good practice to design &lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;atomic/immutable types&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; private set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 6.0 introduced more syntactic sugar to further simplify above code, so private setter can be omitted:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For getter only auto property, compiler generates read only backing field. So getter only auto property can only be initialized from constructor, or from property initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; }

    public Guid Id { get; } = Guid.NewGuid();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above code will be compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    [CompilerGenerated]
    private readonly string nameBackingField;

    [CompilerGenerated]
    private readonly Guid idBackingField = Guid.NewGuid();

    public Person(string name)
    {
        this.nameBackingField = name;
    }

    public string Name
    {
        [CompilerGenerated]
        get { return this.nameBackingField; }
    }

    public Guid Id
    {
        [CompilerGenerated]
        get { return this.idBackingField; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Auto property initializer&lt;/h2&gt;
&lt;p&gt;So getter only auto property can only be initialized from constructor, or from auto property initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; }

    public Guid Id { get; } = Guid.NewGuid();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Expression bodied property-like function member&lt;/h2&gt;
&lt;p&gt;Since C# 3.0, the following Person class can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }

    public string FirstName { get; private set; }

    public string LastName { get; private set; }

    public string FullName
    {
        get
        {
            return string.Format(CultureInfo.InvariantCulture, &quot;{0} {1}&quot;, this.FirstName, this.LastName);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since C# 6.0, the FirstName and LastName properties can be simplified to getter only, and FullName property can be simplified to expression body:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Person(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }

    public string FirstName { get; }

    public string LastName { get; }

    public string FullName =&amp;gt; $&quot;{this.FirstName} {this.LastName}&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice expression bodied property is different from auto property with initializer. Consider the following case:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public Guid Id1 { get; } = Guid.NewGuid();

    public Guid Id2 =&amp;gt; Guid.NewGuid();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every time when Id1 is called, it always returns the same GUID; Every time when Id2 is called, it always returns a new GUID. Actually, above class is compiled to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    [CompilerGenerated]
    private readonly Guid id1BackingField = Guid.NewGuid();

    public Guid Id1
    {
        [CompilerGenerated]
        get { return this.id1BackingField; }
    }

    public Guid Id2
    {
        [CompilerGenerated]
        get { return Guid.NewGuid(); }
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Features (2) Object Initializer, Collection Initializer and Index Initializer</title><link>https://dixin.github.io/posts/understanding-csharp-features-2-object-initializer-collection-initializer-and-index-initializer/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-2-object-initializer-collection-initializer-and-index-initializer/</guid><description>\] - \]</description><pubDate>Thu, 26 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Take this Person type as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person
{
    public string Name { get; set; }

    public int Age { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Object initializer&lt;/h2&gt;
&lt;p&gt;Before C# 3.0, a Person object can be initialized like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Person person = new Person();
person.Name = &quot;Dixin&quot;;
person.Age = 30;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With object initializer syntactic sugar in C# 3.0+, above code can be more declarative:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Person person = new Person()
    {
        Name = &quot;Dixin&quot;,
        Age = 30
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which is will be compiled to above imperative version..&lt;/p&gt;
&lt;h2&gt;Collection initializer&lt;/h2&gt;
&lt;p&gt;Similarly, before C# 3.0, a collection can be initialized like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Collection&amp;lt;Person&amp;gt; persons = new Collection&amp;lt;Person&amp;gt;();
persons.Add(anna);
persons.Add(brian);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C# 3.0+, there is syntactic sugar called collection initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Collection&amp;lt;Person&amp;gt; persons = new Collection&amp;lt;Person&amp;gt;()
    {
        anna, 
        brian
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler will look up the Add() method, and compile collection initializer to above imperative code.&lt;/p&gt;
&lt;p&gt;To use the collection initializer, a collection must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement System.IEnumerable&lt;/li&gt;
&lt;li&gt;Has a Add() instance method or extension method; It takes at least one parameter, and its return value is ignored&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following example demonstrates the minimal requirement of collection initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PersonCollection : IEnumerable
{
    public void Add(Person person)
    {
    }

    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the Add() method takes more than one parameters, this syntax should be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;string, int&amp;gt; persons = new Dictionary&amp;lt;string, int&amp;gt;()
    {
        { &quot;Anna&quot;, 18 }, // Compiled to persons.Add(&quot;Mark&quot;, 18).
        { &quot;Brian&quot;, 19 } // Compiled to persons.Add(&quot;Steven&quot;, 18).
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Index initializer&lt;/h2&gt;
&lt;p&gt;Since C# 6.0, index initializer syntactic sugar makes C# indexer declarative too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PersonDictionary persons = new PersonDictionary()
    {
        [Guid.NewGuid()] = new Person() { Name = &quot;Dixin&quot;, Age = 30 }
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the minimal requirement of index initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PersonDictionary
{
    public Person this[Guid id]
    {
        set { throw new NotImplementedException(); }
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Features (3) Implicit Type and Immutable Anonymous Type</title><link>https://dixin.github.io/posts/understanding-csharp-features-3-implicit-type-and-immutable-anonymous-type/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-features-3-implicit-type-and-immutable-anonymous-type/</guid><description>\] - \]</description><pubDate>Thu, 26 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt;] - [&lt;a href=&quot;/archive/?tag=C%23%20Features&quot;&gt;C# Features&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;Local variable type inference&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb383973.aspx&quot;&gt;var keyword&lt;/a&gt; is introduced since C# 3.0. Consider the local variable declaration and initialization:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TypeName localVariable = value;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the type of localVariable can be inferred from the type of value, it is Ok to write code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var localVariable = value; // Compiler infers type of localVariable from type of value.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are some samples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var a = 1;
var b = 1.0;
var c = &quot;Mark&quot;;
var d = null as Uri;
var e = default(IEnumerable&amp;lt;Person&amp;gt;);
var f = File.ReadAllLines(filePath);
var g = f.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are identical to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int a = 1;
double b = 1.0;
string c = &quot;Mark&quot;;
Uri d = null;
IEnumerable&amp;lt;Person&amp;gt; e = default(IEnumerable&amp;lt;Person&amp;gt;);
string[] f = File.ReadAllLines(filePath);
int g = f.Length;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice that type inference must be applied to local variables declaration and initialization statement. The following cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var a; // Compiler cannot infer the type of a.
var b = null; // Compiler cannot infer the type of b.

private var Func() // Compiler cannot infer the type of return value.
{
    throw new NotImplementedException();
}

private void Action(var paramter) // Compiler cannot infer the type of parameter.
{
    throw new NotImplementedException();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;var vs. explicit typing&lt;/h3&gt;
&lt;p&gt;Sometimes the “var” keyword seems somewhat convenient:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dictionary&amp;lt;string, IEnumerable&amp;lt;Person&amp;gt;&amp;gt; dictionary1 = GetDictionary();
var dictionary2 = GetDictionary();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But for consistency, It is a good practice to &lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;use explicit type when possible, use var when needed&lt;/a&gt;, like anonymous type. This entire tutorial follows this.&lt;/p&gt;
&lt;h3&gt;var vs. dynamic&lt;/h3&gt;
&lt;p&gt;C# 4.0 introduces another &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd264741.aspx&quot;&gt;keyword dynamic&lt;/a&gt;. var is totally different from dynamic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var is for implicit typed local variables, which works at compiled time&lt;/li&gt;
&lt;li&gt;dynamic is like System.Object. Compiler allow any operation on a dynamic object. Exception is thrown at runtime if operation is invalid..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above invalid var examples can be compiled by replacing var with dynamic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic a; // object a;
dynamic b = null; // object b = null;

private dynamic Func() // private object Func()
{
    throw new NotImplementedException();
}

private void Action(dynamic paramter) // private void Action(object paramter)
{
    throw new NotImplementedException();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Immutable anonymous type&lt;/h2&gt;
&lt;p&gt;This feature provides a way to create an instance without specifying the type name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var dixin = new 
    { 
        Name = &quot;Dixin&quot;, 
        Age = 30 
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the type name is unknown at design time, this is called a anonymous type. At compile time, the type definition will be generated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[CompilerGenerated]
[DebuggerDisplay(@&quot;\{ Name = {Name}, Age = {Age} }&quot;, Type = &quot;&amp;lt;Anonymous Type&amp;gt;&quot;)]
internal sealed class AnonymousType&amp;lt;TName, TAge&amp;gt;
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly TName nameBackingField;

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly TAge ageBackingField;

    [DebuggerHidden]
    public AnonymousType(TName name, TAge age)
    {
        this.nameBackingField = name;
        this.ageBackingField = age;
    }

    public TAge Age { get { return this.ageBackingField; } }

    public TName Name { get { return this.nameBackingField; } }

    [DebuggerHidden]
    public override bool Equals(object value)
    {
        AnonymousType&amp;lt;TName, TAge&amp;gt; anonymous = value as AnonymousType&amp;lt;TName, TAge&amp;gt;;
        return anonymous != null
            &amp;amp;&amp;amp; EqualityComparer&amp;lt;TName&amp;gt;.Default.Equals(this.nameBackingField, anonymous.nameBackingField)
            &amp;amp;&amp;amp; EqualityComparer&amp;lt;TAge&amp;gt;.Default.Equals(this.ageBackingField, anonymous.ageBackingField);
    }

    [DebuggerHidden]
    public override int GetHashCode()
    {
        int num = 0x7d068cce;
        num = (-1521134295 * num) + EqualityComparer&amp;lt;TName&amp;gt;.Default.GetHashCode(this.nameBackingField);
        return ((-1521134295 * num) + EqualityComparer&amp;lt;TAge&amp;gt;.Default.GetHashCode(this.ageBackingField));
    }

    [DebuggerHidden]
    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(&quot;{ Name = &quot;);
        builder.Append(this.nameBackingField);
        builder.Append(&quot;, Age = &quot;);
        builder.Append(this.ageBackingField);
        builder.Append(&quot; }&quot;);
        return builder.ToString();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is atomic/immutable type. And the instantiation code s compiled to constructor call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AnonymousType&amp;lt;string, int&amp;gt; dixin = new AnonymousType&amp;lt;string, int&amp;gt;(&quot;Dixin&quot;, 30);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, at design time, the type definition is not generated yet, this is why var must be used.&lt;/p&gt;
&lt;h3&gt;Reuse type definition&lt;/h3&gt;
&lt;p&gt;Anonymous type are reused by 2 anonymous instantiation if they have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the same number of properties&lt;/li&gt;
&lt;li&gt;the same names of properties&lt;/li&gt;
&lt;li&gt;the same order of property&lt;/li&gt;
&lt;li&gt;the same types of properties&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod()]
public void ReuseAnonymousType()
{
    var anna = new { Name = &quot;Anna&quot;, Age = 18 };
    var bill = new { Name = &quot;Bill&quot;, Age = 19 };
    Assert.AreSame(anna.GetType(), bill.GetType()); // Passes.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Equality&lt;/h3&gt;
&lt;p&gt;Compiler also generates a override of object.Equals(), two anonymous objects are equal if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;they are of the same anonymous type&lt;/li&gt;
&lt;li&gt;their each property’s value are equal&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod()]
public void AnonymousObjectEquality()
{
    Assert.AreEqual(
        new { Name = &quot;Dixin&quot;, Age = 30 }, 
        new { Name = &quot;Dixin&quot;, Age = 30 }); // Passes.
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Introducing LINQ (2) Advancements Overview</title><link>https://dixin.github.io/posts/introducing-linq-2-advancements-overview/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-linq-2-advancements-overview/</guid><description>\]</description><pubDate>Tue, 24 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[&lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C# series&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&quot;http://msdn.microsoft.com/en-us/netframework/aa904594.aspx&quot;&gt;MSDN&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LINQ is one of Microsoft’s most exciting, powerful new development technologies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Independent to data source&lt;/h2&gt;
&lt;p&gt;This sample mentioned in &lt;a href=&quot;/posts/introducing-linq-1-what-is-linq&quot;&gt;part 1&lt;/a&gt; is working on items in a .NET array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from number in source
               where number &amp;gt; 0
               orderby number descending
               select number;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of LINQ query expression can also be used on other data source, like data in SQL Server, data on the Internet, etc.&lt;/p&gt;
&lt;h2&gt;Strong typing&lt;/h2&gt;
&lt;p&gt;It is obvious that each item in the above LINQ query is strong typed: source is an int[], number is an int. Even we used “var” keyword for results, it is actually an IEnumerable&amp;lt;int&amp;gt;.&lt;/p&gt;
&lt;p&gt;Since the data is strong typed, intellisense can work in IDE:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/introducinglinqadvancementsoverview1_49F804F0.png&quot; alt=&quot;introducing-linq-advancements-overview-1&quot; title=&quot;introducing-linq-advancements-overview-1&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Query compilation&lt;/h2&gt;
&lt;p&gt;The query expression looks like a SQL query. But they are totally different. For example, in the previous LINQ to SQL scenario, the T-SQL “SELECT” statement is not compiled, but the C# “select” query expression is compiled. Strong typing and the ability of identifying issues in compile time provides outstanding productivity.&lt;/p&gt;
&lt;h2&gt;Deferred execution&lt;/h2&gt;
&lt;p&gt;Deferred execution is a feature of functional programming. Now it is introduced all over the LINQ. In the runtime, when this statement finished executing, we got the local variable: products.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from product in database.Products
               where product.Category.CategoryName == &quot;Beverages&quot;
               orderby product.ProductName
               select product.ProductName; // Defines the query.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice at this time positive is not the query result, but the query definition itself.&lt;/p&gt;
&lt;p&gt;When we iterate the results, which means the results need to be fetched, the query executes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (var item in results) // Executes the query when we need the query results.
{
    Console.WriteLine(item);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;LINQ is far more than querying&lt;/h2&gt;
&lt;p&gt;Beside querying different data sources, LINQ also brings&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;functional programming constructs to C# (Check this article for &lt;a href=&quot;http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html&quot;&gt;functional programming&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;a way of parallel computing (See &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd460688(VS.100).aspx&quot;&gt;Parallel LINQ&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;reactive programming (See &lt;a href=&quot;http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx&quot;&gt;Rx&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;LINQ does not only change the way of working with data, like writing , it also changes the way of thinking on problems.&lt;/p&gt;
</content:encoded></item><item><title>Mac OSX Turns Dual Core Laptop into Solo Core</title><link>https://dixin.github.io/posts/mac-osx-turns-dual-core-laptop-into-solo-core/</link><guid isPermaLink="true">https://dixin.github.io/posts/mac-osx-turns-dual-core-laptop-into-solo-core/</guid><description>This is blogged because it is surprising. Some months ago my friend and me were investigating Mac OSX for my , so we installed the latest version on a machine, [SAMSUN</description><pubDate>Wed, 11 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is blogged because it is surprising. Some months ago my friend and me were investigating Mac OSX for my &lt;a href=&quot;http://www.coolwebos.com&quot;&gt;WebOS&lt;/a&gt;, so we installed the latest version on a machine, &lt;a href=&quot;http://www.samsung.com/he/products/notebookcomputer/r_series/np_r25.asp&quot;&gt;SAMSUNG R25 XE04&lt;/a&gt; with a &lt;a href=&quot;http://processorfinder.intel.com/details.aspx?sSpec=SLA4K&quot;&gt;T2330&lt;/a&gt; Dual Core CPU. After that, Windows 7 was installed back. However, Windows recognized his laptop as a Solo Core CPU.&lt;/p&gt;
&lt;p&gt;Obviously the resolution is to refresh / update the BIOS. We searched the Internet for this, and found a number of people having this problem. It is hard to understand why could this happen.&lt;/p&gt;
</content:encoded></item><item><title>The Funny Enum.ToString(IFormatProvider) Method</title><link>https://dixin.github.io/posts/the-funny-enum-tostring-iformatprovider-method/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-funny-enum-tostring-iformatprovider-method/</guid><description>Here is a ToString(IFormatProvider) method on the System.Enum type. It looks a IformatProvider (like CultureInfo) can be passed to this method:</description><pubDate>Sat, 17 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here is a ToString(IFormatProvider) method on the System.Enum type. It looks a IformatProvider (like CultureInfo) can be passed to this method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;someEnum.ToString(cultureInfo);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this is the source code from .NET 1.1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// &amp;lt;para&amp;gt; Converts the value of this instance to 
/// its equivalent string representation using the specified
/// format information. &amp;lt;/para&amp;gt;
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot; provider&quot;&amp;gt;(Reserved) An &amp;lt;see cref=&quot;T:System.IFormatProvider&quot; /&amp;gt; that supplies format information about this instance.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;
/// &amp;lt;para&amp;gt;The string 
/// representation of the name of the value of this instance as
/// specified by &amp;lt;paramref name=&quot;provider&quot; /&amp;gt;.&amp;lt;/para&amp;gt;
/// &amp;lt;/returns&amp;gt;
public string ToString(IFormatProvider provider)
{
    return this.ToString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside this method, it does nothing with the IFormatProvider parameter. Actually it does not make any sense to specify such a parameter for a enum. Enum should be used for programming.&lt;/p&gt;
&lt;p&gt;So since .NET 2.0, this method is marked as obsolete:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Obsolete(&quot;The provider argument is not used. Please use ToString().&quot;)]
public string ToString(IFormatProvider provider)
{
    return this.ToString();
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# Coding Guidelines (7) Tools</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-7-tools/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-7-tools/</guid><description>C# Coding Guidelines:</description><pubDate>Wed, 14 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-1-fundamentals&quot;&gt;C# Coding Guidelines (1) Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;C# Coding Guidelines (4) Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-5-exceptions&quot;&gt;C# Coding Guidelines (5) Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (7) Tools&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this article some excellent tools for code quality will be introduced.&lt;/p&gt;
&lt;h2&gt;FxCop / Code Analysis&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx&quot;&gt;FxCop&lt;/a&gt; is standalone while Code Analysis is integrated in Visual Studio, but many developer do not quite care about it.&lt;/p&gt;
&lt;p&gt;Its original purpose is programmatic enforcement of the &lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/ref=dp_ob_title_bk&quot;&gt;Framework Design Guidelines&lt;/a&gt;. Applying Code Analysis in the daily coding will be helpful to build the habit of professional coding.&lt;/p&gt;
&lt;p&gt;You can get a lot of useful information from the &lt;a href=&quot;http://blogs.msdn.com/fxcop/&quot;&gt;Code Analysis Team Blog&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;StyleCop&lt;/h2&gt;
&lt;p&gt;Many people never used this tool. Personally I like it very much. &lt;a href=&quot;http://code.msdn.microsoft.com/sourceanalysis&quot;&gt;StyleCop&lt;/a&gt; analyzes C# source code to enforce a set of style and consistency rules, which are customizable.&lt;/p&gt;
&lt;p&gt;After the installation it can be integrated into Visual Studio:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_2.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can download the latest version from &lt;a href=&quot;http://code.msdn.microsoft.com/sourceanalysis/Release/ProjectReleases.aspx?ReleaseId=1425&quot;&gt;here&lt;/a&gt;. And the StyleCop Team Blog is &lt;a href=&quot;http://blogs.msdn.com/sourceanalysis/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Resharper + [StyleCop For Resharper]&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.jetbrains.com/resharper/index.html&quot;&gt;Resharper&lt;/a&gt; is the most powerful plug-in for Visual Studio I have ever used. Its features include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jetbrains.com/resharper/documentation/presentation/overview/quick-fixes/qf_ca_demo.htm&quot;&gt;error analysis and suggestions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jetbrains.com/resharper/documentation/presentation/overview/navigation/Navigate_from_here_demo.htm&quot;&gt;navigation and search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jetbrains.com/resharper/documentation/presentation/overview/code_generation/Generate_demo.htm&quot;&gt;code generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jetbrains.com/resharper/documentation/presentation/overview/refactorings/Refactor_this_demo.htm&quot;&gt;refactorings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Itself also supports plug-ins, like this excellent &lt;a href=&quot;http://www.codeplex.com/StyleCopForReSharper&quot;&gt;StyleCop for ReSharper&lt;/a&gt;. After the installation, Visual Studio becomes like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_6.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_thumb_2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The developer cannot get rid of even a slight coding style inconsistency.&lt;/p&gt;
&lt;p&gt;And this is its Code Cleanup feature:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_4.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines7Tools_12A4B/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So many customizable rules make it incomparable with the Ctrl + K + D of Visual Studio.&lt;/p&gt;
&lt;h2&gt;GhostDoc&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://submain.com/products/ghostdoc.aspx&quot;&gt;GhostDoc&lt;/a&gt; is a small plug-in of Visual Studio used to generate XML documentation comments. Using GhostDoc greatly saves a lot time.&lt;/p&gt;
&lt;h2&gt;Sandcastle&lt;/h2&gt;
&lt;p&gt;This is a toolkit for generating document from the XML comments in the code.&lt;/p&gt;
&lt;p&gt;These are needed to install:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkId=14188&quot;&gt;Microsoft HTML Help Workshop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sandcastle.codeplex.com/&quot;&gt;Sandcastle Documentation Compiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.codeplex.com/SHFB&quot;&gt;Sandcastle Help File Builder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then just:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;import the solution;&lt;/li&gt;
&lt;li&gt;customize the configurations;&lt;/li&gt;
&lt;li&gt;build the document.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then the MSDN-like document is built, which looks very professional. Here are some snapshots in &lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;part 6&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>C# Coding Guidelines (6) Documentation</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-6-documentation/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-6-documentation/</guid><description>C# Coding Guidelines:</description><pubDate>Tue, 13 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-1-fundamentals&quot;&gt;C# Coding Guidelines (1) Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;C# Coding Guidelines (4) Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-5-exceptions&quot;&gt;C# Coding Guidelines (5) Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (6) Documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post topics like “whether we should use Chinese in the C# comment documentation or not” will not be discussed.&lt;/p&gt;
&lt;p&gt;It is difficult to find detailed articles on how to write comments for C# code in a professional way. If you find anything incorrect, or if you have any better ideas, please do reply me.&lt;/p&gt;
&lt;h2&gt;Fundamentals&lt;/h2&gt;
&lt;p&gt;This sample code is from my &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/09/20/introducing-coolwebos-com.html&quot;&gt;so called WebOS&lt;/a&gt; (&lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;http://www.CoolWebOS.com/&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace WebOS.Common
{
    using System;
    using System.Linq;

    using Properties;

    /// &amp;lt;summary&amp;gt;
    /// Provides extension methods for the &amp;lt;see cref=&quot;T:System.Linq.IQueryable`1&quot;/&amp;gt; interface.
    /// &amp;lt;/summary&amp;gt;
    public static class QueryableExtensions
    {
        #region Public Methods

        /// &amp;lt;summary&amp;gt;
        /// Gets a collection of elemets in the data source in pages of a sequence.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name=&quot;TSource&quot;&amp;gt;
        /// The type of the source.
        /// &amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name=&quot;source&quot;&amp;gt;
        /// The &amp;lt;see cref=&quot;T:System.Linq.IQueryable`1&quot;/&amp;gt; for pagination.
        /// &amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;pageIndex&quot;&amp;gt;
        /// The index of the page of results to return. &amp;lt;paramref name=&quot;pageIndex&quot;/&amp;gt; is zero-based.
        /// &amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;pageSize&quot;&amp;gt;
        /// The size of the page of results to return.
        /// &amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;
        /// An &amp;lt;see cref=&quot;T:System.Linq.IQueryable`1&quot;/&amp;gt; that contains elements in the specified page of the input sequence.
        /// &amp;lt;/returns&amp;gt;
        /// &amp;lt;exception cref=&quot;T:System.ArgumentNullException&quot;&amp;gt;
        /// &amp;lt;paramref name=&quot;source&quot;/&amp;gt; is null.
        /// &amp;lt;/exception&amp;gt;
        /// &amp;lt;exception cref=&quot;T:System.ArgumentOutOfRangeException&quot;&amp;gt;
        /// &amp;lt;paramref name=&quot;pageIndex&quot;/&amp;gt; is less than zero or &amp;lt;paramref name=&quot;pageSize&quot;/&amp;gt; is less than zero.
        /// &amp;lt;/exception&amp;gt;
        public static IQueryable&amp;lt;TSource&amp;gt; Page&amp;lt;TSource&amp;gt;(this IQueryable&amp;lt;TSource&amp;gt; source, int pageIndex, int pageSize)
        {
            if (source == null)
            {
                throw new ArgumentNullException(&quot;source&quot;);
            }

            if (pageIndex &amp;lt; 0)
            {
                throw new ArgumentOutOfRangeException(&quot;pageIndex&quot;, Resource.PageIndexShouldNotBeNegative);
            }

            if (pageSize &amp;lt; 0)
            {
                throw new ArgumentOutOfRangeException(&quot;pageSize&quot;, Resource.PageSizeShouldNotBeNegative);
            }

            // Deferred execution works here.
            return source.Skip(pageIndex * pageSize).Take(pageSize);
        }

        #endregion
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use Microsoft XML documentation tags to write the comments.&lt;/p&gt;
&lt;p&gt;You can see the list of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/5ast78ax.aspx&quot;&gt;recommended xml tags for documentation comments&lt;/a&gt; from MSDN, as well as the &lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/cc302121.aspx&quot;&gt;basic usage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use &amp;lt;see&amp;gt; when referring to a type / member in the comments.&lt;/p&gt;
&lt;p&gt;This rule is specially mentioned because I saw a lot people incorrectly using &amp;lt;c&amp;gt;.&lt;/p&gt;
&lt;p&gt;Here is a sample of referring to property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;exception cref=&quot;T:System.Runtime.Serialization.SerializationException&quot;&amp;gt;
/// The class name is null or &amp;lt;see cref=&quot;P:System.Exception.HResult&quot;/&amp;gt; is zero (0).
/// &amp;lt;/exception&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and a sample of referring to a generic interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;returns&amp;gt;
/// An &amp;lt;see cref=&quot;T:System.Linq.IQueryable`1&quot;/&amp;gt; that contains elements in the specified page of the input sequence.
/// &amp;lt;/returns&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use one space between “///” or “//” and your comments.&lt;/p&gt;
&lt;p&gt;This is easy but a lot of developers writing comment immediately after the slash.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use a capitalized letter to start the comment, unless it is a specified identifier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use a punctuation to end the comment.&lt;/p&gt;
&lt;p&gt;The above two rules are too easy to forgot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use a blank line before a single line comment, unless this single line comment is after another single line comment, or it is the fist line of the scope.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use a blank line after a single line comment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider writing comment document for all non-private members and types.&lt;/p&gt;
&lt;p&gt;The word “consider” is used because this is too hard or unnecessary for most projects.&lt;/p&gt;
&lt;h2&gt;Members&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider using third person singular verb to start the summary of members.&lt;/p&gt;
&lt;p&gt;Here are some samples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For methods:
&lt;ul&gt;
&lt;li&gt;Gets xxx with the specified xxx.&lt;/li&gt;
&lt;li&gt;Applies xxx over xxx.&lt;/li&gt;
&lt;li&gt;Converts xxx to xxx.&lt;/li&gt;
&lt;li&gt;Computes xxx of xxx.&lt;/li&gt;
&lt;li&gt;Returns xxx of xxx.&lt;/li&gt;
&lt;li&gt;Invokes xxx on xxx.&lt;/li&gt;
&lt;li&gt;Sorts the elements of xxx in ascending order according to xxx.&lt;/li&gt;
&lt;li&gt;Create xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For properties:
&lt;ul&gt;
&lt;li&gt;Gets xxx.&lt;/li&gt;
&lt;li&gt;Gets or sets xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For events:
&lt;ul&gt;
&lt;li&gt;Occurs when xxx.&lt;/li&gt;
&lt;li&gt;Occurs before xxx.&lt;/li&gt;
&lt;li&gt;Occurs after xxx.&lt;/li&gt;
&lt;li&gt;Occurs at the beginning of xxx.&lt;/li&gt;
&lt;li&gt;Occurs at the end of xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “Initializes a new instance of the xxx class.” for the summary of constructors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “Gets” to start the summary on read only property, and use “Gets or sets” to start the summary of read write property.&lt;/p&gt;
&lt;p&gt;Write only property is not preferred just as &lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;part 3&lt;/a&gt; said.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “Gets a value indicating whether xxx” or “Gets or sets a value indicating whether xxx” to start the summary of methods / properties returning a bool value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if xxx; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.” for the comment on bool return value.&lt;/p&gt;
&lt;p&gt;Here is a sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Gets a value indicating whether the user can be authenticated.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;
/// &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the user can be authenticated; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.
/// &amp;lt;/returns&amp;gt;
public bool IsApproved
{
    get;
    private set;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “Finalizes an instance of the xxx class.” for the summary of finalizers.&lt;/p&gt;
&lt;h2&gt;Types&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider using third person singular verb to start the summary of types, except it is an exception.&lt;/p&gt;
&lt;p&gt;Here are some samples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For normal classes / structs:
&lt;ul&gt;
&lt;li&gt;Represents xxx as xxx.&lt;/li&gt;
&lt;li&gt;Provides xxx for xxx.&lt;/li&gt;
&lt;li&gt;Provides the base class from which the classes that represent xxx are derived.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For attributes:
&lt;ul&gt;
&lt;li&gt;Instructs xxx.&lt;/li&gt;
&lt;li&gt;Specifies xxx.&lt;/li&gt;
&lt;li&gt;Defines xxx.&lt;/li&gt;
&lt;li&gt;Indicates xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For delegates:
&lt;ul&gt;
&lt;li&gt;Represents the method that xxx.&lt;/li&gt;
&lt;li&gt;Encapsulates a method that xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For interfaces:
&lt;ul&gt;
&lt;li&gt;Defines methods to xxx.&lt;/li&gt;
&lt;li&gt;Provides a mechanism for xxx / functionality to xxx.&lt;/li&gt;
&lt;li&gt;Represents xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For enums:
&lt;ul&gt;
&lt;li&gt;Describes xxx.&lt;/li&gt;
&lt;li&gt;Defines xxx.&lt;/li&gt;
&lt;li&gt;Identifies xxx.&lt;/li&gt;
&lt;li&gt;Specifies flags for xxx.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use “The exception that is thrown when xxx.” for the summary of exceptions.&lt;/p&gt;
&lt;h2&gt;Generate documents&lt;/h2&gt;
&lt;p&gt;If you use those Microsoft xml documentation correctly, your code document could be generated correctly.&lt;/p&gt;
&lt;p&gt;This is the intellisense when writing code with the API at the beginning of this article:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_8.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_thumb_3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and this is the hint parameter:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_4.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_thumb_1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also use &lt;a href=&quot;http://sandcastle.codeplex.com/&quot;&gt;Sandcastle&lt;/a&gt; to generate MSDN-like documentation:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_12.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_thumb_5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the document for the code at the beginning of this article:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_14.png&quot;&gt;&lt;img src=&quot;http://images.cnblogs.com/cnblogs_com/dixin/WindowsLiveWriter/CCodingGuidelines6Documentation_C8DF/image_thumb_6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sandcastle will be introduced in &lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;part 7&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Microsofty Kids Around (3) Mark Junior</title><link>https://dixin.github.io/posts/microsofty-kids-3-mark-junior/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsofty-kids-3-mark-junior/</guid><description>Actually this baby is not so Microsofty currently, but his father  is so Microsoftily crazy, so everyone believes that he will become so very soon.</description><pubDate>Tue, 13 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Actually this baby is not so Microsofty currently, but his father &lt;a href=&quot;http://www.markzhou.com/blog/&quot;&gt;Mark&lt;/a&gt; is so Microsoftily crazy, so everyone believes that he will become so very soon.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/markjunior1_44DC3115.jpg&quot; alt=&quot;mark-junior-1&quot; title=&quot;mark-junior-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/markjunior2_28EAFC1D.jpg&quot; alt=&quot;mark-junior-2&quot; title=&quot;mark-junior-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;His father, Mark, was an excellent developer / development lead of Microsoft projects, as well as my buddy. &lt;a href=&quot;http://fastdev.spaces.live.com/blog/cns!8A0406089AAD8752!1126.entry&quot;&gt;We discuss a lot of things&lt;/a&gt; about him. And here are the conclusions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;His father complained that, according to &lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;my post&lt;/a&gt;, constructor is better to be lightweight, but his constructor is not so well and ran for 280 days…&lt;/li&gt;
&lt;li&gt;Some properties or behaviors were override from parents, which would possibly break &lt;a href=&quot;http://en.wikipedia.org/wiki/Liskov_substitution_principle&quot;&gt;Liskov substitution principle&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Obvious &lt;a href=&quot;http://en.wikipedia.org/wiki/Side_effect_(computer_science)&quot;&gt;side effects&lt;/a&gt;, like making parents very nervous and tried, etc.&lt;/li&gt;
&lt;li&gt;Resource costly. A large quantity of resource exhausted to construct just one instance.&lt;/li&gt;
&lt;li&gt;He is not covariant or contravariant.&lt;/li&gt;
&lt;li&gt;He implements neither System.IComparable nor System.IComparable&amp;lt;T&amp;gt;. We cannot compare him with the other guys’ babies.&lt;/li&gt;
&lt;li&gt;He is not &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/08/csharp-coding-guidelines-4-type.html&quot;&gt;atomic&lt;/a&gt;. He can change during the runtime. I think he is more like the dynamic object in .NET 4.0, supporting late bindings of behaviors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I suggest his parents to implement this interface for him:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IAffluent
{
    void GetGiftAround(decimal money);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally we discussed the variant relationship of the stealing stuff behavior and stealing drink behavior:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Stuff is the base class of Drink.
internal class Drink : object
{
}

internal class Program
{
    // The behavior of stealing stuff.
    private static void StealStuff(object stuff)
    {
    }

    // The behavior of stealing Drink.
    private static void StealDrink(Drink drink)
    {
    }

    private static void Main()
    {
        Action&amp;lt;Drink&amp;gt; stealDrink = StealDrink;
        Action&amp;lt;object&amp;gt; stealStuff = StealStuff;

        // Contravariance.
        Action&amp;lt;Drink&amp;gt; contralvariance = StealStuff;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see more details about variances in &lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;my posts&lt;/a&gt;. And you can see more photos of the baby &lt;a href=&quot;https://cid-8a0406089aad8752.skydrive.live.com/browse.aspx/.res/8a0406089aad8752!1113?ct=photos&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>C# Coding Guidelines (5) Exceptions</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-5-exceptions/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-5-exceptions/</guid><description>C# Coding Guidelines:</description><pubDate>Sun, 11 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-1-fundamentals&quot;&gt;C# Coding Guidelines (1) Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;C# Coding Guidelines (4) Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (5) Exceptions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a true story. Once a developer wrote a bunch of code, which crashed frequently:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Action1();
Action2();
// ...
ActionN();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So he was asked to fix the code, and his solution is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    Action1();
    Action2();
    // ...
    ActionN();
}
catch
{
    // Fails silently.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other developers became crazy when they saw this “Fails silently.” comment during debugging.&lt;/p&gt;
&lt;h2&gt;Throw exceptions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Throw an exception if something goes unexpectedly, so that the code will not continue executing in a corrupted or unpredictable status, and report this to the upper code in the call stack.&lt;/p&gt;
&lt;p&gt;An exception is not equal to an error. An exception is thrown means something unexpected happens. For example, there a correct function executing. But if the memory is exhausted, an OutOfMemoryException will be thrown. This memory-exhausted situation is something unexpected by the code.&lt;/p&gt;
&lt;p&gt;A very frequently asked question is, “When we cannot find something, should we return null or throw an exception?”. According to this rule, it is clear that logically exception has nothing to do with the return value. Once something goes unexpectedly, throw an exception to stop executing, and report to the upper code in the call stack.&lt;/p&gt;
&lt;p&gt;A typical usage of the exception is the parameter checking. Just as &lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;part 3&lt;/a&gt; mentioned, when writing public methods, the first thing is to check the parameters. If the parameters are unexpected, throw an exception:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.ArgumentException,&lt;/li&gt;
&lt;li&gt;System.ArgumentNullException,&lt;/li&gt;
&lt;li&gt;System.ArgumentOutOfRangeException&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void GetTaxonomy(Uri uri)
{
    if (uri == null)
    {
        // The null URI is unexpected.
        throw new ArgumentNullException(&quot;uri&quot;, message);
    }

    // Works with the URI.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After an exception is thrown, the thread is suspended, and the upper code in the call stack has got a chance to handle it. If no code is going to handling that exception, the program is terminated. Just like &lt;a href=&quot;http://www.wintellect.com/cs/blogs/jeffreyr/default.aspx&quot;&gt;Jeffrey Richter&lt;/a&gt; said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is much better for a program to crash than to continue running with unpredictable behavior and potential security vulnerabilities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consistently use exceptions instead of return value based reporting.&lt;/p&gt;
&lt;p&gt;One simple reason is, in some scenarios it is impossible to report with the return value, like in the constructor. For the consistency consideration, exception should always be used.&lt;/p&gt;
&lt;p&gt;If something fails, It could bring a lot of issues if the code continue running. The choice is throw an exception and stop right away.&lt;/p&gt;
&lt;p&gt;But in FCL, there are some return value based reporting, like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Web.Security
{
    public abstract class MembershipProvider : ProviderBase
    {
        public abstract MembershipUser CreateUser(
            string username,
            string password,
            string email,
            string passwordQuestion,
            string passwordAnswer,
            bool isApproved,
            object providerUserKey,
            out MembershipCreateStatus status);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It outputs a MembershipCreateStatus enum to report the status:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Web.Security
{
    public enum MembershipCreateStatus
    {
        Success,
        InvalidUserName,
        InvalidPassword,
        InvalidQuestion,
        InvalidAnswer,
        InvalidEmail,
        DuplicateUserName,
        DuplicateEmail,
        UserRejected,
        InvalidProviderUserKey,
        DuplicateProviderUserKey,
        ProviderError
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; In a fatal situation, call Environment.FailFast() to terminate the process instead of throwing an exception.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not throw nonspecific exceptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Exception&lt;/li&gt;
&lt;li&gt;System.SystemException&lt;/li&gt;
&lt;li&gt;System.ApplicationException&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not throw CLR exceptions.&lt;/p&gt;
&lt;p&gt;These are explicitly enumerated by &lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/ref=dp_ob_title_bk&quot;&gt;Framework Design Guidelines&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.AccessViolationException&lt;/li&gt;
&lt;li&gt;System.ExecutionEngineException&lt;/li&gt;
&lt;li&gt;System.IndexOutOfRangeException&lt;/li&gt;
&lt;li&gt;System.NullReferenceException&lt;/li&gt;
&lt;li&gt;System.OutOfMemoryException&lt;/li&gt;
&lt;li&gt;System.StackOverflowException&lt;/li&gt;
&lt;li&gt;System.Runtime.InteropServices.COMException&lt;/li&gt;
&lt;li&gt;System.Runtime.InteropServices.SEHException&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;h2&gt;Handle exceptions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider catching an exception when knowing about how to recover from that exception.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Avoid catching a nonspecific exception, and swallowing it.&lt;/p&gt;
&lt;p&gt;These code are unprofessional:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    Action1();
    Action2();
    // ...
    ActionN();
}
catch
{
    // Fails silently.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    Action1();
    Action2();
    // ...
    ActionN();
}
catch (Exception)
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    Action1();
    Action2();
    // ...
    ActionN();
}
catch (Exception exception)
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But it is Ok if catching a nonspecific exception, then do something (like logging, etc.) and re-throw it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Catch exception for specific execution.&lt;/p&gt;
&lt;p&gt;Do not lazily put a big bunch of code into a try block. It is necessary to figure out where exactly the exceptions are throw, and how to exactly recover from those exceptions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Action1();

try
{
    Action2();
}
catch (FileNotFoundException exception)
{
    // Recover.
}
catch (InvalidOperationException exception)
{
    // Recover.
}

Action3();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not catch and swallow CLR exceptions.&lt;/p&gt;
&lt;p&gt;Actually, even if code is written to catch some CLR critical exception, usually it will not work. A typical sample is StackOverflowException thrown by CLR. Once stack overflow happens, program will be terminated. the code in the catch block and finally block will never execute.&lt;/p&gt;
&lt;p&gt;Take a look at the following Fibonacci function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static long Fibonacci(int value)
{
    if (value &amp;lt; 0)
    {
        throw new ArgumentOutOfRangeException(&quot;value&quot;);
    }

    if (value == 0)
    {
        return 0;
    }

    if (value == 1)
    {
        return 1;
    }

    return Fibonacci(value - 1) + Fibonacci(value - 2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above function is very ineffective with a recursive computing. Write some experimental stack overflow code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Program
{
    private static void Main()
    {
        long result = 0;
        try
        {
            result = Fibonacci(int.MaxValue);
        }
        catch (StackOverflowException)
        {
            // Never execute.
            Console.WriteLine(&quot;Inside catch.&quot;);
        }
        finally
        {
            // Never execute.
            Console.WriteLine(&quot;Inside finally.&quot;);
        }

        // Never execute.
        Console.WriteLine(result);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code demonstrates writing code to catch CLR exceptions like StackOverflowException is useless.&lt;/p&gt;
&lt;h2&gt;Effectively work with exceptions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Reuse FCL exception when possible, create a new exception when needed.&lt;/p&gt;
&lt;p&gt;In 80%+ of the scenarios, creating a customized exception type is not needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider using exception helper for uniformed exception handling in the application.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal static class ExceptionHelper
{
    internal static void ThrowInvalidOperationException(parameters)
    {
        // Build message.
        // Write log.
        throw new InvalidOperationException(message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very useful for &lt;a href=&quot;http://en.wikipedia.org/wiki/Don&apos;t_repeat_yourself&quot;&gt;DRY&lt;/a&gt; and standardization consideration. Another example is the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd203116.aspx&quot;&gt;Exception Handling Application Block&lt;/a&gt; of Microsoft &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc467894.aspx&quot;&gt;Enterprise Library&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    // ...
}
catch (Exception exception)
{
    if (ExceptionPolicy.HandleException(exception, &quot;PolicyName&quot;))
    {
        throw;
    }

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider Trier-Doer Pattern for the API which frequently throw exceptions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public struct Int32
    {
        public static int Parse(string s)
        {
        }

        public static bool TryParse(string s, out int result)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When there a Do() method which frequently throw exceptions, provide a TryDo() method which is not likely to throw exceptions but using a bool to indicate the success.&lt;/p&gt;
&lt;p&gt;By the way, the above parameter name “s” does not make sense. “value” should be better. See &lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;part 2&lt;/a&gt; for naming.&lt;/p&gt;
</content:encoded></item><item><title>Microsofty Kids Around (2) My Nephew</title><link>https://dixin.github.io/posts/microsofty-kids-around-2-my-nephew/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsofty-kids-around-2-my-nephew/</guid><description>This is my nephew is very cute. And he is even cuter with this Microsofty T-shirt:</description><pubDate>Fri, 09 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is my nephew is very cute. And he is even cuter with this Microsofty T-shirt:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/mynephew1_3BCAAF5C.jpg&quot; alt=&quot;my-nephew-1&quot; title=&quot;my-nephew-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/mynephew2_3CDF987B.jpg&quot; alt=&quot;my-nephew-2&quot; title=&quot;my-nephew-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This “I’M A PC” shirt is also bought from &lt;a href=&quot;https://shop.ecompanystore.com/MSEPPStore/login.aspx&quot;&gt;Microsoft Company Store&lt;/a&gt; in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;Seattle&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>C# Coding Guidelines (4) Types</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-4-types/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-4-types/</guid><description>C# Coding Guidelines:</description><pubDate>Thu, 08 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-1-fundamentals&quot;&gt;C# Coding Guidelines (1) Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (4) Types&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-5-exceptions&quot;&gt;C# Coding Guidelines (5) Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this part, type-related topics will be discussed, including design, usage, etc.&lt;/p&gt;
&lt;h2&gt;Value types vs. reference types&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider designing a value type when&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the type acts like a primitive type;&lt;/li&gt;
&lt;li&gt;the type doesn&apos;t need to inherit from any other type;&lt;/li&gt;
&lt;li&gt;the type will not have any other types derived from it;&lt;/li&gt;
&lt;li&gt;instances of the type are not frequently passed as method arguments since this would cause frequent memory copy operations, hurting performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Actually, if there is no explicit need to design a struct, design a class by default.&lt;/p&gt;
&lt;p&gt;In FCL, there are very few structs. System.Collections.Generic.KeyValuePair&amp;lt;TKey, TValue&amp;gt; is an example.&lt;/p&gt;
&lt;h2&gt;Atomicity&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Prefer designing atomic types.&lt;/p&gt;
&lt;p&gt;Design atomic types if possible, which makes code simple and brings fewer bugs.&lt;/p&gt;
&lt;p&gt;This sample is from a legacy book “&lt;a href=&quot;http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660&quot;&gt;Effective C#&lt;/a&gt;”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Address
{
    public string City { get; set; }

    public int ZipCode { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Think about the above type. The first problem is, validation code is needed in each property setter. For example, zip code should not be negative.&lt;/p&gt;
&lt;p&gt;The second problems is, the client code could be like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Address address = new Address();
address.City = &quot;Bellevue&quot;;
address.ZipCode = 98007;

// ...

address.City = &quot;Redmond&quot;;
address.ZipCode = 98053;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are some invalid temporary status existing for the address object.&lt;/p&gt;
&lt;p&gt;Another problem is, this design is obviously not thread-safe. If there are 10 threads reading a address instance, and 5 threads writing the address, it becomes complex.&lt;/p&gt;
&lt;p&gt;This design is much better:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Address
{
    public Address(string city, int zipCode)
    {
        // Check arguments and validate.
        this.City = city;
        this.ZipCode = zipCode;
    }

    public string City { get; private set; }

    public int ZipCode { get; private set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The values can only be injected from the constructor, so the validation is centralized. Once the instance is constructed, its value cannot be changed. As a immutable or invariant type, it cannot have a invalid status, and it is also threading safe.&lt;/p&gt;
&lt;h2&gt;Type inferring&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use var for variables that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you do not know its type, and&lt;/li&gt;
&lt;li&gt;you do not need to know its type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Actually var is mostly used because of anonymous type. Here is a sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = source.Where(item =&amp;gt; item.Value &amp;gt; 20).Select(item =&amp;gt; new
{
    Id = employee.Id,
    OrderCount = employee.Orders.Count()
});

foreach (var result in results)
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Select() query method returns a generic IEnumerable of some anonymous type generated by compiler.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use var keyword in the other scenarios. In another way it means: do not use var if possible.&lt;/p&gt;
&lt;p&gt;For example, these code are from a project:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var a = dictionary[key];
// ...
// ...
var b = GetSomething(a);
// ...
// ...
var c = b.Data;
// ...
// ...
var d = Process(c, x, y, z);
// ...
// ...
foreach (var e in d.Items) 
{
    // What the heck is e?
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Continuously using var will make the code harder to read.&lt;/p&gt;
&lt;h2&gt;Dynamic types&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Static typing where possible, dynamic typing when needed.&lt;/p&gt;
&lt;p&gt;This is copied from the title of a paper, &lt;a href=&quot;http://research.microsoft.com/~emeijer/papers/rdl04meijer.pdf&quot;&gt;Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;Anders Hejlsberg&lt;/a&gt; said, When C# code is “talking to anything that isn’t statically typed to be a .NET class”, dynamic is a great solution. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Type type = Type.GetTypeFromProgID(&quot;SAPI.SpVoice&quot;);
dynamic optimusPrime = Activator.CreateInstance(type);
optimusPrime.Speak(&quot;Autobots, transform, and roll out!&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dynamic type saves a lot of time in interoperation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not abuse dynamic when static typing is possible.&lt;/p&gt;
&lt;p&gt;This rule need to be emphasized a lot. Otherwise these are going to happen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;performance hit;&lt;/li&gt;
&lt;li&gt;no intellisense in IDE;&lt;/li&gt;
&lt;li&gt;a lot of errors cannot be checked at compile time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take the above Address class as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dynamic address = new Address(&quot;Bellevue&quot;, 98007);
Console.WriteLine(address.City);
Console.WriteLine(address.State); // RuntimeBinderException
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These code will be Ok to compile, but throw a RuntimeBinderException at runtime.&lt;/p&gt;
&lt;p&gt;Here is another sample of abusage of dynamic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Program
{
    private static void Main()
    {
        dynamic number = 1;
        number += 1;
        string message = string.Format(CultureInfo.InvariantCulture, &quot;The value of number is &apos;{0}&apos;.&quot;, number);
        Console.WriteLine(message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These code will be compiled into:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Program
{
    [CompilerGenerated]
    private static class SiteContainer0
    {
        // Represents object = Add(object, 1).
        public static CallSite&amp;lt;Func&amp;lt;CallSite, object, int, object&amp;gt;&amp;gt; Add;

        // Represents object = string.Format(CultureInfo, string, object).
        public static CallSite&amp;lt;Func&amp;lt;CallSite, Type, CultureInfo, string, object, object&amp;gt;&amp;gt; Format;

        // Represents string = object.ToString().
        public static CallSite&amp;lt;Func&amp;lt;CallSite, object, string&amp;gt;&amp;gt; ToString;
    }

    private static void Main()
    {
        object number = 1;

        // Caches object = Add(object, 1).
        if (SiteContainer0.Add == null)
        {
            SiteContainer0.Add = CallSite&amp;lt;Func&amp;lt;CallSite, object, int, object&amp;gt;&amp;gt;.Create(
                Binder.BinaryOperation(
                    CSharpBinderFlags.None,
                    ExpressionType.TypeIs | ExpressionType.Lambda,
                    new CSharpArgumentInfo[] 
                { 
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), 
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, 
                        null) 
                }));
        }

        // Executes object = Add(object, 1).
        number = SiteContainer0.Add.Target.Invoke(SiteContainer0.Add, number, 1);

        // Caches object = string.Format(CultureInfo, string, object).
        if (SiteContainer0.Format == null)
        {
            SiteContainer0.Format = CallSite&amp;lt;Func&amp;lt;CallSite, Type, CultureInfo, string, object, object&amp;gt;&amp;gt;.Create(
                Binder.InvokeMember(
                    CSharpBinderFlags.None,
                    &quot;Format&quot;,
                    null,
                    typeof(Program),
                    new CSharpArgumentInfo[] 
                { 
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, 
                        null), 
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.UseCompileTimeType, 
                        null), 
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, 
                        null), 
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) 
                }));
        }

        // Executes object = string.Format(CultureInfo, string, object).
        object messageValue = SiteContainer0.Format.Target.Invoke(
            SiteContainer0.Format, 
            typeof(string), 
            CultureInfo.InvariantCulture, 
            &quot;The value of number is &apos;{0}&apos;.&quot;, 
            number);

        // Caches string = object.ToString().
        if (SiteContainer0.ToString == null)
        {
            SiteContainer0.ToString = CallSite&amp;lt;Func&amp;lt;CallSite, object, string&amp;gt;&amp;gt;.Create(
                Binder.Convert(
                    CSharpBinderFlags.None,
                    typeof(string)));
        }

        // Executes string = object.ToString().
        string message = SiteContainer0.ToString.Target.Invoke(SiteContainer0.ToString, messageValue);

        Console.WriteLine(message);
    }        
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is obviously much better to write code with static typing, replacing dynamic with int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Program
{
    private static void Main()
    {
        int number = 1;
        number += 1;
        string message = string.Format(CultureInfo.InvariantCulture, &quot;The value of number is &apos;{0}&apos;.&quot;, number);
        Console.WriteLine(message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>C# Coding Guidelines (3) Members</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-3-members/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-3-members/</guid><description>C# Coding Guidelines:</description><pubDate>Wed, 07 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/06/csharp-coding-guidelines-1-fundamental.html&quot;&gt;C# Coding Guidelines (1) Fundamental&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/07/csharp-coding-guidelines-2-naming.html&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (3) Member&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/08/csharp-coding-guidelines-4-type.html&quot;&gt;C# Coding Guidelines (4) Type&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/11/csharp-coding-guidelines-5-exception.html&quot;&gt;C# Coding Guidelines (5) Exception&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/13/csharp-coding-guidelines-6-documentation.html&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/13/csharp-coding-guidelines-7-tools.html&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Constructors&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider designing lightweight constructors doing minimal work, like initializing the fields with the parameters.&lt;/p&gt;
&lt;p&gt;When we call a constructor, an instance is expected to return immediately. These constructors are heavy and could be slow:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Category
{
    internal Category(int id)
    {
        this.Items = QueryFromDatabase(item =&amp;gt; item.CategoryId == id);
    }
}

internal class Taxonomy
{
    internal Taxonomy(Uri uri)
    {
        this.Value = DownloadFromInternet(uri);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the database or network is busy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Category category = new Category(id);
Taxonomy taxonomy = new Taxonomy(uri);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above thread it would take 5 minutes to create a new instance of the class, which will be surprising. So it is recommended to deign the constructors like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Category
{
    internal Category(int id)
    {
        this.Id = id;
    }
}

internal class Taxonomy
{
    internal Taxonomy(Uri uri)
    {
        this.Uri = uri;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the data will be retrieved later when the data is needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider using constructor to manage dependencies.&lt;/p&gt;
&lt;p&gt;This following sample is based on &lt;a href=&quot;http://stephenwalther.com/&quot;&gt;Stephen Walther&lt;/a&gt;’s &lt;a href=&quot;http://stephenwalther.com/blog/archive/2009/02/27/chapter-5-understanding-models.aspx&quot;&gt;code&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductController : Controller
{
    public ActionResult Index()
    {
        return this.View(repository.List&amp;lt;Product&amp;gt;().ToList());
    }

    public ActionResult Create(Product productToCreate)
    {
        try
        {
            repository.Create&amp;lt;Product&amp;gt;(productToCreate);
        }
        catch (InvalidOperationException)
        {
            return this.View();
        }

        return this.RedirectToAction(&quot;Index&quot;);
    }    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you see, to implement the functionalities, ProductController class (higher layer code) need to call IRepository interface (lower layer code). So there is a dependency between ProductController class and IRepository interface. We can inject IRepository into ProductController via ProductController’s constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductController : Controller
{
    private IRepository _repository;

    public ProductController(IRepository repository)
    {
        this._repository = repository;
    }

    public ActionResult Index()
    {
        return this.View(this._repository.List&amp;lt;Product&amp;gt;().ToList());
    }

    public ActionResult Create(Product productToCreate)
    {
        try
        {
            this._repository.Create&amp;lt;Product&amp;gt;(productToCreate);
        }
        catch (InvalidOperationException)
        {
            return this.View();
        }

        return this.RedirectToAction(&quot;Index&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For more information of dependency injection pattern, please read &lt;a href=&quot;http://martinfowler.com/&quot;&gt;Martin Fowler&lt;/a&gt;’s &lt;a href=&quot;http://martinfowler.com/articles/injection.html&quot;&gt;article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Avoid calling virtual members in constructor.&lt;/p&gt;
&lt;p&gt;In this base class, virtual method is called:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Base
{
    protected bool _field;

    public Base()
    {
        this.Method();
    }

    public virtual void Method()
    {
        Console.WriteLine(&quot;Method is called.&quot;);
    }
}

public class Derived : Base
{
    public Derived()
    {
        this._field = true;
    }

    public override void Method()
    {
        Console.WriteLine(&quot;_field is {0}.&quot;, this._field);
    }
}

internal class Program
{
    private static void Main()
    {
        Derived derived = new Derived();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when we invoke the derived class constructor, its method will be executed before the constructor being executed. This is a unexpected behavior for the designer of the derived class.&lt;/p&gt;
&lt;h2&gt;Instance Members vs. static Members&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consistently use “this.” prefix before to call to instance members.&lt;/p&gt;
&lt;p&gt;This is too simple but strongly suggested because it is very helpful to distinguish the invocation of instance members and static members.&lt;/p&gt;
&lt;p&gt;A common question is, if “this.” is always added before instance members, it is harder to refactor instance member into static member. The answer is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is a design issue which should not happen by default;&lt;/li&gt;
&lt;li&gt;Even it happened, refactor tools can be used to easily deal with that.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Actually, this is also the requirement of Rule SA1101 of StyleCop.&lt;/p&gt;
&lt;h2&gt;Properties&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Design a property if it&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;behaves like a field, or is a logical attribute of the type;&lt;/li&gt;
&lt;li&gt;is unlikely to throw exceptions (If the setter throws an exception, keep the original value.);&lt;/li&gt;
&lt;li&gt;does not have dependencies on each other;&lt;/li&gt;
&lt;li&gt;is settable in any order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once in a project, there is a static utility class the intermediate layer, its static properties had to be used in a special order. I suggest the developers to correct this design but they did not. After sometime, more properties were added due to the requirement change, then those properties became a nightmare for the developers to work with.&lt;/p&gt;
&lt;h2&gt;Methods&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Design a method if&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the operation is a conversion, such as ToString();&lt;/li&gt;
&lt;li&gt;the getter has an observable side effect;&lt;/li&gt;
&lt;li&gt;the order of executions is important;&lt;/li&gt;
&lt;li&gt;the method might not return immediately;&lt;/li&gt;
&lt;li&gt;the member returns a collection.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use property if a different value is returned for each invocation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.DateTime.Now&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Obviously the value of Now is not persisted at all. System.Guid.NewGuid() is a correct sample.&lt;/p&gt;
&lt;p&gt;Sometimes, designing a GetXxx() method results a warning in Code Analysis: “CA1024: Microsoft.Design: Change &apos;YourType.GetXxx()&apos; to a property if appropriate.” If the design is appropriate, just suppress this warning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; For methods returning a collection, when the result collection is empty, do not return null. Return an empty collection instead.&lt;/p&gt;
&lt;h2&gt;Extension Methods&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Consider using extension methods to manage dependencies.&lt;/p&gt;
&lt;p&gt;This sample is from &lt;a href=&quot;http://channel9.msdn.com/pdc2008/PC58/&quot;&gt;this talk&lt;/a&gt;. Consider we might need a String.ToUri() method to convert a string to a URI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Uri uri = &quot;http://www.CoolWebOS.com&quot;.ToUri();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is hard to define a ToUri() method in the String type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public class String
    {
        public Uri ToUri()
        {
            return new Uri(this);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;String type is defined in mscorlib.dll assembly, and Uri type is defined in System.dll assembly. The dependency is from System.dll to mscorlib.dll. It is improper to use the Uri type inside the String type.&lt;/p&gt;
&lt;p&gt;The solution is extension method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Net
{
    public static class StringExtensions
    {
        public static Uri ToUri(this string uriString)
        {
            return new Uri(uriString);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And of course it should be defined in the higher-level code, not in the mscorlib.dll.&lt;/p&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (7) Microsoft Picnic</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Wed, 07 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Microsoft picnic 2008 was a great event happened in the summer for the Seattle area employees. It is organized by a professional company picnic company in a very green and beautiful place. Each employee could invite one adult guest and take the employee’s own children there.&lt;/p&gt;
&lt;h2&gt;Place&lt;/h2&gt;
&lt;p&gt;At the gate of the picnic place, there was a map, identifying so many activities and food service:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301913_thumb_3BB208EB.jpg&quot; alt=&quot;S7301913_thumb&quot; title=&quot;S7301913_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There were so many people in this geek party:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301921_thumb_2C8B0444.jpg&quot; alt=&quot;S7301921_thumb&quot; title=&quot;S7301921_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301922_thumb_675EBEE8.jpg&quot; alt=&quot;S7301922_thumb&quot; title=&quot;S7301922_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301952_thumb_7A231CC5.jpg&quot; alt=&quot;S7301952_thumb&quot; title=&quot;S7301952_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yeah this is me:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301953_thumb_4C157E73.jpg&quot; alt=&quot;S7301953_thumb&quot; title=&quot;S7301953_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Food and drink&lt;/h2&gt;
&lt;p&gt;Here ware the endless food service windows, each window provided a different kinds of food. All of the food was free:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301966_thumb_2F8866C6.jpg&quot; alt=&quot;S7301966_thumb&quot; title=&quot;S7301966_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;These were satisfying we Chinese geeks:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301920_thumb_7CA83A84.jpg&quot; alt=&quot;S7301920_thumb&quot; title=&quot;S7301920_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Of course all the drink was free:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301919_thumb_3F93E325.jpg&quot; alt=&quot;S7301919_thumb&quot; title=&quot;S7301919_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;These were very delicious, and free to take:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301963_thumb_25435434.jpg&quot; alt=&quot;S7301963_thumb&quot; title=&quot;S7301963_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Shopping&lt;/h2&gt;
&lt;p&gt;We had &lt;a href=&quot;https://shop.ecompanystore.com/MSEPPStore/login.aspx&quot;&gt;Microsoft Company Store&lt;/a&gt; there:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301918_thumb_0C375E22.jpg&quot; alt=&quot;S7301918_thumb&quot; title=&quot;S7301918_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Things were very cheap. I bought some cloths.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301931_thumb_6E65AD95.jpg&quot; alt=&quot;S7301931_thumb&quot; title=&quot;S7301931_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Playing&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301914_thumb_1F088F74.jpg&quot; alt=&quot;S7301914_thumb&quot; title=&quot;S7301914_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301967_thumb_1B2A9F0A.jpg&quot; alt=&quot;S7301967_thumb&quot; title=&quot;S7301967_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301941_thumb_41102993.jpg&quot; alt=&quot;S7301941_thumb&quot; title=&quot;S7301941_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301948_thumb_4746DA54.jpg&quot; alt=&quot;S7301948_thumb&quot; title=&quot;S7301948_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We had places for children:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301958_thumb_43B592EC.jpg&quot; alt=&quot;S7301958_thumb&quot; title=&quot;S7301958_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301959_thumb_315CA65D.jpg&quot; alt=&quot;S7301959_thumb&quot; title=&quot;S7301959_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As well as casino:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301935_thumb_7684D7B9.jpg&quot; alt=&quot;S7301935_thumb&quot; title=&quot;S7301935_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There were even fortune-tellers, they all looked like Chinese…&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301978_thumb_2D025D31.jpg&quot; alt=&quot;S7301978_thumb&quot; title=&quot;S7301978_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Their ping-pong skill was just so so in my opinion:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301960_thumb_2B8E1492.jpg&quot; alt=&quot;S7301960_thumb&quot; title=&quot;S7301960_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Performances&lt;/h2&gt;
&lt;p&gt;This band was rocking:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301962_thumb_33656B5A.jpg&quot; alt=&quot;S7301962_thumb&quot; title=&quot;S7301962_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The most exciting is the motor show:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301997_thumb_7D041D7D.jpg&quot; alt=&quot;S7301997_thumb&quot; title=&quot;S7301997_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7302028_thumb_2A751774.jpg&quot; alt=&quot;S7302028_thumb&quot; title=&quot;S7302028_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7302031_thumb_4A7FFE64.jpg&quot; alt=&quot;S7302031_thumb&quot; title=&quot;S7302031_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;p&gt;It was very lucky to participate the picnic in 2008. because &lt;a href=&quot;http://news.cnet.com/8301-13860_3-10227175-56.html&quot;&gt;this picnic is cancelled in 2009&lt;/a&gt;, after all this become a real memory…&lt;/p&gt;
</content:encoded></item><item><title>C# Coding Guidelines (1) Fundamentals</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-1-fundamentals/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-1-fundamentals/</guid><description>Recently some talks on dos and don&apos;ts of C# 2.0 / 3.0 / 4.0 are delivered for some junior developers in my friend’s team. Since the feedback looks good, those contents are decided to write down.</description><pubDate>Tue, 06 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently some talks on dos and don&apos;ts of C# 2.0 / 3.0 / 4.0 are delivered for some junior developers in my friend’s team. Since the feedback looks good, those contents are decided to write down.&lt;/p&gt;
&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C# Coding Guidelines (1) Fundamentals&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-2-naming&quot;&gt;C# Coding Guidelines (2) Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;C# Coding Guidelines (4) Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-5-exceptions&quot;&gt;C# Coding Guidelines (5) Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This part is used to mention some general concepts.&lt;/p&gt;
&lt;h2&gt;Framework Design Guidelines&lt;/h2&gt;
&lt;p&gt;The first thing is, one important way to learn professional C# coding is to read the book “&lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/ref=dp_ob_title_bk&quot;&gt;Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries&lt;/a&gt;” (2nd Edition).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/frameworkdesignguidelines_17CB25D7.png&quot; alt=&quot;frame-work-design-guidelines&quot; title=&quot;frame-work-design-guidelines&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This book is from the 10 years’ professional coding and design experience of Microsoft. It is the winner of the 16th Jolt Productivity award in 2006. Just like &lt;a href=&quot;http://www.wintellect.com/cs/blogs/jeffreyr/default.aspx&quot;&gt;Jeffrey Richter&lt;/a&gt; said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This book is an absolute must read for all .NET developers. It gives clear ‘do’ and ‘don’t’ guidance on how to design class libraries for .NET. It also offers insight into the design and creation of .NET that really helps developers understand the reasons why things are the way they are. This information will aid developers designing their own class libraries and will also allow them to take advantage of the .NET class library more effectively.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Consistency&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;Anders Hejlsberg&lt;/a&gt;, chief designer of C# programming language, said that,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have always felt that a key characteristic of a framework must be consistency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is also mentioned in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Usability#Lund.2C_1997_Usability_Maxims&quot;&gt;Usability Maxims&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consistency, consistency, consistency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Consistency need to be enforced as a rule with high priority. Externally consistency makes the design easier to use, and internally consistency makes the code easier to maintain.&lt;/p&gt;
&lt;h2&gt;Usability&lt;/h2&gt;
&lt;p&gt;This word is borrowed from the user experience design. Referring to “&lt;a href=&quot;http://www.useit.com/jakob/&quot;&gt;the king of usability&lt;/a&gt;” &lt;a href=&quot;http://en.wikipedia.org/wiki/Jakob_Nielsen_(usability_consultant)&quot;&gt;Jakob Nielsen&lt;/a&gt;’s explanation, &lt;a href=&quot;http://en.wikipedia.org/wiki/Usability&quot;&gt;usability&lt;/a&gt; is a part of usefulness:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learnability: How easy is it for developers to accomplish basic tasks (like invoking the API) the first time they encounter the design?&lt;/li&gt;
&lt;li&gt;Efficiency: Once developers have learned the design, how quickly can they perform tasks?&lt;/li&gt;
&lt;li&gt;Memorability: When developers return to the design after a period of not using it, how easily can they re establish proficiency?&lt;/li&gt;
&lt;li&gt;Errors: How many errors do developers make, how severe are these errors, and how easily can they recover from the errors?&lt;/li&gt;
&lt;li&gt;Satisfaction: How pleasant is it to use the design?&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>C# Coding Guidelines (2) Naming</title><link>https://dixin.github.io/posts/csharp-coding-guidelines-2-naming/</link><guid isPermaLink="true">https://dixin.github.io/posts/csharp-coding-guidelines-2-naming/</guid><description>C# Coding Guidelines:</description><pubDate>Tue, 06 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C# Coding Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-1-fundamentals&quot;&gt;C# Coding Guidelines (1) Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C# Coding Guidelines (2) Naming&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-3-members&quot;&gt;C# Coding Guidelines (3) Members&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-4-types&quot;&gt;C# Coding Guidelines (4) Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-5-exceptions&quot;&gt;C# Coding Guidelines (5) Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-6-documentation&quot;&gt;C# Coding Guidelines (6) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/csharp-coding-guidelines-7-tools&quot;&gt;C# Coding Guidelines (7) Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post topics like “whether we should use Chinese in the identifiers or not” will not discussed.&lt;/p&gt;
&lt;h2&gt;Casing Conventions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use PascalCasing for namespace, type, and member names, except fields.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Id&lt;/li&gt;
&lt;li&gt;Ok&lt;/li&gt;
&lt;li&gt;UIOption&lt;/li&gt;
&lt;li&gt;XmlHelper&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For acronyms with 2 letters, these 2 letters should be upper case; for acronyms with more than 2 letters, the first letter should be upper case.&lt;/p&gt;
&lt;p&gt;Please notice Id is remembered rather than ID, Ok is remembered rather than OK. They are treated as words, not acronyms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use camelCasing for field, local variable and parameter names.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;id&lt;/li&gt;
&lt;li&gt;ok&lt;/li&gt;
&lt;li&gt;uiOption&lt;/li&gt;
&lt;li&gt;xmlHelper&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One common discussion is the prefix of the names.&lt;/p&gt;
&lt;p&gt;The Framework Design Guidelines said:&lt;/p&gt;
&lt;p&gt;Names cannot defer by case only.&lt;/p&gt;
&lt;p&gt;Sometimes we write code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Person
{
    private string name;

    internal Person(string name)
    {
        this.name = name;
    }

    internal string Name
    {
        get
        {
            return name;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually this code is Ok even the name field and Name property defer by case only. Because Framework Design Guidelines is talking about exposed members. The name field is not exposed.&lt;/p&gt;
&lt;p&gt;Personally I like to add an underscore before the fields, and always add “this.” before instance members:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Person
{
    private string _name;

    internal Person(string name)
    {
        this._name = name;
    }

    internal string Name
    {
        get
        {
            return this._name;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So it become very easy to distinguish:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;static field: _staticField&lt;/li&gt;
&lt;li&gt;instance field: this._instanceField&lt;/li&gt;
&lt;li&gt;static property: StaticProperty&lt;/li&gt;
&lt;li&gt;instance property: this.InstanceProperty&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course a lot of developers do not like the prefix. Whatever, the most important is to keep code consistent.&lt;/p&gt;
&lt;h2&gt;Hungary Notation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use &lt;a href=&quot;http://en.wikipedia.org/wiki/Hungarian_notation&quot;&gt;Hungarian notations&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;intCount&lt;/li&gt;
&lt;li&gt;strName&lt;/li&gt;
&lt;li&gt;btnOk&lt;/li&gt;
&lt;li&gt;lblMessage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use postfix when to identify the type / base type.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;okButton&lt;/li&gt;
&lt;li&gt;messageLabel&lt;/li&gt;
&lt;li&gt;System.Exception and System.ArgumentException&lt;/li&gt;
&lt;li&gt;System.IO.Stream and System.IO.FileStream&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abbreviations And Acronyms&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use abbreviations and contractions as part of identifiers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sr (streamReader)&lt;/li&gt;
&lt;li&gt;GetWnd (GetWindow)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use acronym if it is widely accepted, and has only one single meaning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Web.Mvc.HtmlHelper&lt;/li&gt;
&lt;li&gt;Microsoft.VisualBasic.FileIO.UIOption&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A obvious example is HTML: Almost everyone knows HTML, and HTML does not have multiple meanings. And also “HyperTextMarkupLanguageHelper” looks prolix. “HtmlHelper” is choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use acronyms that are not widely accepted.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Drawing.Color.FromArgb()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sample is from the book. Sometimes FromArgb is confusing because Argb looks like argument b. FromAlphaRgb could be better.&lt;/p&gt;
&lt;p&gt;Another sample is “e”. Too many “e”s have been seen. Usually e should be only used for the EventArgs instance name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;protected void Page_Load(object sender, EventArgs e)
{

}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the other scenarios, like exception, error, element, event, … e should not be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{ 
}
catch (InvalidOperationException exception)
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Special Names&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not use language-specific names&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.NullReferenceException&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sample is also from the book. NullReferenceException is not perfect because VB uses Nothing.&lt;/p&gt;
&lt;p&gt;Another sort of language-specific name is the primitive type name.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use FCL type name instead of language-specific primitive type name.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Convert.ToInt32(), not ToInt()&lt;/li&gt;
&lt;li&gt;System.Convert.ToInt64(), not ToLong()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A developer asked where to find a “ToFloat()” method. Actually it is “ToSingle()”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✘&lt;/strong&gt; Do not abuse .NET-specific names.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XxxHandler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“Handler” has specified meaning in .NET programming. When I was in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;Microsoft Redmond&lt;/a&gt;, I was invited to review some code for a friend, which contained tons of “XxxHandler”s. Once something is related to Xxx, it is named “XxxHandler”. This cannot make sense.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Prefer .NET-recommended words.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Id (not ID)&lt;/li&gt;
&lt;li&gt;Ok (not OK)&lt;/li&gt;
&lt;li&gt;Canceled (not Cancelled)&lt;/li&gt;
&lt;li&gt;Indexes (not Indices)&lt;/li&gt;
&lt;li&gt;UserName (not Username)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But FCL itself is not 100% complying this rule, like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Web.Security
{
    public abstract class MembershipProvider : ProviderBase
    {
        public abstract bool DeleteUser(string username, bool deleteAllRelatedData);

        public abstract MembershipUser GetUser(string username, bool userIsOnline);

        public abstract string ResetPassword(string username, string answer);

        public abstract bool UnlockUser(string userName);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“userName” should be used for the parameter name.&lt;/p&gt;
&lt;h2&gt;Symmetry&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Use symmetric words in symmetric identifiers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add / Remove&lt;/li&gt;
&lt;li&gt;Insert / Delete&lt;/li&gt;
&lt;li&gt;Create / Destroy&lt;/li&gt;
&lt;li&gt;Initialize / Finalize&lt;/li&gt;
&lt;li&gt;Get / Set&lt;/li&gt;
&lt;li&gt;LogOn / LogOff&lt;/li&gt;
&lt;li&gt;Begin / End&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Consistency&lt;/h2&gt;
&lt;p&gt;Once I saw the source code of a website, where the verb Insert is used in the data access layer, while Add is used in the data models, while Create is used in the controllers.&lt;/p&gt;
&lt;p&gt;In another website, many verbs for the membership: LogOn, LogOff, LogIn, LogOut, SignIn, SignOff, SignOut … This is unnecessary.&lt;/p&gt;
&lt;p&gt;In a fantastic project, to identify one thing, 5 different names are used in&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;documents,&lt;/li&gt;
&lt;li&gt;database table,&lt;/li&gt;
&lt;li&gt;SQL stored procedure code,&lt;/li&gt;
&lt;li&gt;C# code,&lt;/li&gt;
&lt;li&gt;and UI message.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✔&lt;/strong&gt; Again, Consistency of the naming should always be kept in mind.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (8) Struct And Void</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Sun, 04 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Part 1&lt;/a&gt; mentioned that variances do not work with struct and void.&lt;/p&gt;
&lt;h2&gt;Struct&lt;/h2&gt;
&lt;p&gt;When we say Derived object “is a” Base object, it means the reference to a Derived object can be considered as a reference to a Base object.&lt;/p&gt;
&lt;p&gt;But struct is value type. On the virtual machine described by CLI, when passing a struct value to a method receiving struct parameter, that value is copied and pushed to the stack. When returning a struct value from a method, that item is placed on the stack. We are not working with references.&lt;/p&gt;
&lt;h2&gt;Void&lt;/h2&gt;
&lt;p&gt;The scenario of void looks special. On &lt;a href=&quot;http://connect.microsoft.com/default.aspx&quot;&gt;Microsoft Connect&lt;/a&gt;. Someone is asking for “&lt;a href=&quot;http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=90909&quot;&gt;Covariant return types should include void –&amp;gt; anything&lt;/a&gt;”.&lt;/p&gt;
&lt;p&gt;It looks like anything can be covariant to void:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void VoidOut();

internal delegate object ObjectOut();

internal class Program
{
    private static void Main()
    {
        VoidOut voidOut = () =&amp;gt; { };
        ObjectOut objectOut = () =&amp;gt; new object();

        // It looks like covariance is Ok here.
        voidOut = objectOut;

        // Because when we invoke [void voidOut()], we are invoking [object objectOut()]. 
        // The return value of [object objectOut()] can be just ignored.
        voidOut();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are also some people asking about the parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal delegate void NoParameterIn();

internal delegate void ObjectIn(object @object);

internal class Program
{
    private static void Main()
    {
        NoParameterIn noParameterIn = () =&amp;gt; { };
        ObjectIn objectIn = (@object) =&amp;gt; { };

        // It looks like contravariance is Ok here.
        objectIn = noParameterIn;

        // Because when we invoke [void objectIn(object)], we are invoking [void noParameterIn()].
        // The parameter of [void objectIn(object)] can be just ignored.
        objectIn(new object());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both of the above variance code cannot be compiled in C# 2.0 / 3.0 / 4.0. The reason is, on the virtual machine described by CLI, function with return value and function without return value work differently. If the variant is allowed, according to &lt;a href=&quot;http://blogs.msdn.com/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx&quot;&gt;Eric Lippert&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;we would be allowing you to misalign the IL stack!&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Microsofty Kids Around (1) My Nominal Daughter</title><link>https://dixin.github.io/posts/microsofty-kids-around-1-my-nominal-daughter/</link><guid isPermaLink="true">https://dixin.github.io/posts/microsofty-kids-around-1-my-nominal-daughter/</guid><description>I am very glad to introduce my nominal daughter (or “dry daughter” in Chinese). This is a kind of Chinese culture. Her parents are my very good friends so she could be treated just like my daughter:</description><pubDate>Sat, 03 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am very glad to introduce my nominal daughter (or “dry daughter” in Chinese). This is a kind of Chinese culture. Her parents are my very good friends so she could be treated just like my daughter:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/mynorminaldaughter1_0D144A97.png&quot; alt=&quot;my-norminal-daughter-1&quot; title=&quot;my-norminal-daughter-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;She looks really nice with the shirt bought from &lt;a href=&quot;https://shop.ecompanystore.com/MSEPPStore/login.aspx&quot;&gt;Microsoft Company Store&lt;/a&gt; in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;Seattle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/mynorminaldaughter2_09DF1057.png&quot; alt=&quot;my-norminal-daughter-2&quot; title=&quot;my-norminal-daughter-2&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (6) University of Washington</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-6-university-of-washington/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-6-university-of-washington/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Fri, 25 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/University_of_Washington&quot;&gt;University of Washington&lt;/a&gt;, founded in 1861, is a public research university in &lt;a href=&quot;http://en.wikipedia.org/wiki/Seattle,_Washington&quot;&gt;Seattle&lt;/a&gt;. It is the largest university in the northwestern US and one of the oldest public universities on the west coast.&lt;/p&gt;
&lt;p&gt;In 2008, it is placed 16th in the world&apos;s top universities, according to the so called &lt;a href=&quot;http://www.arwu.org/rank2008/ARWU2008_A(EN).htm&quot;&gt;Academic Ranking of World Universities&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Views&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040229_thumb_241828C2.jpg&quot; alt=&quot;P1040229_thumb&quot; title=&quot;P1040229_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040239_thumb_63D1E97A.jpg&quot; alt=&quot;P1040239_thumb&quot; title=&quot;P1040239_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040248_thumb_06C20F51.jpg&quot; alt=&quot;P1040248_thumb&quot; title=&quot;P1040248_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040254_thumb_346F8C7C.jpg&quot; alt=&quot;P1040254_thumb&quot; title=&quot;P1040254_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040261_thumb_57AB99AD.jpg&quot; alt=&quot;P1040261_thumb&quot; title=&quot;P1040261_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040263_thumb_40E8FFCC.jpg&quot; alt=&quot;P1040263_thumb&quot; title=&quot;P1040263_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040285_thumb_4C026449.jpg&quot; alt=&quot;P1040285_thumb&quot; title=&quot;P1040285_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040293_thumb_027FE9C1.jpg&quot; alt=&quot;P1040293_thumb&quot; title=&quot;P1040293_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040267_thumb_34573EB1.jpg&quot; alt=&quot;P1040267_thumb&quot; title=&quot;P1040267_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040295_thumb_7EEDE0B1.jpg&quot; alt=&quot;P1040295_thumb&quot; title=&quot;P1040295_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Walking in the school, I felt so peaceful and so similar as &lt;a href=&quot;http://en.wikipedia.org/wiki/Nanjing_University&quot;&gt;my university&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Links for more pictures and information&lt;/h2&gt;
&lt;p&gt;For University of Washington:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/University_of_Washington&quot;&gt;University of Washington on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The so called &lt;a href=&quot;http://www.arwu.org/rank2008/ARWU2008_A(EN).htm&quot;&gt;Academic Ranking of World Universities&lt;/a&gt;, and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Academic_Ranking_of_World_Universities&quot;&gt;introduction on Wikipedia&lt;/a&gt;. This is some kind of bullshit I believe.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.washington.edu/&quot;&gt;University of Washington official site&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (2) Working</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-2-working/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-2-working/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (2) Working&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this part, the working environment and style will be introduced. Because I do not prefer to show up my face or the Microsoft office internals here, in this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Most of the photos outside office are shot by me;&lt;/li&gt;
&lt;li&gt;All of the photos inside office are from the Internet.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Microsoft Redmond Campus&lt;/h2&gt;
&lt;p&gt;The north of Bellevue (introduced in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;part 1&lt;/a&gt;) is Redmond. Microsoft Campus is tens of buildings distributed in the trees and flowers. These photos are shot by my &lt;a href=&quot;http://www.nokiausa.com/find-products/phones/nokia-n73&quot;&gt;legacy Nokia N73&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080609079_thumb_2DDDC7F2.jpg&quot; alt=&quot;20080609079_thumb&quot; title=&quot;20080609079_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Actually Redmond is as beautiful as Bellevue. Rabbits and squirrels can be seen frequently:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080724165_thumb_0114C27F.jpg&quot; alt=&quot;20080724165_thumb&quot; title=&quot;20080724165_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My friend &lt;a href=&quot;http://wayneye.cn/&quot;&gt;Wei&lt;/a&gt; tried to give him a cigarette, and I tried to give him a chocolate, but he said he does not like those stuff…&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080724167_thumb_3DC8F8B7.jpg&quot; alt=&quot;20080724167_thumb&quot; title=&quot;20080724167_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And this was shot during the heavy snow in the winter of 2008:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081218258_thumb_6447139D.jpg&quot; alt=&quot;20081218258_thumb&quot; title=&quot;20081218258_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is the mail box outside RedWest E. The car is a Microsoft shuttle, which will be introduced later.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080728169_thumb_497A2BEA.jpg&quot; alt=&quot;20080728169_thumb&quot; title=&quot;20080728169_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Originally I was working in Building 9 at the &lt;a href=&quot;http://www.microsoft.com/presspass/gallery/imageviewer.mspx?webURL=%2fpresspass%2fimages%2fgallery%2fcampus%2fbldg10_flags_web.jpg&amp;amp;printURL=%2fpresspass%2fimages%2fgallery%2fcampus%2fbldg10_flags_print.jpg&amp;amp;caption=Main+entrance+to+the+Microsoft+Redmond+Campus.&amp;amp;JPGSize=&amp;amp;TiffSize=&quot;&gt;main entrance of the campus&lt;/a&gt;, later the team was relocated to Building 34:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081218260_thumb_786C41F4.jpg&quot; alt=&quot;20081218260_thumb&quot; title=&quot;20081218260_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So the exciting thing is, I was working with&lt;/strong&gt; &lt;a href=&quot;http://en.wikipedia.org/wiki/Bill_Gates&quot;&gt;&lt;strong&gt;Bill Gates&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;a href=&quot;http://en.wikipedia.org/wiki/Steve_Ballmer&quot;&gt;&lt;strong&gt;Steve Ballmer&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;in the same building&lt;/strong&gt;:)… I was in the 1st floor, and they were in the 5th floor.&lt;/p&gt;
&lt;p&gt;I shot this in the garage of Building 40 / 41:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080804174_thumb_3E6CD93B.jpg&quot; alt=&quot;20080804174_thumb&quot; title=&quot;20080804174_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Building 40 and 41 are the office of the .NET and Visual Studio division. We have many thunderous people there, like &lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;Anders Hejlsberg&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;This is the photo of &lt;a href=&quot;http://www.microsoft.com/about/companyinformation/visitorcenter/default.aspx&quot;&gt;Microsoft Visitor Center&lt;/a&gt;, &lt;a href=&quot;http://www.microsoft.com/presspass/gallery/imageviewer.mspx?webURL=%2Fpresspass%2Fimages%2Ffeatures%2F2005%2F03-21visitor-center_lg.jpg&amp;amp;printURL=&amp;amp;caption=The+Microsoft+Visitor+Center.&amp;amp;JPGSize=&amp;amp;TiffSize=&quot;&gt;from Microsoft.com&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoftvisitorcenter_thumb_7960DF79.jpg&quot; alt=&quot;microsoft-visitor-center_thumb&quot; title=&quot;microsoft-visitor-center_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In 2008 the Visitor Center was relocated to Building 92, as well as &lt;a href=&quot;https://shop.ecompanystore.com/MSEPPStore/login.aspx&quot;&gt;Microsoft Company Store&lt;/a&gt;. I bought several shirts there, like &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/03/my-microsoft-kid.html&quot;&gt;this one&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Cafeterias&lt;/h2&gt;
&lt;p&gt;Many buildings have cafeterias. They are excellent, and not expensive at all. We have Chinese food in the cafeteria of Building 88, served by a very nice uncle from Shanghai.&lt;/p&gt;
&lt;p&gt;This is the cafeteria of Building 34, where I often had my lunch (The picture is &lt;a href=&quot;http://www.microsoft.com/presspass/images/gallery/campus/building_34_cafeteria_print.jpg&quot;&gt;from Microsoft.com&lt;/a&gt;.):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/building34cafeteria_thumb_16E294AC.jpg&quot; alt=&quot;building-34-cafeteria_thumb&quot; title=&quot;building-34-cafeteria_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And this is the inside view (This picture is &lt;a href=&quot;http://www.pconline.com.cn/pcjob/rs/zc/0508/pic/microsoft31.jpg&quot;&gt;from PCOnline.com.cn&lt;/a&gt;.):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/building34cafeteriainside_thumb_1_77136F49.jpg&quot; alt=&quot;building-34-cafeteria-inside_thumb_1&quot; title=&quot;building-34-cafeteria-inside_thumb_1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Below is the way outside Building 16 (This picture is &lt;a href=&quot;http://www.pconline.com.cn/pcjob/rs/zc/0508/pic/microsoft19.jpg&quot;&gt;from PCOnline.com.cn&lt;/a&gt;.). Since the cafeteria of Building 34 does not provide supper, sometimes when I was too lazy to cook, I walked through this way to go to the cafeteria of Building 16 to have supper:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/building16_thumb_373962F7.jpg&quot; alt=&quot;building-16_thumb&quot; title=&quot;building-16_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On the plates those are the names for each Microsoft product.&lt;/p&gt;
&lt;p&gt;This is the salad in the Building 16 cafeteria, each costs $6.95 max, which is cheap enough. I do not use any salad sauce, because it tasted horrible for me:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301896_thumb_531A7222.jpg&quot; alt=&quot;S7301896_thumb&quot; title=&quot;S7301896_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The drink is a bottle of 100% apple juice. The drink is free. I will talk more about drink later.&lt;/p&gt;
&lt;h2&gt;Office&lt;/h2&gt;
&lt;p&gt;Because publishing pictures of Microsoft office internals might cause trouble, in this section I will mainly use pictures &lt;a href=&quot;http://www.pconline.com.cn/pcjob/rs/zc/0508/680779.html&quot;&gt;from the Internet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoft22_thumb_7144DD7E.jpg&quot; alt=&quot;microsoft22_thumb&quot; title=&quot;microsoft22_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoft26_thumb_57CCB477.jpg&quot; alt=&quot;microsoft26_thumb&quot; title=&quot;microsoft26_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoft28_thumb_6647B09C.jpg&quot; alt=&quot;microsoft28_thumb&quot; title=&quot;microsoft28_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The name of the employee is on the plate of his office. I also have my own office in Building 34, but I am sorry I do not prefer to publish photos of my office.&lt;/p&gt;
&lt;p&gt;Ok, here is the key point, the drink. There is at least one kitchen for each floor of each building:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoft34_thumb_7ABCDA4D.jpg&quot; alt=&quot;microsoft34_thumb&quot; title=&quot;microsoft34_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The free drinks includes kinds of cola, kinds of milk, kinds of 100% fruit juice, etc.&lt;/p&gt;
&lt;p&gt;And we have free Starbucks coffee and hot chocolate:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301880_thumb_2_1AC7C13E.jpg&quot; alt=&quot;S7301880_thumb_2&quot; title=&quot;S7301880_thumb_2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And also other free drinks, like kinds of tea, etc:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301882_thumb_70F4207D.jpg&quot; alt=&quot;S7301882_thumb&quot; title=&quot;S7301882_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yes, it is said that “Your drink, our passion!”. My favorite are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sprite,&lt;/li&gt;
&lt;li&gt;chocolate milk,&lt;/li&gt;
&lt;li&gt;100% apple juice,&lt;/li&gt;
&lt;li&gt;100% orange juice,&lt;/li&gt;
&lt;li&gt;hot chocolate.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the beginning, the most horrible drink for me is &lt;a href=&quot;http://en.wikipedia.org/wiki/V8_(beverage)&quot;&gt;V8&lt;/a&gt;. But later we invented a simple way to change it into delicious: heat via the microwave and add a little sugar.&lt;/p&gt;
&lt;p&gt;We also have a lot of recreation stuff:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoft33_thumb_7CE5EAE4.jpg&quot; alt=&quot;microsoft33_thumb&quot; title=&quot;microsoft33_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And this is &lt;a href=&quot;http://fastdev.spaces.live.com/blog/cns!8A0406089AAD8752!886.entry&quot;&gt;from my friend’s blog&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/streetfight_thumb_67A7BF6F.jpg&quot; alt=&quot;street-fight_thumb&quot; title=&quot;street-fight_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yes, &lt;a href=&quot;http://fastdev.spaces.live.com/&quot;&gt;Mark&lt;/a&gt;, Steven and me we are playing &lt;a href=&quot;http://en.wikipedia.org/wiki/Street_Fighter_II&quot;&gt;Street fighter II&lt;/a&gt; in Building 50. You can see this arcade belongs to the IE team.&lt;/p&gt;
&lt;p&gt;This is fancy:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081224304_thumb_0509EAAF.jpg&quot; alt=&quot;20081224304_thumb&quot; title=&quot;20081224304_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can play with the &lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Surface&quot;&gt;surface multi-touch device&lt;/a&gt; in the &lt;a href=&quot;http://www.microsoft.com/about/companyinformation/visitorcenter/default.aspx&quot;&gt;Microsoft Visitor Center&lt;/a&gt;, also in Building 43, etc.&lt;/p&gt;
&lt;h2&gt;Transportation&lt;/h2&gt;
&lt;p&gt;Since the buildings are distributed in the campus, people like me (do not have a car to drive) could have trouble. But don’t worry, Microsoft provides &lt;a href=&quot;http://www.microsoft.com/environment/our_commitment/articles/alternative_commuting.aspx&quot;&gt;free shuttle service&lt;/a&gt; between buildings and areas. For example, sometimes we call a shuttle to go to Building 88 to have the Chinese food, then call a shuttle back to office.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsftshuttle_thumb_5295F162.jpg&quot; alt=&quot;microsft-shuttle_thumb&quot; title=&quot;microsft-shuttle_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The above picture &lt;a href=&quot;http://www.flickr.com/photos/kylezoa/3656568250/sizes/l/&quot;&gt;is from Flickr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This picture looks like the shuttle connector in &lt;a href=&quot;http://www.soundtransit.org/Projects-and-Plans/Project-List/Overlake-Transit-Center.xml&quot;&gt;Overlake Transit Center&lt;/a&gt;, also &lt;a href=&quot;http://www.flickr.com/photos/thewhir/2422064673/sizes/l/&quot;&gt;from Flickr&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/microsoftshuttleconnector_thumb_6F3F40AA.jpg&quot; alt=&quot;microsoft-shuttle-connector_thumb&quot; title=&quot;microsoft-shuttle-connector_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Every morning I took a 245 from apartment (in Bellevue, introduced in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;part 1&lt;/a&gt;) to office (in Redmond). This one is shot by my Nokia N73:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614099_thumb_77634074.jpg&quot; alt=&quot;20080614099_thumb&quot; title=&quot;20080614099_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Links for more pictures and information&lt;/h2&gt;
&lt;p&gt;For more pictures of Microsoft Redmond Campus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/Presspass/gallery/campus.mspx&quot;&gt;Microsoft.com Image Gallery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.pconline.com.cn/pcjob/rs/zc/0508/680779.html&quot;&gt;Introduction from PCOnline.com.cn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tech.sina.com.cn/pc/2004-06-07/95/464.html&quot;&gt;Introduction from Sina.com.cn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (3) Living</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-3-living/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-3-living/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (3) Living&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Homestead: The Hotel&lt;/h2&gt;
&lt;p&gt;When first arriving in the US, I lived in this hotel &lt;a href=&quot;http://www.homesteadhotels.com/hotels/seattle-bellevue.html&quot;&gt;Homestead in Bellevue&lt;/a&gt; for several days:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7300961_thumb_5F182AD4.jpg&quot; alt=&quot;S7300961_thumb&quot; title=&quot;S7300961_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It is very close to Building 27 of Microsoft.&lt;/p&gt;
&lt;p&gt;These two pictures are &lt;a href=&quot;http://www.undercovertourist.com/united-states/washington/seattle/hotels/homestead-seattle-redmond.html&quot;&gt;from the Internet&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/homesteadseattleredmond_0_thumb_64A2D313.jpg&quot; alt=&quot;homestead-seattle-redmond_0_thumb&quot; title=&quot;homestead-seattle-redmond_0_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/homesteadseattleredmond_1_thumb_61413B6B.jpg&quot; alt=&quot;homestead-seattle-redmond_1_thumb&quot; title=&quot;homestead-seattle-redmond_1_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I remember it took me a very long time to check in.&lt;/p&gt;
&lt;h2&gt;Central Park East: The apartment&lt;/h2&gt;
&lt;p&gt;After days I moved to &lt;a href=&quot;http://www.centralparkeastapartments.net/&quot;&gt;Central Park East&lt;/a&gt;, where I had a &lt;a href=&quot;http://www.centralparkeastapartments.net/TourApartments.aspx&quot;&gt;living of peace and relaxation&lt;/a&gt; for over half a year. It was comfortable, and there are swimming pool and gym. Again, the following are shot by my &lt;a href=&quot;http://www.nokiausa.com/find-products/phones/nokia-n73&quot;&gt;legacy Nokia N73&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614094_thumb_572C9A40.jpg&quot; alt=&quot;20080614094_thumb&quot; title=&quot;20080614094_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614092_thumb_4644A3F8.jpg&quot; alt=&quot;20080614092_thumb&quot; title=&quot;20080614092_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614093_thumb_0E41EE6E.jpg&quot; alt=&quot;20080614093_thumb&quot; title=&quot;20080614093_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081019243_thumb_1_533A700A.jpg&quot; alt=&quot;20081019243_thumb_1&quot; title=&quot;20081019243_thumb_1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;These are the heavy snow in the winter of 2008:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081222262_thumb_01EBEEE1.jpg&quot; alt=&quot;20081222262_thumb&quot; title=&quot;20081222262_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081222263_thumb_7A8CDCDB.jpg&quot; alt=&quot;20081222263_thumb&quot; title=&quot;20081222263_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This was outside my window:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20081221261_thumb_7C1D5D15.jpg&quot; alt=&quot;20081221261_thumb&quot; title=&quot;20081221261_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Inside my apartment, these are shot by my roommate Steven:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7302163_thumb_156514B6.jpg&quot; alt=&quot;S7302163_thumb&quot; title=&quot;S7302163_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7302173_thumb_1C07F86C.jpg&quot; alt=&quot;S7302173_thumb&quot; title=&quot;S7302173_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7302172_thumb_3891BDC1.jpg&quot; alt=&quot;S7302172_thumb&quot; title=&quot;S7302172_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is my desktop:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301238_thumb_09DB6945.jpg&quot; alt=&quot;S7301238_thumb&quot; title=&quot;S7301238_thumb&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (4) Food</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-4-food/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-4-food/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (4) Food&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are many choices for food in Seattle.&lt;/p&gt;
&lt;h2&gt;Sichuanese food&lt;/h2&gt;
&lt;p&gt;Around the apartment (introduced in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;part 3&lt;/a&gt;), there are at least 3 Sichuanese restaurants.&lt;/p&gt;
&lt;p&gt;Mark and Wei took me an Steven to this place, where I had my first dinner in the US. Later this place became our favorite restaurant:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614105_thumb_01A5CFAE.jpg&quot; alt=&quot;20080614105_thumb&quot; title=&quot;20080614105_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080625118_thumb_6C27CEAB.jpg&quot; alt=&quot;20080625118_thumb&quot; title=&quot;20080625118_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;How beautiful it was! I felt I was back in my hometown…&lt;/p&gt;
&lt;p&gt;And sometimes we also went here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080812175_thumb_54BC7EA0.jpg&quot; alt=&quot;20080812175_thumb&quot; title=&quot;20080812175_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080707145_thumb_547CA913.jpg&quot; alt=&quot;20080707145_thumb&quot; title=&quot;20080707145_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Cooking&lt;/h2&gt;
&lt;p&gt;Sometimes we also cook some Chinese food by ourselves. This was in my friend Yiming’s apartment:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301869_thumb_1_45E16154.jpg&quot; alt=&quot;S7301869_thumb_1&quot; title=&quot;S7301869_thumb_1&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Other choices&lt;/h2&gt;
&lt;p&gt;There is a McDonald near my apartment:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7300965_thumb_46E624A6.jpg&quot; alt=&quot;S7300965_thumb&quot; title=&quot;S7300965_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The hamburgers are much cheaper than in China. For example, a MacChicken costs $1.09 with tax.&lt;/p&gt;
&lt;p&gt;There is also Mexican restaurant. Its wrapper is nice:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080702141_thumb_6A427D71.jpg&quot; alt=&quot;20080702141_thumb&quot; title=&quot;20080702141_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There are many shops around the apartment. This was shot in &lt;a href=&quot;http://www.fredmeyer.com/&quot;&gt;Fred Mayer&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080621117_thumb_4002A9BC.jpg&quot; alt=&quot;20080621117_thumb&quot; title=&quot;20080621117_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;$3.99 for 24 bottles of water.&lt;/p&gt;
&lt;p&gt;And we can also buy Chinese food for the shop:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301901_thumb_724631A1.jpg&quot; alt=&quot;S7301901_thumb&quot; title=&quot;S7301901_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This was in my apartment (introduced in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;part 3&lt;/a&gt;), you can also see my N73 there:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301112_thumb_7D12ED1C.jpg&quot; alt=&quot;S7301112_thumb&quot; title=&quot;S7301112_thumb&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (5) Playing around</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-5-playing-around/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-5-playing-around/</guid><description>The Memory of Programming in Seattle:</description><pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Memory of Programming in Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;The Memory of Programming in Seattle (1) Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Memory of Programming in Seattle (5) Playing around&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are many many places to go around Seattle.&lt;/p&gt;
&lt;h2&gt;Green Lake&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Green_Lake_(Seattle)&quot;&gt;Green Lake&lt;/a&gt; is a freshwater lake in north central &lt;a href=&quot;http://en.wikipedia.org/wiki/Seattle,_Washington&quot;&gt;Seattle&lt;/a&gt;. It is a beacon for wildlife. Many types of wildlife, &lt;a href=&quot;http://en.wikipedia.org/wiki/Duck&quot;&gt;ducks&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Cormorant&quot;&gt;cormorants&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Loon&quot;&gt;loons&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Heron&quot;&gt;herons&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Goose&quot;&gt;geese&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Turtle&quot;&gt;turtles&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Raccoon&quot;&gt;raccoons&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Rat&quot;&gt;rats&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Squirrel&quot;&gt;squirrels&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Bat&quot;&gt;bats&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Hawk&quot;&gt;hawks&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Eagle&quot;&gt;eagles&lt;/a&gt;, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Osprey&quot;&gt;osprey&lt;/a&gt; are among the wild creatures commonly viewed there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040056_thumb_7E005EC2.jpg&quot; alt=&quot;P1040056_thumb&quot; title=&quot;P1040056_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301279_thumb_2AD16205.jpg&quot; alt=&quot;S7301279_thumb&quot; title=&quot;S7301279_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This picture is &lt;a href=&quot;http://en.wikipedia.org/wiki/Green_Lake_(Seattle)&quot;&gt;from Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/WoodlandPark1_thumb_34C5B796.jpg&quot; alt=&quot;WoodlandPark-1_thumb&quot; title=&quot;WoodlandPark-1_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Lake Washington&lt;/h2&gt;
&lt;p&gt;Lake Washington is introduced in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;part 1&lt;/a&gt;. Below are the photo of barbecue beside the lake.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301523_thumb_6EA4D4B5.jpg&quot; alt=&quot;S7301523_thumb&quot; title=&quot;S7301523_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;They were very hungry:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301543_thumb_7D7BDE02.jpg&quot; alt=&quot;S7301543_thumb&quot; title=&quot;S7301543_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301552_thumb_0848997E.jpg&quot; alt=&quot;S7301552_thumb&quot; title=&quot;S7301552_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A doggy in a boat on the lake:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040139_thumb_3D155321.jpg&quot; alt=&quot;P1040139_thumb&quot; title=&quot;P1040139_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Mount Rainier&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Mount_Rainier&quot;&gt;Mount Rainier&lt;/a&gt; is a very famous snow mountain. I first knew it in 2004, from the movie “&lt;a href=&quot;http://www.imdb.com/title/tt0370263/&quot;&gt;Alien vs. Predator&lt;/a&gt;”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/alienvspredator_thumb_515ACD12.jpg&quot; alt=&quot;alien-vs-predator_thumb&quot; title=&quot;alien-vs-predator_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/alienvspredatorsnapshot_thumb_01FDAEF1.jpg&quot; alt=&quot;alien-vs-predator-snapshot_thumb&quot; title=&quot;alien-vs-predator-snapshot_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Mount Rainier is an active volcano in &lt;a href=&quot;http://en.wikipedia.org/wiki/Pierce_County,_Washington&quot;&gt;Pierce County&lt;/a&gt;, located 54 miles (87 km) southeast of &lt;a href=&quot;http://en.wikipedia.org/wiki/Seattle,_Washington&quot;&gt;Seattle&lt;/a&gt;. Driving from Bellevue to the mountain costs at least 4 hours. The mountain is very beautiful, surrounded and protected within &lt;a href=&quot;http://en.wikipedia.org/wiki/Mount_Rainier_National_Park&quot;&gt;Mount Rainier National Park&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/IMG_6668_thumb_7E9C1748.jpg&quot; alt=&quot;IMG_6668_thumb&quot; title=&quot;IMG_6668_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/IMG_6677_thumb_7D07830F.jpg&quot; alt=&quot;IMG_6677_thumb&quot; title=&quot;IMG_6677_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/IMG_6680_thumb_3742AD57.jpg&quot; alt=&quot;IMG_6680_thumb&quot; title=&quot;IMG_6680_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/IMG_6683_thumb_0603271D.jpg&quot; alt=&quot;IMG_6683_thumb&quot; title=&quot;IMG_6683_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is me, shooting the cute squirrel:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P5150311_thumb_28576A3E.jpg&quot; alt=&quot;P5150311_thumb&quot; title=&quot;P5150311_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Snoqualmie Falls&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Snoqualmie_Falls&quot;&gt;Snoqualmie Falls&lt;/a&gt; is a 82m waterfall on the &lt;a href=&quot;http://en.wikipedia.org/wiki/Snoqualmie_River&quot;&gt;Snoqualmie River&lt;/a&gt; between &lt;a href=&quot;http://en.wikipedia.org/wiki/Snoqualmie,_Washington&quot;&gt;Snoqualmie&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Fall_City,_Washington&quot;&gt;Fall City&lt;/a&gt;. It is one of Washington&apos;s most popular scenic attractions. More than 1.5 million visitors come to the Falls every year.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/IMG_0325_thumb_262A45A8.png&quot; alt=&quot;IMG_0325_thumb&quot; title=&quot;IMG_0325_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/S7301192_thumb_47390414.jpg&quot; alt=&quot;S7301192_thumb&quot; title=&quot;S7301192_thumb&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Links for more pictures and information&lt;/h2&gt;
&lt;p&gt;For Green Lake:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Green_Lake_(Seattle)&quot;&gt;Green Lake on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Lake Washington:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;See &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-1-places&quot;&gt;part 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Mount Rainier&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Mount_Rainier&quot;&gt;Mount Rainier on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nps.gov/mora/index.htm&quot;&gt;Mount Rainier National Park official site&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Snoqualmie Falls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Snoqualmie_Falls&quot;&gt;Snoqualmie Falls on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://snoqualmiefalls.com/&quot;&gt;Snoqualmie Falls official site&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>The Memory of Programming in Seattle (1) Places</title><link>https://dixin.github.io/posts/the-memory-of-programming-in-seattle-1-places/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-memory-of-programming-in-seattle-1-places/</guid><description>Long long ago, I was working in Seattle – actually in Microsoft Redmond campus. That experience gave me a lot of beautiful memories:</description><pubDate>Tue, 22 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Long long ago, I was working in Seattle – actually in Microsoft Redmond campus. That experience gave me a lot of beautiful memories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Memory of Programming in Seattle (1) Places&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-2-working&quot;&gt;The Memory of Programming in Seattle (2) Working&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-3-living&quot;&gt;The Memory of Programming in Seattle (3) Living&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-4-food&quot;&gt;The Memory of Programming in Seattle (4) Food&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;The Memory of Programming in Seattle (5) Playing around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-6-university-of-washington&quot;&gt;The Memory of Programming in Seattle (6) University of Washington&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-7-microsoft-picnic&quot;&gt;The Memory of Programming in Seattle (7) Microsoft Picnic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Seattle&lt;/h2&gt;
&lt;p&gt;Seattle is in the northwest of US:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/image_thumb_3FEB2B21.png&quot; alt=&quot;image_thumb&quot; title=&quot;image_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On the map, it is even more north than Beijing.&lt;/p&gt;
&lt;p&gt;When first arriving in Seattle, A taxi took me from the &lt;a href=&quot;http://en.wikipedia.org/wiki/Seatac_Airport&quot;&gt;SeaTac airport&lt;/a&gt; to Microsoft. I was quite surprised because I did not see many fancy things on my way. Seattle does not look so populous and bustling as New York. There are some tall buildings in the downtown. But for the other places, it is more like a quiet and beautiful countryside.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1050771_fixed_thumb_7E400760.jpg&quot; alt=&quot;P1050771_fixed_thumb&quot; title=&quot;P1050771_fixed_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is the night of Seattle downtown, shot by my friend &lt;a href=&quot;http://wayneye.cn/&quot;&gt;Wei&lt;/a&gt; and psed by me. That is the most famous landmark of the city, the &lt;a href=&quot;http://www.spaceneedle.com/&quot;&gt;Space Needle&lt;/a&gt;. You can see it from &lt;a href=&quot;http://www.microsoft.com/presspass/exec/guthrie/default.aspx&quot;&gt;Scott Guthrie&lt;/a&gt;’s &lt;a href=&quot;http://weblogs.asp.net/scottgu/&quot;&gt;blog&lt;/a&gt; header, also the “Architecture” theme of Windows 7:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/img13_thumb_7BA6AFD5.jpg&quot; alt=&quot;img13_thumb&quot; title=&quot;img13_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Lake_Washington&quot;&gt;Lake Washington&lt;/a&gt; is also very beautiful. It is very huge. It is said a lot of the rich bosses in Microsoft bought palatial yachts and drive around in the lake, and the house of Bill Gates is on an island of this lake. On top of Space Needle, we can see a corner of the lake:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/P1040098_thumb_5C53E335.jpg&quot; alt=&quot;P1040098_thumb&quot; title=&quot;P1040098_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And this sunrise is &lt;a href=&quot;http://www.igougo.com/travelcontent/photoFull.aspx?PhotoID=304500&quot;&gt;from the Internet&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/lakewashingtonsunrise_thumb_04FF22B2.jpg&quot; alt=&quot;lake-washington-sunrise_thumb&quot; title=&quot;lake-washington-sunrise_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Salmon&quot;&gt;salmon&lt;/a&gt; in this lake is very delicious.&lt;/p&gt;
&lt;p&gt;There are &lt;a href=&quot;http://en.wikipedia.org/wiki/List_of_companies_based_in_Seattle&quot;&gt;many companies based in Seattle&lt;/a&gt;, like &lt;a href=&quot;http://en.wikipedia.org/wiki/Starbucks&quot;&gt;Starbucks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are a lot of gays and lesbians in Seattle. They have their own news paper, &lt;a href=&quot;http://www.sgn.org/&quot;&gt;Seattle Gay News&lt;/a&gt;, and their own &lt;a href=&quot;http://en.wikipedia.org/wiki/Seattle_Gay_and_Lesbian_Film_Festival&quot;&gt;film festival&lt;/a&gt;. One day I walked around Seattle downtown with my friends Jac and &lt;a href=&quot;http://wayneye.cn/&quot;&gt;Wei&lt;/a&gt;, and there we encountered &lt;a href=&quot;http://www.seattlepride.org/&quot;&gt;their parade&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Bellevue&lt;/h2&gt;
&lt;p&gt;I was living in &lt;a href=&quot;http://en.wikipedia.org/wiki/Bellevue,_Washington&quot;&gt;Bellevue&lt;/a&gt;. It belongs to &lt;a href=&quot;http://en.wikipedia.org/wiki/King_County,_Washington&quot;&gt;King County&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Washington&quot;&gt;Washington State&lt;/a&gt;. Bellevue and Seattle downtown are connected by &lt;a href=&quot;http://en.wikipedia.org/wiki/Evergreen_Point_Bridge&quot;&gt;Evergreen Point Floating Bridge&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Washington_State_Route_520&quot;&gt;State Route 520&lt;/a&gt;. Go across Lake Washington from Seattle downtown, it is Bellevue:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/evergreenpointbridge_thumb_5C03E7DB.jpg&quot; alt=&quot;evergreen-point-bridge_thumb&quot; title=&quot;evergreen-point-bridge_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The above picture is &lt;a href=&quot;http://upload.wikimedia.org/wikipedia/commons/3/3a/Aerial_520_Bridge_August_2009.JPG&quot;&gt;from Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bellevue is a French word, means “beautiful view” or [&lt;a href=&quot;http://translate.google.com/translate_t#fr%7Czh-CN%7CBelle%20vue&quot;&gt;美景尽收眼底&lt;/a&gt;] in Chinese. The place is as beautiful as its name. These pictures are the 156th Avenue outside my apartment, shot by my &lt;a href=&quot;http://www.nokiausa.com/find-products/phones/nokia-n73&quot;&gt;legacy Nokia N73&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614104_thumb_49F7A44E.jpg&quot; alt=&quot;20080614104_thumb&quot; title=&quot;20080614104_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614095_thumb_35EDEBEB.jpg&quot; alt=&quot;20080614095_thumb&quot; title=&quot;20080614095_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is the cross of the 156th Avenue and the Northup Way:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/20080614100_thumb_37123930.jpg&quot; alt=&quot;20080614100_thumb&quot; title=&quot;20080614100_thumb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Valve_Corporation&quot;&gt;Valve Corporation&lt;/a&gt; is in Bellevue, and Microsoft North American Sales Group is Headquartered in the Lincoln Square office tower, in &lt;a href=&quot;http://en.wikipedia.org/wiki/File:Aerial_Bellevue_Washington_August_2009.jpg&quot;&gt;Bellevue downtown&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bellevue is currently my favorite place in the US. It was rated one of the &lt;a href=&quot;http://money.cnn.com/2006/10/30/real_estate/Most_dangerous_cities/index.htm&quot;&gt;top 20 safest cities in America&lt;/a&gt;, based on the per-capita incidence of violent crime. The people living around me looked very polite:), which impressed me a lot.&lt;/p&gt;
&lt;p&gt;“Bellevue continues to be a very safe city, with the lowest per capita violent and property crime rate among the state&apos;s 10 largest cities.” &lt;a href=&quot;http://www.ci.bellevue.wa.us/council-roundup-9-21-09.htm&quot;&gt;said City Manager Steve Sarkozy&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Links for more pictures and information&lt;/h2&gt;
&lt;p&gt;For Seattle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Seattle&quot;&gt;Seattle on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.meritweb.com/seattle/&quot;&gt;Seattle Photographs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tripadvisor.com/LocationPhotos-g60878-w2-Seattle_Washington.html&quot;&gt;Seattle Pictures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Bellevue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Bellevue,_Washington&quot;&gt;Bellevue on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.city-data.com/city/Bellevue-Washington.html&quot;&gt;City-data.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ci.bellevue.wa.us/&quot;&gt;Official website of Bellevue City&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Discover Bellevue](http://wiki.worldflicks.org/bellevue,_washington.html#coords=(47.6106, -122.1994)&amp;amp;z=13) (This page is very nice)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For famous movies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.imdb.com/title/tt0108160/&quot;&gt;Sleepless in Seattle&lt;/a&gt;, 1993&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.imdb.com/title/tt0850253/&quot;&gt;Battle in Seattle&lt;/a&gt;, 2007&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.imdb.com/title/tt0370263/&quot;&gt;Alien vs. Predator&lt;/a&gt;, 2004 (Explained in &lt;a href=&quot;/posts/the-memory-of-programming-in-seattle-5-playing-around&quot;&gt;part 5&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>LINQ via C# Events Posters Design</title><link>https://dixin.github.io/posts/linq-via-csharp-events-posters-design/</link><guid isPermaLink="true">https://dixin.github.io/posts/linq-via-csharp-events-posters-design/</guid><description>10  events have been held successfully. Each event is a pure English speaking technical talk. I designed some posters for the events, with no enough time to design</description><pubDate>Mon, 21 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;10 &lt;a href=&quot;/posts/linq-via-csharp&quot;&gt;LINQ via C#&lt;/a&gt; events have been held successfully. Each event is a pure English speaking technical talk. I designed some posters for the events, with no enough time to design for each event.&lt;/p&gt;
&lt;h2&gt;LINQ via C# part 4&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/LinqViaCSharp4_Dixin_PosterDesign_64F76D87.jpg&quot; alt=&quot;LinqViaCSharp4_Dixin_PosterDesign&quot; title=&quot;LinqViaCSharp4_Dixin_PosterDesign&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In part 3, lambda expression of C# is introduced, in which audiences are very interested. So according to the feedback, in part 4 &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; is introduced in detail. On the poster there are a big lambda symbol and the classic lambda expression - &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_combinator#Y_combinator&quot;&gt;Y combinator&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;LINQ via C# part 5&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/LinqViaCSharp5_Dixin_PosterDesign_4FB94212.jpg&quot; alt=&quot;LinqViaCSharp5_Dixin_PosterDesign&quot; title=&quot;LinqViaCSharp5_Dixin_PosterDesign&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In part 4 people are attracted by lambda calculus. So in part 5 it is extended, and a little functional C# is introduced as well.&lt;/p&gt;
&lt;p&gt;This is based on a photo. The flower was shot in &lt;a href=&quot;http://en.wikipedia.org/wiki/Chengdu&quot;&gt;Chengdu&lt;/a&gt; by my brother. On this poster, just the seeds are changed into a λ symbol, which also looks like a Y.&lt;/p&gt;
&lt;h2&gt;LINQ via C# part 7&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/LinqViaCSharp7_Dixin_PosterDesign_4600AE0F.jpg&quot; alt=&quot;LinqViaCSharp7_Dixin_PosterDesign&quot; title=&quot;LinqViaCSharp7_Dixin_PosterDesign&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is copycat. I was very busy during that time, so I just picked up a wallpaper for Windows 7 in my computer, and changed the logo and text into LINQ stuff.&lt;/p&gt;
&lt;h2&gt;LINQ via C# part 9 and part 10&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/LinqViaCSharp9_Dixin_PosterDesign_547BAA34.jpg&quot; alt=&quot;LinqViaCSharp9_Dixin_PosterDesign&quot; title=&quot;LinqViaCSharp9_Dixin_PosterDesign&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I believe this one should be fancy enough, though it is nothing.&lt;/p&gt;
&lt;p&gt;All posters are designed by &lt;a href=&quot;http://www.adobe.com/products/fireworks/&quot;&gt;Fireworks&lt;/a&gt;. It is much lighter than Photoshop.&lt;/p&gt;
</content:encoded></item><item><title>Introducing CoolWebOS.com</title><link>https://dixin.github.io/posts/introducing-coolwebos-com/</link><guid isPermaLink="true">https://dixin.github.io/posts/introducing-coolwebos-com/</guid><description>This post is supposed to introduce the so-called WebOS – , as well as to have your important feedback.</description><pubDate>Sun, 20 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post is supposed to introduce the so-called WebOS – &lt;a href=&quot;http://www.CoolWebOS.com/&quot;&gt;http://www.CoolWebOS.com/&lt;/a&gt;, as well as to have your important feedback.&lt;/p&gt;
&lt;p&gt;WebOS 0.2 has been released quietly for some time. It is an OS-like personal Web portal, implementing the desktop OS experience in the Web pages.&lt;/p&gt;
&lt;h2&gt;Features&lt;/h2&gt;
&lt;p&gt;The current features includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using Web pages to simulate the UI of &lt;a href=&quot;http://www.apple.com/macosx/what-is-macosx/&quot;&gt;some kind of operating system&lt;/a&gt;, providing
&lt;ul&gt;
&lt;li&gt;a log on UI,&lt;/li&gt;
&lt;li&gt;a main desktop UI, where users can run “applications” from the start menu;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Each “application” is a Web widget, which are
&lt;ul&gt;
&lt;li&gt;either provided by WebOS itself,&lt;/li&gt;
&lt;li&gt;or mashed up from the Internet, like &lt;a href=&quot;http://www.google.com/webmasters/gadgets/&quot;&gt;Google Gadgets&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WebOS and its widgets are localizable, which means users can switch languages;&lt;/li&gt;
&lt;li&gt;WebOS is an extensible framework, so in the future, more and more widgets can be integrated;&lt;/li&gt;
&lt;li&gt;Finally, WebOS is also considered to be a potential &lt;a href=&quot;http://en.wikipedia.org/wiki/Software_as_a_service&quot;&gt;SaaS&lt;/a&gt; platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also some other technical objectives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The infrastructure (trying to avoid the word “architecture”) should be somehow professional;&lt;/li&gt;
&lt;li&gt;WebOS is designed to be very unit-testable (That’s why &lt;a href=&quot;http://www.asp.net/mvc/&quot;&gt;ASP.NET MVC&lt;/a&gt; is used);&lt;/li&gt;
&lt;li&gt;The C# code quality should be compliant with Microsoft &lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613&quot;&gt;Framework Design Guidelines&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;The JavaScript and CSS code must be well organized;&lt;/li&gt;
&lt;li&gt;WebOS must be no dependency on concrete data source like SQL Server, MySQL, Access, XML, etc., that’s because WebOS would be moved from one server to another, and those servers may support different data source, and that’s the reason &lt;a href=&quot;http://martinfowler.com/eaaCatalog/repository.html&quot;&gt;repository pattern&lt;/a&gt; is used;&lt;/li&gt;
&lt;li&gt;WebOS should be cross-browser-compatible in IE 6, &lt;a href=&quot;http://www.microsoft.com/windows/internet-explorer/ie7/&quot;&gt;IE 7&lt;/a&gt;, &lt;a href=&quot;http://www.microsoft.com/windows/internet-explorer/default.aspx&quot;&gt;IE 8&lt;/a&gt;, and the latest &lt;a href=&quot;http://www.mozilla.com/firefox/&quot;&gt;Firefox&lt;/a&gt;, &lt;a href=&quot;http://www.opera.com/&quot;&gt;Opera&lt;/a&gt;, &lt;a href=&quot;http://www.apple.com/safari/&quot;&gt;Safari&lt;/a&gt;, and &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Chrome&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I created, designed and implemented WebOS independently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Designed the infrastructure;&lt;/li&gt;
&lt;li&gt;Designed the database and developed the Website, service layer and data access layer;&lt;/li&gt;
&lt;li&gt;Designed and developed the widget framework, and developed several sample widgets;&lt;/li&gt;
&lt;li&gt;Improving user experience by usability testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My friends Ling and &lt;a href=&quot;http://fastdev.spaces.live.com&quot;&gt;Mark&lt;/a&gt; have offered distinguished code review. Many thanks!&lt;/p&gt;
&lt;h2&gt;Technologies&lt;/h2&gt;
&lt;p&gt;Actually, I am using a bunch of fancy stuff for the code (but they are probably outdated in your opinion):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&quot;&gt;ASP.NET MVC 1.0 RTM&lt;/a&gt; (I will upgrade to &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=d34f9eaa-fcbe-4e20-b2fd-a9a03de7d6dd&quot;&gt;ASP.NET MVC 2.0 Preview&lt;/a&gt; later if I have time);&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; 1.3.2;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://interface.eyecon.ro/&quot;&gt;Interface&lt;/a&gt; for jQuery;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://martinfowler.com/eaaCatalog/repository.html&quot;&gt;Repository pattern&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb425822.aspx&quot;&gt;LINQ to SQL&lt;/a&gt; for the data access;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://martinfowler.com/articles/injection.html&quot;&gt;Dependency injection pattern&lt;/a&gt; with the help of &lt;a href=&quot;http://unity.codeplex.com/&quot;&gt;Unity&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;A little &lt;a href=&quot;http://weblogs.asp.net/rashid/archive/2009/02/17/use-bootstrapper-in-your-asp-net-mvc-application-and-reduce-code-smell.aspx&quot;&gt;Bootstrapper&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;System.Web.Abstraction.dll for improving the unit-testability;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.msdn.microsoft.com/sourceanalysis&quot;&gt;StyleCop&lt;/a&gt; and Code Analysis are applied to help improving the code quality;&lt;/li&gt;
&lt;li&gt;Well modularized JavaScript and CSS;&lt;/li&gt;
&lt;li&gt;Of course, the globalization mechanism of ASP.NET;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I need to emphasize this is a totally playful website. Maybe we should not expect too much for such &lt;a href=&quot;http://en.wiktionary.org/wiki/JK&quot;&gt;JK&lt;/a&gt; website.&lt;/p&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;p&gt;The URI is: &lt;a href=&quot;http://www.CoolWebOS.com/&quot;&gt;http://www.CoolWebOS.com/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any problems, found some bugs, or have anything to say, please reply this post to offer the feedback, which is so important and appreciative.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (7) CLR</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-7-clr/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-7-clr/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Tue, 08 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Variances in CLR&lt;/h2&gt;
&lt;p&gt;Unlike C# 3.0 features are mostly C# level syntactical sugars, the variance feature of C# 4.0 is not just a CLR level feature.&lt;/p&gt;
&lt;p&gt;Take a look at the definition of System.Func&amp;lt;in T, out TResult&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class public auto ansi sealed System.Func`2&amp;lt;- T,+ TResult&amp;gt;
       extends System.MulticastDelegate
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the definition of System.IComparable&amp;lt;in T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class interface public abstract auto ansi System.IComparable`1&amp;lt;- T&amp;gt;
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CLR introduces the “-” operator to express the same meaning of “in” in C#, while “+” for “out”. The “in” and “out” keywords are introduced in &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/30/understanding-csharp-covariance-and-contravariance-2-interfaces.html&quot;&gt;part three&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Obviously, without the CLR supporting, those implicit type conversions in C# can never happen.&lt;/p&gt;
&lt;h2&gt;The + and – operators&lt;/h2&gt;
&lt;p&gt;Once again, take a look at these guys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Base
{
}

internal class Derived : Base
{
}

internal class AnotherDerived : Base
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Many materials from Internet start variances from the relationship of type A and type B:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A is bigger than B: for example, Base is bigger than Derived;&lt;/li&gt;
&lt;li&gt;A is smaller than B: for example, Derived is smaller than Base;&lt;/li&gt;
&lt;li&gt;A is equal to B: for example, Derived is equal to Derived, which is very simple;&lt;/li&gt;
&lt;li&gt;A is not related to B: for example, Derived is not related to AnotherDerived.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Think about the first two relationships. For the interfaces in &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/30/understanding-csharp-covariance-and-contravariance-2-interfaces.html&quot;&gt;part 2&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output: Derived is a Base =&amp;gt; for IOut&amp;lt;out T&amp;gt;, we have IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;;&lt;/li&gt;
&lt;li&gt;Contravariance of input: Derived is a Base =&amp;gt; for IIn&amp;lt;in T&amp;gt;, we have IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now with the “bigger and smaller concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output: Base is bigger than Derived =&amp;gt; for IOut&amp;lt;+ T&amp;gt;, we have IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;;&lt;/li&gt;
&lt;li&gt;Contravariance of input: Derived is smaller than Base =&amp;gt; for IIn&amp;lt;- T&amp;gt;, we have IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So for the + and - operators:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For covariance, + is used, which means can be bigger;&lt;/li&gt;
&lt;li&gt;For contravariance, – is used, which means can be smaller.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They look confusing, and it is hard to remember which is which, &lt;a href=&quot;http://blogs.msdn.com/ericlippert/archive/2007/10/31/covariance-and-contravariance-in-c-part-eight-syntax-options.aspx&quot;&gt;even for the members of the C# design committee&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>A UI bug of Windows Server 2008 R2 RTM</title><link>https://dixin.github.io/posts/a-ui-bug-of-windows-server-2008-r2-rtm/</link><guid isPermaLink="true">https://dixin.github.io/posts/a-ui-bug-of-windows-server-2008-r2-rtm/</guid><description>Today when playing with Windows Server 2008 R2 RTM at home, I noticed a small UI bug from the start menu.</description><pubDate>Mon, 07 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today when playing with Windows Server 2008 R2 RTM at home, I noticed a small UI bug from the start menu.&lt;/p&gt;
&lt;p&gt;After R2 RTM is installed, for the first log on, the default setting for “Control Panel” item of start menu is “Display as a menu”. Actually, the “Control Panel” item is displayed as a link.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/windowsserver2008r2rtmuibug_44C2527F.png&quot; alt=&quot;windows-server-2008-r2-rtm-ui-bug&quot; title=&quot;windows-server-2008-r2-rtm-ui-bug&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To resolve this, first select “Display as a link” in the “Customize Start Menu” dialog, click ”OK”, the “Control Panel” item remains. Then select “Display as a menu” back, this time “Control Panel” item is displayed as a menu, just like we expected.&lt;/p&gt;
&lt;p&gt;This bug repros in my:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows Server 2008 R2 RTM Enterprise&lt;/li&gt;
&lt;li&gt;Windows Server 2008 R2 RTM Datacenter&lt;/li&gt;
&lt;li&gt;Windows Server 2008 R2 RTM Standard&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (6) Typing issues</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues/</guid><description>Understanding C# covariance and contravariance:</description><pubDate>Tue, 01 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# covariance and contravariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/29/understanding-csharp-covariance-and-contravariance-1-delegates.html&quot;&gt;Understanding C# covariance and contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/30/understanding-csharp-covariance-and-contravariance-2-interfaces.html&quot;&gt;Understanding C# covariance and contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/31/understanding-csharp-covariance-and-contravariance-3-samples.html&quot;&gt;Understanding C# covariance and contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/31/understanding-csharp-covariance-and-contravariance-4-arrays.html&quot;&gt;Understanding C# covariance and contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/08/31/understanding-csharp-covariance-and-contravariance-5-higher-order-functions.html&quot;&gt;Understanding C# covariance and contravariance (5) Higher-order functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# covariance and contravariance (6) Typing issues&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/09/08/understanding-csharp-covariance-and-contravariance-7-clr.html&quot;&gt;Understanding C# covariance and contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/10/04/understanding-csharp-covariance-and-contravariance-8-void.html&quot;&gt;Understanding C# covariance and contravariance (8) Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In each previous part, type implicit conversion is dicussed, which happen during the variances, like&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;function (method / delegate) conversion, as well as higher-order function conversion;&lt;/li&gt;
&lt;li&gt;generic interface conversion;&lt;/li&gt;
&lt;li&gt;array conversion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since C# 4.0 introduces new variance rules, which means in C# 4.0, types could be more convertible than C# 2.0 / 3.0, there could be potential typing issues for C# 4.0. If comparing some code between Visual Studio 2008 (C# 2.0 / 3.0) and Visual Studio 2010 Beta2 (C# 4.0), you can find that is true.&lt;/p&gt;
&lt;h2&gt;Delegate covariance / contravariance issues&lt;/h2&gt;
&lt;p&gt;Take a look at this covariance sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Func&amp;lt;Base&amp;gt; baseFunc = () =&amp;gt; new Base();
Func&amp;lt;Derived&amp;gt; derivedFunc = () =&amp;gt; new Derived();

// This always prints &quot;True&quot;.
Console.WriteLine(derivedFunc is Func&amp;lt;Derived&amp;gt;);
// Covariance is supported by C# 4.0.
// This prints &quot;False&quot; in C# 2.0 / 3.0, prints &quot;True&quot; in C# 4.0.
Console.WriteLine(derivedFunc is Func&amp;lt;Base&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this contravariance sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Action&amp;lt;Base&amp;gt; baseAction = arg =&amp;gt; { };
Action&amp;lt;Derived&amp;gt; derivedAction = arg =&amp;gt; { };

// This always prints &quot;True&quot;.
Console.WriteLine(baseAction is Action&amp;lt;Base&amp;gt;);
// Contravariance is supported by C# 4.0.
// This prints &quot;False&quot; in C# 2.0 / 3.0, prints &quot;True&quot; in C# 4.0.
Console.WriteLine(baseAction is Action&amp;lt;Derived&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, in C# 4.0, delegate types are more convertable.&lt;/p&gt;
&lt;h2&gt;Interface covariance / contravariance issues&lt;/h2&gt;
&lt;p&gt;This is the interface covariance on IEnumerator&amp;lt;out T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerator&amp;lt;Base&amp;gt; baseEnumerator = new BaseEnumerator();
IEnumerator&amp;lt;Derived&amp;gt; derivedEnumerator = new DerivedEnumerator();

// This always prints &quot;True&quot;.
Console.WriteLine(derivedEnumerator is IEnumerator&amp;lt;Derived&amp;gt;);
// Covariance is supported by C# 4.0.
// This prints &quot;False&quot; in C# 2.0 / 3.0, prints &quot;True&quot; in C# 4.0.
Console.WriteLine(derivedEnumerator is IEnumerator&amp;lt;Base&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks acceptable.&lt;/p&gt;
&lt;p&gt;Then this is covariance on IEnumerable&amp;lt;out T&amp;gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IEnumerable&amp;lt;Base&amp;gt; bases = new Base[0];
IEnumerable&amp;lt;Derived&amp;gt; deriveds = new Derived[0];

// This always prints &quot;True&quot;.
Console.WriteLine(deriveds is IEnumerable&amp;lt;Derived&amp;gt;);
// Covariance is supported by C# 4.0.
// This prints &quot;True&quot; in C# 2.0 / 3.0 / 4.0.
Console.WriteLine(deriveds is IEnumerable&amp;lt;Base&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looks like a big mess.&lt;/p&gt;
&lt;p&gt;To try interface contravariance, IComparable&amp;lt;in T&amp;gt; can be used as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;internal class Base : IComparable&amp;lt;Base&amp;gt;
{
    public int CompareTo(Base other)
    {
        throw new NotImplementedException();
    }
}

internal class Derived : Base
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IComparable&amp;lt;Base&amp;gt; baseComparable = new Base();
// This cannot compile in C# 2.0 / 3.0,
// because Derived does not implement IComparable&amp;lt;Derived&amp;gt;.
IComparable&amp;lt;Derived&amp;gt; derivedComparable = new Derived();

// This always prints &quot;True&quot;.
Console.WriteLine(baseComparable is IComparable&amp;lt;Base&amp;gt;);
// Contravariance is supported by C# 4.0.
// This prints &quot;False&quot; in C# 2.0 / 3.0, prints &quot;True&quot; in C# 4.0.
Console.WriteLine(baseComparable is IComparable&amp;lt;Derived&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The interface variances are also confusing.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;C# 4.0 introduces new variance rules, so in C# 4.0, types becomes more convertible than C# 2.0 / 3.0. And this makes the same code work differently between C# 2.0 / 3.0 and C# 4.0.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (3) Variances in .NET</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-3-samples/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-3-samples/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Mon, 31 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not many generic types in .NET have variant type parameter(s). LINQ can be uses to query these generic types from .NET libraries.&lt;/p&gt;
&lt;p&gt;The following method queries a specified directory, and retrieve all .NET assemblies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Assembly&amp;gt; GetAssemblies(string directory)
    {
        return Directory.EnumerateFiles(directory, &quot;*.dll&quot;)
            .Select(file =&amp;gt;
                {
                    try
                    {
                        return Assembly.LoadFrom(file);
                    }
                    catch (BadImageFormatException)
                    {
                        return null;
                    }
                })
            .Where(assembly =&amp;gt; assembly != null);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following method queries one specified assembly, and filter generic types with any variant type parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Type&amp;gt; GetTypesWithVariance(Assembly assembly)
    {
        try
        {
            return assembly.ExportedTypes.Where(type =&amp;gt;
                type.IsGenericTypeDefinition &amp;amp;&amp;amp; type.GetGenericArguments().Any(argument =&amp;gt;
                    (argument.GenericParameterAttributes &amp;amp; GenericParameterAttributes.Covariant)
                    == GenericParameterAttributes.Covariant
                    ||
                    (argument.GenericParameterAttributes &amp;amp; GenericParameterAttributes.Contravariant)
                    == GenericParameterAttributes.Contravariant));
        }
        catch (TypeLoadException)
        {
            return Enumerable.Empty&amp;lt;Type&amp;gt;();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last method queries the assemblies in the same directory of mscorlib.dll, and retrieves the wanted types, and orders them by name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class ReflectionHelper
{
    public static IEnumerable&amp;lt;Type&amp;gt; GetTypesWithVariance()
    {
        string mscorlibPath = typeof(object).Assembly.GetName().CodeBase;
        string directory = Path.GetDirectoryName(new Uri(mscorlibPath).AbsolutePath);
        return GetAssemblies(directory)
            .SelectMany(GetTypesWithVariance)
            .OrderBy(type =&amp;gt; type.Name);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the result of executing the last method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System namespace:
&lt;ul&gt;
&lt;li&gt;Action`1 to Action`16, Func`1 to Func`17&lt;/li&gt;
&lt;li&gt;Comparison&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Converter`2&lt;/li&gt;
&lt;li&gt;IComparable&amp;lt;T&amp;gt;,&lt;/li&gt;
&lt;li&gt;IObservable&amp;lt;T&amp;gt;, IObserver&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IProgress&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Predicate&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Collections.Generic namespace:
&lt;ul&gt;
&lt;li&gt;IComparer&amp;lt;T&amp;gt;, IEqualityComparer&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IEnumerable&amp;lt;T&amp;gt;, IEnumerator&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;IReadOnlyCollection&amp;lt;T&amp;gt;, IReadOnlyList&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;System.Linq namespace:
&lt;ul&gt;
&lt;li&gt;IGrouping`2&lt;/li&gt;
&lt;li&gt;IOrderedQueryable&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MSDN has a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dd799517#VariantList&quot;&gt;List of Variant Generic Interface and Delegate Types&lt;/a&gt;, but it is inaccurate. For example, it says TElement is covariant for IOrderedEnumerable&amp;lt;TElement&amp;gt;, but actually not:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Linq
{
    public interface IOrderedEnumerable&amp;lt;TElement&amp;gt; : IEnumerable&amp;lt;TElement&amp;gt;, IEnumerable
    {
        IOrderedEnumerable&amp;lt;TElement&amp;gt; CreateOrderedEnumerable&amp;lt;TKey&amp;gt;(Func&amp;lt;TElement, TKey&amp;gt; keySelector, IComparer&amp;lt;TKey&amp;gt; comparer, bool descending);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (4) Arrays</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-4-arrays/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-4-arrays/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Mon, 31 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An array T[] can be viewed as an IList&amp;lt;T&amp;gt;. As fore mentioned, T is invariant for IList&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;h2&gt;Covariance&lt;/h2&gt;
&lt;p&gt;C# unexpectedly support covariance for array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void Covariance()
    {
        // IList&amp;lt;Base&amp;gt; baseArray = new Base[2];
        Base[] baseArray = new Base[2];

        // IList&amp;lt;Derived&amp;gt; derivedArray = new Derived[3];
        Derived[] derivedArray = new Derived[2];

        // T of IList&amp;lt;T&amp;gt; is invariant,
        // so logically binding IList&amp;lt;derivedArray&amp;gt; to IList&amp;lt;Base&amp;gt; could not be compiled.
        // But C# compiles it, to be compliant with Java :(
        baseArray = derivedArray; // Array covariance.

        // At runtime, baseArray refers to a Derived array.
        // So A Derived object can be an element of baseArray[0].
        baseArray[0] = new Derived();

        // At runtime, baseArray refers to a Derived array.
        // A Base object &quot;is not a&quot; Derivd object.
        // And ArrayTypeMismatchException is thrown at runtime.
        baseArray[1] = new Base();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code can be compiled but throws ArrayTypeMismatchException at runtime. In some scenarios, this can be confusing and makes code buggy. For example, when using array as parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void ProcessArray(Base[] array)
    {
        array[0] = new Base(); // ArrayTypeMismatchException.
        }

    public static void CallProcessArray()
    {
        Derived[] array = new Derived[1];
        ProcessArray(array); // Array covariance. Compliable.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As fore mentioned, value type has nothing to do with variances, the following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class Array
{
    public static void ValueType()
    {
        object[] objectArray = new object[1];
        int[] int32Array = new int[1];
#if Uncompilable
        // No covariance.
        objectArray = int32Array;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;p&gt;Here are some comments for array covariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/news/2008/08/GenericVariance&quot;&gt;Jonathan Allen said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On a historical note, C# and VB both support array covariance (&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/09/01/understanding-csharp-covariance-and-contravariance-6-typing-issues.html&quot;&gt;out/IEnumerable scenario&lt;/a&gt;) even though it can lead to runtime errors in contravariant situations (in/IWriter scenario). This was done in order to make C# more compatible with Java. This is generally considered a poor decision, but it cannot be undone at this time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the book “&lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0321154932&quot;&gt;The Common Language Infrastructure Annotated Standard&lt;/a&gt;”, Jim Miller said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The decision to support covariant arrays was primarily to allow Java to run on the VES. The covariant design is not thought to be the best design in general, but it was chosen in the interest of broad reach.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx&quot;&gt;Rick Byers said&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve heard that Bill Joy, one of the original Java designers, has since said that he tried to remove array covariance in 1995 but wasn&apos;t able to do it in time, and has regretted having it in Java ever since.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Anders Hejlsberg (&lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;chief architect&lt;/a&gt; of C#) &lt;a href=&quot;http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/&quot;&gt;said in this video&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This isn&apos;t type safe. A lot of people maybe don&apos;t even realize that there&apos;s a hole there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a C# feature that should never be used.&lt;/p&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (5) Higher-order functions</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Mon, 31 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Higher-order_function&quot;&gt;Higher-order functions&lt;/a&gt; are functions which either take one or more functions as input, or output a function. The other functions are called first-order functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrder
{
    public static void FirstOrderAndHigherOrder()
    {
        { Action action = () =&amp;gt; { }; } // First-order function.
        Action&amp;lt;Action&amp;gt; actionIn = action =&amp;gt; action(); // Higher-order function

        Func&amp;lt;object&amp;gt; func = () =&amp;gt; new object(); // First-order function.
        Func&amp;lt;Func&amp;lt;object&amp;gt;&amp;gt; funcOut = () =&amp;gt; func; // Higher-order function
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, all the covariance/contravariance demonstrations are using first-order functions. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrder
{
    // System.Action&amp;lt;T&amp;gt;.
    public delegate void Action&amp;lt;in TIn&amp;gt;(TIn @in);

    public static void ContravarianceForFirstOrder()
    {
        // First-order functions.
        Action&amp;lt;Derived&amp;gt; derivedIn = (Derived @in) =&amp;gt; { };
        Action&amp;lt;Base&amp;gt; baseIn = (Base @in) =&amp;gt; { };

        // Contravariance of input: Action&amp;lt;Base&amp;gt; &quot;is a&quot; Action&amp;lt;Derived&amp;gt;.
        // Or: T is contravariant for Action&amp;lt;in T&amp;gt;.
        derivedIn = baseIn;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most LINQ query methods are higher-order functions. In the fore mentioned example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class LinqToObjects
{
    public static IEnumerable&amp;lt;int&amp;gt; Positive(IEnumerable&amp;lt;int&amp;gt; source)
    {
        return source.Where(value =&amp;gt; value &amp;gt; 0);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the lambda expression is a anonymous first-order function, and Where is a higher-order function.&lt;/p&gt;
&lt;h2&gt;Variance of input&lt;/h2&gt;
&lt;p&gt;The following delegate type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate void ActionIn&amp;lt;T&amp;gt;(Action&amp;lt;T&amp;gt; action);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can represent a higher-order function type, which take a function as parameter.&lt;/p&gt;
&lt;p&gt;Regarding T for Action&amp;lt;T&amp;gt; is contravariant, is T still contravariant for ActionIn&amp;lt;T&amp;gt;? The answer is no. The following code cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrder
{
#if Uncompilable
    public delegate void ActionIn&amp;lt;in T&amp;gt;(Action&amp;lt;T&amp;gt; action);

    public static void ContravarianceOfInput()
    {
        // Higher-order funcitons:
        ActionIn&amp;lt;Derived&amp;gt; derivedInIn = (Action&amp;lt;Derived&amp;gt; derivedIn) =&amp;gt; derivedIn(new Derived());
        ActionIn&amp;lt;Base&amp;gt; baseInIn = (Action&amp;lt;Base&amp;gt; baseIn) =&amp;gt; baseIn(new Base());

        // Regarding Action&amp;lt;Base&amp;gt; &quot;is a&quot; ActionIn&amp;lt;Derived&amp;gt;,
        // assumes there is still contravariance of input,
        // which is, ActionIn&amp;lt;Base&amp;gt; &quot;is a&quot; ActionIn&amp;lt;Derived&amp;gt;
        derivedInIn = baseInIn;

        // When calling baseInIn, derivedInIn executes.
        // baseInIn should have a Action&amp;lt;Base&amp;gt; input, while derivedInIn requires a Action&amp;lt;Derived&amp;gt; input.
        // The actual Action&amp;lt;Base&amp;gt; &quot;is a&quot; required Action&amp;lt;Derived&amp;gt;. This binding should always works.
        baseInIn(new Action&amp;lt;Base&amp;gt;((Base @in) =&amp;gt; { }));
    }
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is the problem here? And how to fix?&lt;/p&gt;
&lt;h2&gt;Revisit covariance and contravariance&lt;/h2&gt;
&lt;p&gt;First, covariance/contravariance can be viewed in another way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Func&amp;lt;T&amp;gt;: Derived “is a” Base =&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt;. This is named covariance (not out-variance) because the direction of “is a” relationship remains.&lt;/li&gt;
&lt;li&gt;Action&amp;lt;T&amp;gt;: Derived “is a” Base =&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt;. This is named contravariance (not in-variance) because the direction of “is a” relationship reverses.
&lt;ul&gt;
&lt;li&gt;In the original “is a” relationship, Derived is on the left side, Base is on the right side&lt;/li&gt;
&lt;li&gt;In the new “is a” relationship, Derived goes to the right, and Base goes to the left&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To examine the variance for higher-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Func&amp;lt;T&amp;gt; can be made higher order, by just replacing T with Func&amp;lt;T&amp;gt;. Then:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Derived/Base. Comparing to 1, T is covariant for Func&amp;lt;T&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Func&amp;lt;Derived&amp;gt;/Func&amp;lt;Base&amp;gt;. Comparing to 1, T is covariant for Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Func&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; (In Func&amp;lt;T&amp;gt;, replaces T with Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; /Func&amp;lt;Func&amp;lt;Base&amp;gt;&amp;gt; . Comparing to 1, T is covariant for Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Action&amp;lt;T&amp;gt; can be made higher order, by just replacing T with Action&amp;lt;T&amp;gt;. Then:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Base/Derived. the direction of “Is-a” relationship reverses. Comparing to 1, T is contravariant for Action&amp;lt;T&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Action&amp;lt;Derived&amp;gt;/Action&amp;lt;Base&amp;gt;. the direction of “Is-a” relationship reverses again, so that Derived goes back to left, and Base goes back to right. Comparing to 1, T is covariant for Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; (In Action&amp;lt;T&amp;gt;, replaces T with Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; /Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;. Comparing to 1, T is contravariant for Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;.)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In above code, ActionIn&amp;lt;T&amp;gt; is equivalent to Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;. So, T is covariant for Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;/ActionIn&amp;lt;T&amp;gt;, not contravariant. The fix is to use out keyword to decorate T, and swap the binding:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrder
{
    // Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;
    public delegate void ActionIn&amp;lt;out T&amp;gt;(Action&amp;lt;T&amp;gt; action);

    public static void CovarianceOfInput() // Not contravariance.
    {
        // Higher-order funcitons:
        ActionIn&amp;lt;Derived&amp;gt; derivedInIn = (Action&amp;lt;Derived&amp;gt; derivedIn) =&amp;gt; derivedIn(new Derived());
        ActionIn&amp;lt;Base&amp;gt; baseInIn = (Action&amp;lt;Base&amp;gt; baseIn) =&amp;gt; baseIn(new Base());

        // Not derivedInIn = baseInIn;
        baseInIn = derivedInIn;

        // When calling baseInIn, derivedInIn executes.
        // baseInIn should have a Action&amp;lt;Base&amp;gt; input, while derivedInIn requires a Action&amp;lt;Derived&amp;gt; input.
        // The actual Action&amp;lt;Base&amp;gt; &quot;is a&quot; required Action&amp;lt;Derived&amp;gt;. This binding always works.
        baseInIn(new Action&amp;lt;Base&amp;gt;((Base @in) =&amp;gt; { }));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other case, type parameter as output, is straightforward, because the type parameter is always covariant for any first-order/higher-order function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class HigherOrder
{
    public delegate Func&amp;lt;TOut&amp;gt; FuncOut&amp;lt;out TOut&amp;gt;();

    public static void CovarianceOfOutput()
    {
        // First order functions.
        Func&amp;lt;Base&amp;gt; baseOut = () =&amp;gt; new Base();
        Func&amp;lt;Derived&amp;gt; derivedOut = () =&amp;gt; new Derived();
        // T is covarianct for Func&amp;lt;T&amp;gt;.
        baseOut = derivedOut;

        // Higher-order funcitons:
        FuncOut&amp;lt;Base&amp;gt; baseOutOut = () =&amp;gt; baseOut;
        FuncOut&amp;lt;Derived&amp;gt; derivedOutOut = () =&amp;gt; derivedOut;

        // Covariance of output: FuncOut&amp;lt;Derived&amp;gt; &quot;is a&quot; FuncOut&amp;lt;Base&amp;gt;
        baseOutOut = derivedOutOut;

        // When calling baseOutOut, derivedOutOut executes.
        // baseOutOut should output a Func&amp;lt;Base&amp;gt;, while derivedOutOut outputs a Func&amp;lt;Derived&amp;gt;.
        // The actual Func&amp;lt;Derived&amp;gt; &quot;is a&quot; required Func&amp;lt;Base&amp;gt;. This binding always works.
        baseOut = baseOutOut();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Variances for higher-order function&lt;/h2&gt;
&lt;p&gt;Variances are straightforward for first-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output (out keyword): Derived “is a” Base =&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt; (“Is-a” remains.)&lt;/li&gt;
&lt;li&gt;Contravariance of input (in keyword): Derived “is a” Base =&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (“Is-a” reverses.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For higher-order functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Output is always covariant:
&lt;ul&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Derived&amp;gt; “is a” Func&amp;lt;Base&amp;gt;&lt;/li&gt;
&lt;li&gt;=&amp;gt; Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt; “is a” Func&amp;lt;Func&amp;lt;Derived&amp;gt;&amp;gt;&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Input can be either contravariant or covariant, depends on how many times the direction of “is-a” relationship reverses:
&lt;ol&gt;
&lt;li&gt;Derived “is a” Base&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Base&amp;gt; “is a” Action&amp;lt;Derived&amp;gt; (contravariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt; (covariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; Action&amp;lt;Action&amp;lt;Action&amp;lt;Base&amp;gt;&amp;gt;&amp;gt; “is a” Action&amp;lt;Action&amp;lt;Action&amp;lt;Derived&amp;gt;&amp;gt;&amp;gt; (contravariance)&lt;/li&gt;
&lt;li&gt;=&amp;gt; …&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public static class OutputCovarianceForHigherOrder
{
    public delegate T Func&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;
    public delegate Func&amp;lt;T&amp;gt; FuncOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    public delegate FuncOut&amp;lt;T&amp;gt; FuncOutOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // Func&amp;lt;Func&amp;lt;Func&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;
    public delegate FuncOutOut&amp;lt;T&amp;gt; FuncOutOutOut&amp;lt;out T&amp;gt;(); // Covariant T as output.

    // ...
}

public static class InputVarianceReversalForHigherOrder
{
    public delegate void Action&amp;lt;in T&amp;gt;(T @in); // Contravariant T as input.

    // Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;
    public delegate void ActionIn&amp;lt;out T&amp;gt;(Action&amp;lt;T&amp;gt; action); // Covariant T as input.

    // Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;
    public delegate void ActionInIn&amp;lt;in T&amp;gt;(ActionIn&amp;lt;T&amp;gt; actionIn); // Contravariant T as input.

    // Action&amp;lt;Action&amp;lt;Action&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;
    public delegate void ActionInInIn&amp;lt;out T&amp;gt;(ActionInIn&amp;lt;T&amp;gt; actionInIn); // Covariant T as input.

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Understanding C# Covariance And Contravariance (2) Interfaces</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-2-interfaces/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-2-interfaces/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Sun, 30 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-1-delegates&quot;&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In C# 4.0+, covariance and contravariance are used for generic interfaces. Covariance and contravariance&lt;/p&gt;
&lt;p&gt;An interface can be viewed as a set of method signatures, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IOut&amp;lt;TOut&amp;gt; // TOut is only used as output.
{
    TOut Out1(); // TOut is covariant for Out1 (Func&amp;lt;TOut&amp;gt;).

    TOut Out2(object @in); // TOut is covariant for Out2 (Func&amp;lt;object, TOut&amp;gt;).

    TOut Out3 { get; } // TOut is covariant for Out3&apos;s getter (Func&amp;lt;object, TOut&amp;gt;).
}

public interface IIn&amp;lt;TIn&amp;gt; // TIn is only used as input.
{
    void In1(TIn @in); // TIn is contravariant for In1 (Action&amp;lt;TIn&amp;gt;).

    object In2(TIn @in); // TIn is contravariant for In2 (Func&amp;lt;TIn, object&amp;gt;).

    TIn In3 { set; } // TIn is contravariant for In3&apos;s setter (Action&amp;lt;TIn&amp;gt;).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Covariance&lt;/h2&gt;
&lt;p&gt;For interface IOut&amp;lt;TOut&amp;gt;, TOut is covariant for all members, so TOut can be made covariant at interface level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IOut&amp;lt;out TOut&amp;gt; // TOut is covariant for all members of interface.
{
    TOut Out1();

    TOut Out2(object @in);

    TOut Out3 { get; } // TOut get_Out3();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the following interface binding (assignment) works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void Covariance()
    {
        IOut&amp;lt;Base&amp;gt; baseOut = default(IOut&amp;lt;Base&amp;gt;);
        IOut&amp;lt;Derived&amp;gt; derivedOut = default(IOut&amp;lt;Derived&amp;gt;);

        // Covariance: Derived &quot;is a&quot; Base =&amp;gt; IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;.
        baseOut = derivedOut;

        // So that, when calling baseOut.Out1, the underlying derivedOut.Out1 executes.
        // derivedOut.Out1 method (Func&amp;lt;Derived&amp;gt;) &quot;is a&quot; baseOut.Out1 method (Func&amp;lt;Base&amp;gt;).
        Base out1 = baseOut.Out1();

        // When calling baseOut.Out2, the underlying derivedOut.Out2 executes.
        // derivedOut.Out2 (Func&amp;lt;object, Derived&amp;gt;) &quot;is a&quot; baseOut.Out2 (Func&amp;lt;object, Base&amp;gt;).
        Base out2 = baseOut.Out2(@in: new object());

        // Out3 property is getter only. The getter is a get_Out3 method (Func&amp;lt;TOut&amp;gt;).
        // derivedOut.Out3 getter (Func&amp;lt;Derived&amp;gt;) &quot;is a&quot; baseOut.Out3 getter (Func&amp;lt;Base&amp;gt;).
        Base out3 = baseOut.Out3;

        // So, IOut&amp;lt;Derived&amp;gt; interface &quot;is an&quot; IOut&amp;lt;Base&amp;gt; interface. Above binding always works.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET 4.0+, System.Collections.Generic.IEnumerator&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    /// &amp;lt;summary&amp;gt;Supports a simple iteration over a generic collection.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to enumerate.This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator
    {
        T Current { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Contravariance&lt;/h3&gt;
&lt;p&gt;For interface IIn&amp;lt;TIn&amp;gt;, TIn is contravariant for all members, so TIn can be made contravariant at interface level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn&amp;lt;in TIn&amp;gt; // TIn is contravariant for all members of interface.
{
    void In1(TIn @in);

    object In2(TIn @in);

    TIn In3 { set; } // void set_In3(TIn @in);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the following interface binding works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void Contravariance()
    {
        IIn&amp;lt;Derived&amp;gt; derivedIn = default(IIn&amp;lt;Derived&amp;gt;);
        IIn&amp;lt;Base&amp;gt; baseIn = default(IIn&amp;lt;Base&amp;gt;);

        // Contravariance: Derived &quot;is a&quot; Base =&amp;gt; IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;.
        derivedIn = baseIn;

        // When calling derivedIn.In1, the underlying baseIn.In1 executes.
        // baseIn.In1 method (Action&amp;lt;Base&amp;gt;) &quot;is a&quot; derivedIn.In1 method (Action&amp;lt;Derived&amp;gt;).
        derivedIn.In1(new Derived());

        // When calling derivedIn.In2, the underlying baseIn.In2 executes.
        // baseIn.In2 (Func&amp;lt;Base, object&amp;gt;) &quot;is a&quot; derivedIn.In2 (Func&amp;lt;Derived, object&amp;gt;).
        object @out = derivedIn.In2(new Derived());

        // In3 property is setter only. The setter is a set_In3 method (Action&amp;lt;TOut&amp;gt;).
        // baseIn.In3 setter (Action&amp;lt;Base&amp;gt;) &quot;is a&quot; derivedIn.In3 setter (Action&amp;lt;Base&amp;gt;).
        derivedIn.In3 = new Derived();

        // So, IIn&amp;lt;Base&amp;gt; interface &quot;is an&quot; IIn&amp;lt;Derived&amp;gt; interface. Above binding always works.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET 4.0+, System.IComparable&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    /// &amp;lt;summary&amp;gt;Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering instances.&amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The type of objects to compare.This type parameter is contravariant. That is, you can use either the type you specified or any type that is less derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.&amp;lt;/typeparam&amp;gt;
    public interface IComparable&amp;lt;in T&amp;gt;
    {
        int CompareTo(T other);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Covariance and contravariance&lt;/h2&gt;
&lt;p&gt;A generic interface can have both covariant and contravariance type parameters, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn_Out&amp;lt;in TIn, out TOut&amp;gt;
{
    void In(TIn @in);
    TOut Out();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericInterfaceWithVariances
{
    public static void CovarianceAndContravariance()
    {
        IIn_Out&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = default(IIn_Out&amp;lt;Derived, Base&amp;gt;);
        IIn_Out&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = default(IIn_Out&amp;lt;Base, Derived&amp;gt;);

        // Covariance and contravariance: IIn_Out&amp;lt;Base, Derived&amp;gt; &quot;is a&quot; IIn_Out&amp;lt;Derived, Base&amp;gt;.
        derivedIn_BaseOut = baseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Invariance&lt;/h2&gt;
&lt;p&gt;In the following generic interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IIn_Out&amp;lt;T&amp;gt;
{
    T Out(); // T is covariant for Out (Func&amp;lt;T&amp;gt;).

    void In(T @in); // T is contravaraint for In (Action&amp;lt;T&amp;gt;).
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;T is not covariant for some member, and not contravariant for some other member. So, T cannot be variant at the interface level. In .NET, System.Collections.Generic.IList&amp;lt;T&amp;gt; is such an interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System.Collections.Generic
{
    public interface IList&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt;, IEnumerable
    {
        T this[int index]
        {
            get; // T is covariant.
            set; // T is contravariant.
        }

        // Other members.
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Is-a relationship of generic interfaces&lt;/h2&gt;
&lt;p&gt;The “is-a” relationship can be promoted to generic interfaces (sets of method signatures):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance: Derived is a Base =&amp;gt; IOut&amp;lt;Derived&amp;gt; &quot;is a&quot; IOut&amp;lt;Base&amp;gt;;&lt;/li&gt;
&lt;li&gt;Contravariance: Derived is a Base =&amp;gt; IIn&amp;lt;Base&amp;gt; &quot;is a&quot; IIn&amp;lt;Derived&amp;gt;;&lt;/li&gt;
&lt;li&gt;Covariance and contravariance: Derived is a Base =&amp;gt; IIn_Out&amp;lt;Base, Derived&amp;gt; &quot;is a&quot; IIn_Out&amp;lt;Derived, Base&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Understanding C# Covariance and Contravariance (1) Delegates</title><link>https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-1-delegates/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-csharp-covariance-and-contravariance-1-delegates/</guid><description>Understanding C# Covariance And Conreavariance:</description><pubDate>Sat, 29 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Understanding C# Covariance And Conreavariance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understanding C# Covariance And Contravariance (1) Delegates&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-2-interfaces&quot;&gt;Understanding C# Covariance And Contravariance (2) Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-3-samples&quot;&gt;Understanding C# Covariance And Contravariance (3) Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-4-arrays&quot;&gt;Understanding C# Covariance And Contravariance (4) Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-5-higher-order-functions&quot;&gt;Understanding C# Covariance And Contravariance (5) Higher-order Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-6-typing-issues&quot;&gt;Understanding C# Covariance And Contravariance (6) Typing Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-7-clr&quot;&gt;Understanding C# Covariance And Contravariance (7) CLR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/understanding-csharp-covariance-and-contravariance-8-struct-and-void&quot;&gt;Understanding C# Covariance And Contravariance (8) Struct And Void&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;a href=&quot;https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)&quot;&gt;Covariance/contravariance&lt;/a&gt;, variance is the capability to replace a type with a less-derived type or a more-derived type in a context. C# 4.0 and CLR 4 introduced covariance and contravariance for generics.&lt;/p&gt;
&lt;h2&gt;Is-a relationship for inheritance&lt;/h2&gt;
&lt;p&gt;Since covariance and contravariance is about deriving, the following &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/27db6csx.aspx&quot;&gt;inheritance hierarchy&lt;/a&gt; is defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Base
{
}

public class Derived : Base
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently, a Derived object “&lt;a href=&quot;https://en.wikipedia.org/wiki/Is-a&quot;&gt;is a&lt;/a&gt;” Base object.&lt;/p&gt;
&lt;h2&gt;Non-generic delegate&lt;/h2&gt;
&lt;p&gt;By using above Base/Derived as input/output of method, there are 4 combinations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class Methods
{
    public static Base DerivedIn_BaseOut(Derived @in)
    {
        return new Base();
    }

    public static Derived DerivedIn_DerivedOut(Derived @in)
    {
        return new Derived();
    }

    public static Base BaseIn_BaseOut(Base @in)
    {
        return new Base();
    }

    public static Derived BaseIn_DerivedOut(Base @in)
    {
        return new Derived();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Bind method to a delegate&lt;/h3&gt;
&lt;p&gt;Before C# 4.0, C# already supported covariance and contravariance for delegates without generics. Consider the following delegate type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate Base DerivedIn_BaseOut(Derived @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above Methods.DerivedIn_BaseOut’s signature matches this delegate type, so Methods.DerivedIn_BaseOut can be bound to its delegate instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Bind()
    {
        // Binding: DerivedIn_BaseOut delegate type and DerivedIn_BaseOut method have exactly the same signature.
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.DerivedIn_BaseOut;

        // When calling derivedIn_BaseOut delegate instance, DerivedIn_BaseOut method executes.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Covariance&lt;/h3&gt;
&lt;p&gt;Methods.DerivedIn_DerivedOut has a different signature from DerivedIn_BaseOut delegate type. The former returns a more derived type. There is a “is-a” relationship between their return types, but there is no intuitive relationship between the two signatures.&lt;/p&gt;
&lt;p&gt;However, C# compiler and the CLR both allow the following binding (assignment) before C# 4.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Covariance()
    {
        // Covariance: Derived &quot;is a&quot; Base =&amp;gt; DerivedIn_DerivedOut &quot;is a&quot; DerivedIn_BaseOut.
        DerivedIn_BaseOut derivedIn_DerivedOut = Methods.DerivedIn_DerivedOut;

        // When calling derivedIn_BaseOut delegate instance, DerivedIn_DerivedOut method executes.
        // derivedIn_BaseOut should output a Base object, while DerivedIn_DerivedOut outputs a Derived object.
        // The actual Derived object &quot;is a&quot; required Base output. This binding always works.
        Base @out = derivedIn_DerivedOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a bound method can return a more derived type than the delegate type. This is called covariance.&lt;/p&gt;
&lt;h3&gt;Contravariance&lt;/h3&gt;
&lt;p&gt;Methods.BaseIn_BaseOut required a less-derived parameter then DerivedIn_BaseOut delegate type. The following binding also works before C# 4.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public static void Contravariance()
    {
        // Contravariance: Derived is a Base =&amp;gt; BaseIn_BaseOut is a DerivedIn_BaseOut.
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.BaseIn_BaseOut;

        // When calling derivedIn_BaseOut delegate instance, BaseIn_BaseOut method executes.
        // derivedIn_BaseOut should have a Derived input, while BaseIn_BaseOut requires a Base input.
        // The actual Derived object &quot;is a&quot; required Base input. This binding always works.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here a method can have less derived parameter type than the delegate type. This is called contravariance.&lt;/p&gt;
&lt;h3&gt;Covariance and contravariance&lt;/h3&gt;
&lt;p&gt;It is easy to predict, Methods.BaseIn_DerivedOut, with more derived parameter type and less derived return type, can be also bound to DerivedIn_BaseOut:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{

    public static void CovarianceAndContravariance()
    {
        // Covariance and contravariance: Derived is a Base =&amp;gt; BaseIn_DerivedOut is a DerivedIn_BaseOut. 
        DerivedIn_BaseOut derivedIn_BaseOut = Methods.BaseIn_DerivedOut;

        // When calling derivedInBaseOut delegate instance, BaseIn_DerivedOut method executes.
        // derivedIn_BaseOut should have a Derived input, while BaseIn_DerivedOut requires a Base input.
        // derivedIn_BaseOut should output a Base object, while BaseIn_DerivedOut outputs a Derived object. 
        // This binding always works.
        Base @out = derivedIn_BaseOut(@in: new Derived());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here covariance and contravariance both happen for the same binding.&lt;/p&gt;
&lt;h3&gt;Invalid variance&lt;/h3&gt;
&lt;p&gt;In the following bindings, there is no valid variance, so they cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class NonGenericDelegate
{
    public delegate Derived BaseIn_DerivedOut(Base @base);

    public static void InvalidVariance()
    {
#if Uncompilable
        // baseIn_DerivedOut should output a Derived object, while BaseIn_DerivedOut outputs a Base object. 
        // Base is not Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut1 = Methods.BaseIn_BaseOut;

        // baseIn_DerivedOut should have a Base input, while DerivedIn_BaseOut required a Derived output.
        // Base is not a Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut2 = Methods.DerivedIn_BaseOut;

        // baseIn_DerivedOut should have a Base input, while DerivedIn_DerivedOut required a Derived input.
        // baseIn_DerivedOut should output a Derived object, while derivedIn_DerivedOut outputs a Base object. 
        // Base is not a Derived, the following binding cannot be compiled.
        BaseIn_DerivedOut baseIn_DerivedOut3 = Methods.DerivedIn_DerivedOut;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Is-a relationship of delegates&lt;/h3&gt;
&lt;p&gt;The root of variances is that, in inheritance hierarchy, derived object “is a” base object. This “is-a” relationship can be promoted to a relationship between method and delegate types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Covariance of output: Derived is a Base =&amp;gt; DerivedIn_DerivedOut is a DerivedIn_BaseOut;&lt;/li&gt;
&lt;li&gt;Contravariance of input: Derived is a Base =&amp;gt; BaseIn_BaseOut is a DerivedIn_BaseOut;&lt;/li&gt;
&lt;li&gt;Covariance of output and contravariance of input: Derived is a Base =&amp;gt; BaseIn_DerivedOut is a DerivedIn_BaseOut.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please notice these rules does not apply to value types. Basically value types has nothing to do with covariance/contravariance.&lt;/p&gt;
&lt;h2&gt;Generic delegate&lt;/h2&gt;
&lt;p&gt;With C# 2.0 generic delegate, the above XxxIn_XxxOut delegate types can be represented by the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TOut Func&amp;lt;TIn, TOut&amp;gt;(TIn @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then above method bindings become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
    public static void BindMethods()
    {
        // Bind.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut1 = Methods.DerivedIn_BaseOut;

        // Covariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut2 = Methods.DerivedIn_DerivedOut;

        // Contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut3 = Methods.BaseIn_BaseOut;

        // Covariance and contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut4 = Methods.BaseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C# 3.0 introduced lambda expression. However, the above bindings cannot be used for lambda expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegate
{
    public static void BindLambdas()
    {
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = (Derived @in) =&amp;gt; new Base();
        Func&amp;lt;Derived, Derived&amp;gt; derivedIn_DerivedOut = (Derived @in) =&amp;gt; new Derived();
        Func&amp;lt;Base, Base&amp;gt; baseIn_BaseOut = (Base @in) =&amp;gt; new Base();
        Func&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = (Base @in) =&amp;gt; new Derived();

#if Uncompilable
        // Covariance.
        derivedIn_BaseOut = derivedIn_DerivedOut;

        // Contravariance.
        derivedIn_BaseOut = baseIn_BaseOut;

        // Covariance and contravariance.
        derivedIn_BaseOut = baseIn_DerivedOut;
#endif
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The out and in keywords&lt;/h3&gt;
&lt;p&gt;C# 4.0 uses the in/out keywords to specify a type parameter is contravariant/covariant. So above generic delegate can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public delegate TOut Func&amp;lt;in TIn, out TOut&amp;gt;(TIn @in);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the bindings work for both methods and lambda expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
    public static void BindMethods()
    {
        // Bind.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut1 = Methods.DerivedIn_BaseOut;

        // Covariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut2 = Methods.DerivedIn_DerivedOut;

        // Contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut3 = Methods.BaseIn_BaseOut;

        // Covariance and contravariance.
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut4 = Methods.BaseIn_DerivedOut;
    }

    public static void BindLambdas()
    {
        Func&amp;lt;Derived, Base&amp;gt; derivedIn_BaseOut = (Derived @in) =&amp;gt; new Base();
        Func&amp;lt;Derived, Derived&amp;gt; derivedIn_DerivedOut = (Derived @in) =&amp;gt; new Derived();
        Func&amp;lt;Base, Base&amp;gt; baseIn_BaseOut = (Base @in) =&amp;gt; new Base();
        Func&amp;lt;Base, Derived&amp;gt; baseIn_DerivedOut = (Base @in) =&amp;gt; new Derived();

        // Covariance.
        derivedIn_BaseOut = derivedIn_DerivedOut;

        // Contravariance.
        derivedIn_BaseOut = baseIn_BaseOut;

        // Covariance and ontravariance.
        derivedIn_BaseOut = baseIn_DerivedOut;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The in/out keywords also constrains the usage of the decorated type parameter to guarantee the variances. The following generic delegate types are invalid and cannot be compiled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static partial class GenericDelegateWithVariances
{
#if Uncompilable
    // CS1961 Invalid variance: The type parameter &apos;TOut&apos; must be covariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TOut&amp;gt;.Invoke()&apos;. &apos;TOut&apos; is contravariant.
    public delegate TOut Func&amp;lt;in TOut&amp;gt;();

    // CS1961 Invalid variance: The type parameter &apos;TIn&apos; must be contravariantly valid on &apos;GenericDelegateWithVariances.Action&amp;lt;TIn&amp;gt;.Invoke(TIn)&apos;. &apos;TIn&apos; is covariant.
    public delegate void Action&amp;lt;out TIn&amp;gt;(TIn @in);

    // CS1961 Invalid variance: The type parameter &apos;TOut&apos; must be covariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TIn, TOut&amp;gt;.Invoke(TIn)&apos;. &apos;TOut&apos; is contravariant.
    // CS1961 Invalid variance: The type parameter &apos;TIn&apos; must be contravariantly valid on &apos;GenericDelegateWithVariances.Func&amp;lt;TIn, TOut&amp;gt;.Invoke(TIn)&apos;. &apos;TIn&apos; is covariant.
    public delegate TOut Func&amp;lt;out TIn, in TOut&amp;gt;(TIn @in);
#endif
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, it looks in is only for input, and out is only for output. In .NET 4.0+:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace System
{
    public delegate TOut Func&amp;lt;out TOut&amp;gt;();

    public delegate TOut Func&amp;lt;out TOut, in TIn&amp;gt;(TIn @in);

    public delegate TOut Func&amp;lt;out TOut, in TIn1, in TIn2&amp;gt;(TIn1 in1, TIn2 in2);

    public delegate TOut Func&amp;lt;out TOut, in TIn1, in TIn2, in TIn3&amp;gt;(TIn1 in1, TIn2 in2, TIn3 in3);
    
    // ...

    public delegate void Action&amp;lt;in TIn&amp;gt;(TIn @in);

    public delegate void Action&amp;lt;in TIn1, in TIn2&amp;gt;(TIn1 in1, TIn2 in2);

    public delegate void Action&amp;lt;in TIn1, in TIn2, in TIn3&amp;gt;(TIn1 in1, TIn2 in2, TIn3 in3);

    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type parameter is renamed to be more intuitive.&lt;/p&gt;
</content:encoded></item><item><title>Developing ASP.NET MVC Website in Visual Studio</title><link>https://dixin.github.io/posts/developing-asp-net-mvc-website-in-visual-studio/</link><guid isPermaLink="true">https://dixin.github.io/posts/developing-asp-net-mvc-website-in-visual-studio/</guid><description>Sometimes I send ASP.NET MVC project to some senior friends, and ask them for code review. But some of them do not have the Visual Studio ASP.NET MVC add-on installed. So I tried to develop MVC websit</description><pubDate>Sun, 14 Jun 2009 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Developing ASP.NET MVC website in normal Web project&lt;/h2&gt;
&lt;p&gt;Sometimes I send ASP.NET MVC project to some senior friends, and ask them for code review. But some of them do not have the Visual Studio ASP.NET MVC add-on installed. So I tried to develop MVC websites in a normal Web application project, so Visual Studio can run the project without installing ASP.NET MVC add-on.&lt;/p&gt;
&lt;p&gt;The difference is, when removing the code-behind file of ViewPage, the C# generic syntax cannot work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%@ Page Language=&quot;C#&quot; Inherits=&quot;WebOS.Website.Views.ViewPageBase&amp;lt;DesktopViewModel&amp;gt;&quot; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code only works in ASP.NET MVC project. In normal web application project, the CLR syntax is needed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%@ Page Language=&quot;C#&quot; Inherits=&quot;WebOS.Website.Views.ViewPageBase`1[[WebOS.Website.ViewModels.DesktopViewModel, WebOS.Website]]&quot; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way works for developing, debugging, and deploy. And the intellisense also works. &lt;a href=&quot;http://www.coolwebos.com&quot;&gt;CoolWebOS.com&lt;/a&gt; has being developed in this way.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please do notice that, this way works in Visual Studio 2008 and Visual Studio 2008 SP1, but in some builds of 2010, when you press F5, your Visual Studio crashes. To resolve this, in your Web project properties, click the “Web” tab, and choose “Use Local IIS Web server”.&lt;/p&gt;
&lt;h2&gt;Web application project vs. ASP.NET MVC project&lt;/h2&gt;
&lt;p&gt;In the .csproj project files of normal Web project and MVC project, the different is the &amp;lt;ProjectTypeGuids&amp;gt; node.&lt;/p&gt;
&lt;p&gt;In normal Web application project, it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ProjectTypeGuids&amp;gt;{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}&amp;lt;/ProjectTypeGuids&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While in MVC project, it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ProjectTypeGuids&amp;gt;{603c0e0b-db56-11dc-be95-000d561079b0};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}&amp;lt;/ProjectTypeGuids&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An extra GUID {603c0e0b-db56-11dc-be95-000d561079b0} is added to indicate this is an ASP.NET MVC project. So when ASP.NET MVC add-on is not installed for Visual Studio , Visual Studio cannot recognize ASP.NET MVC project.&lt;/p&gt;
&lt;h2&gt;Developing ASP.NET MVC website in Visual Studio 2010&lt;/h2&gt;
&lt;p&gt;ASP.NET MVC is not included in Beta 1 because Beta 1 started locking down before MVC 1.0 shipped. The fore mentioned way can be used to develop ASP.NET MVC website, or you can install &lt;a href=&quot;http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527&quot;&gt;this add-on&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Visual Studio ASP.NET Development Server Does Not Work</title><link>https://dixin.github.io/posts/visual-studio-asp-net-development-server-does-not-work/</link><guid isPermaLink="true">https://dixin.github.io/posts/visual-studio-asp-net-development-server-does-not-work/</guid><description>Recently the ASP.NET development server on my machine could not work. When F5 is pressed in Visual Studio 2008, IE started and displayed “Internet Explorer cannot display the webpage”. This problem na</description><pubDate>Sat, 21 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently the ASP.NET development server on my machine could not work. When F5 is pressed in Visual Studio 2008, IE started and displayed “Internet Explorer cannot display the webpage”. This problem nagged me for a couple of days. I checked a lot of things, including logs, firewall, anti-virus software, project settings, the webdev.webserver.exe process, etc. They did not work. Finally I find my hosts file was somehow modified:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/hosts_70E2D9BD.gif&quot; alt=&quot;hosts&quot; title=&quot;hosts&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once localhost is restored to 127.0.0.1, Visual Studio works.&lt;/p&gt;
</content:encoded></item><item><title>Understanding The Internet File Blocking and Unblocking</title><link>https://dixin.github.io/posts/understanding-the-internet-file-blocking-and-unblocking/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-the-internet-file-blocking-and-unblocking/</guid><description>On Windows XP SP2 + IE 7 and later Windows, files from Internet are marked. Sometimes this feature causes problems.</description><pubDate>Sat, 14 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On Windows XP SP2 + IE 7 and later Windows, files from Internet are marked. Sometimes this feature causes problems.&lt;/p&gt;
&lt;h2&gt;The Problems&lt;/h2&gt;
&lt;p&gt;Today when I started &lt;a href=&quot;http://msdn.microsoft.com/en-us/visualc/aa700831.aspx&quot;&gt;Visual Studio 2008&lt;/a&gt; to run unit tests of &lt;a href=&quot;http://coolwebos.com&quot;&gt;WebOS&lt;/a&gt;, all the tests could not start:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock1_0AB30D94.gif&quot; alt=&quot;file-block-1&quot; title=&quot;file-block-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The message is:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock2_39B5496B.gif&quot; alt=&quot;file-block-2&quot; title=&quot;file-block-2&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Failed to queue test run &apos;Administrator@DIXIN-LAPTOP 2009-03-14 14:05:49&apos;: Test Run deployment issue: The location of the file or directory &apos;e:\work\webos\source\test.website.models\bin\debug\test.website.models.dll.config&apos; is not trusted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To resolve this problem, right click the “not trusted” file, choose “Property”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock3_30790E2A.gif&quot; alt=&quot;file-block-3&quot; title=&quot;file-block-3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and click the “Unblock”. Then the unit tests rocks.&lt;/p&gt;
&lt;p&gt;This is because the code is extracted from a zip file, and the zip file is downloaded from Gmail. Since the zip file from the Internet is blocked, the extracted files are also blocked.&lt;/p&gt;
&lt;p&gt;Another example (not problem) is, if we download a istaller from the Internet, it is also marked as blocked:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock4_63689E91.png&quot; alt=&quot;file-block-4&quot; title=&quot;file-block-4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And so is the chm file:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock5_2BD2DDA3.png&quot; alt=&quot;file-block-5&quot; title=&quot;file-block-5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock6_626088E7.png&quot; alt=&quot;file-block-6&quot; title=&quot;file-block-6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Unblocking is required to browse the chm content.&lt;/p&gt;
&lt;h2&gt;The NTFS alternative data streams&lt;/h2&gt;
&lt;p&gt;This file / directory blocking is provided by default on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows XP SP2 with IE 7&lt;/li&gt;
&lt;li&gt;Later Windows, like Windows Vista&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And marking the file / directory as blocked / unblocked is implemented via alternative data stream feature, which is a feature of NTFS file system. The alternative data streams are just some data like key-value pairs attached on a file or folder.&lt;/p&gt;
&lt;p&gt;In the above scenarios (My machine is Windows Vista + IE 7), since the file WebOS.zip is downloaded from the Gmail attachment, the file is marked by set such key-value pair:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;key (data stream name): Zone.Identifier;&lt;/li&gt;
&lt;li&gt;value (data stream content): [ZoneTransfer] ZoneId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 = trusted;&lt;/li&gt;
&lt;li&gt;2 = intranet;&lt;/li&gt;
&lt;li&gt;3 = Internet;&lt;/li&gt;
&lt;li&gt;4 = untrusted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above alternative data stream can be examined via command line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;more &amp;lt; WebOS.zip:Zone.Identifier
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is how is WebOS.zip file marked as blocked to enhance the security, and a “Unblock” button appears on the property dialog.&lt;/p&gt;
&lt;p&gt;Actually any file / directory marked with this Zone.Identifier alternative data stream is considered from Internet and blocked by the Windows. A test.txt file can be created to test this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo test &amp;gt; test.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;by checking its property, this test.txt is unblocked of course. Now inject the same Zone.Identifier alternative data stream into test.txt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;more &amp;lt; WebOS.zip:Zone.Identifier &amp;gt; test.txt:Zone.Identifier
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By clicking the “Unblock” button, the key-value pair is removed from the file, so the file is treated as unblocked by Windows.&lt;/p&gt;
&lt;p&gt;If the files in the WebOS.zip are extracted without unblocking the WebOS.zip, those file will also have the same alternative data stream, indicating they are from Internet. So they are blocked, just like the above test.website.models.dll.config file.&lt;/p&gt;
&lt;p&gt;For more details of how does NTFS alternative data stream come from and how does it work, please check &lt;a href=&quot;http://en.wikipedia.org/wiki/Fork_(filesystem)&quot;&gt;Wikipedia&lt;/a&gt; and &lt;a href=&quot;http://www.securityfocus.com/infocus/1822&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Remove the Zone.Identifier data stream&lt;/h2&gt;
&lt;p&gt;Several ways can be used to remove the Zone.Identifier data stream to unblock file / directory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure Windows to disable this feature&lt;/li&gt;
&lt;li&gt;Use command lines&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;http://technet.microsoft.com/en-au/sysinternals/bb897440.aspx&quot;&gt;streams.exe&lt;/a&gt; provided in &lt;a href=&quot;http://technet.microsoft.com/en-au/sysinternals/bb842062.aspx&quot;&gt;Sysinternals Suite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Programmatically remove the data stream&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To disable this feature in Windows, go to this place:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/fileblock7_0CEC43F8.png&quot; alt=&quot;file-block-7&quot; title=&quot;file-block-7&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The type command can be used to remove the data streams:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ren WebOS.zip WebOS.zip.bak
type WebOS.zip.bak &amp;gt; WebOS.zip
del WebOS.zip.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the second step, the WebOS.zip.bak&apos;s data streams does not come to WebOS.zip.&lt;/p&gt;
&lt;p&gt;Sometimes we need to bulk unblock files / directories. The &lt;a href=&quot;http://technet.microsoft.com/en-au/sysinternals/bb897440.aspx&quot;&gt;streams.exe&lt;/a&gt; can remove all data streams from a directory recursively. And &lt;a href=&quot;http://www.codeproject.com/KB/cs/ntfsstreams.aspx&quot;&gt;this library&lt;/a&gt; can be used to programmatically remove the data stream. It provides useful extension methods like FileSystemInfo.GetAlternateDataStream(), FileSystemInfo.DeleteAlternateDataStream(), so that these methods can be invoked on both FileInfo and DirectoryInfo.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Globalization;
using System.IO;

using Trinet.Core.IO.Ntfs;

public static class FileInfoExtensions
{
    private const string ZoneIdentifierStreamName = &quot;Zone.Identifier&quot;;

    public static void Unblock(this FileInfo file)
    {
        if (file == null)
        {
            throw new ArgumentNullException(&quot;file&quot;);
        }

        if (!file.Exists)
        {
            throw new FileNotFoundException(&quot;Unable to find the specified file.&quot;, file.FullName);
        }

        if (file.Exists &amp;amp;&amp;amp; file.AlternateDataStreamExists(ZoneIdentifierStreamName))
        {
            file.DeleteAlternateDataStream(ZoneIdentifierStreamName);
        }
    }
}

public static class DirectoryInfoExtensions
{
    private const string ZoneIdentifierStreamName = &quot;Zone.Identifier&quot;;

    public static void Unblock(this DirectoryInfo directory)
    {
        directory.Unblock(false);
    }

    public static void Unblock(this DirectoryInfo directory, bool isRecursive)
    {
        if (directory == null)
        {
            throw new ArgumentNullException(&quot;file&quot;);
        }

        if (!directory.Exists)
        {
            throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, &quot;The specified directory &apos;{0}&apos; cannot be found.&quot;, directory.FullName));
        }

        if (directory.AlternateDataStreamExists(ZoneIdentifierStreamName))
        {
            directory.DeleteAlternateDataStream(ZoneIdentifierStreamName);
        }

        if (!isRecursive)
        {
            return;
        }

        foreach (DirectoryInfo item in directory.GetDirectories())
        {
            item.Unblock(true);
        }

        foreach (FileInfo item in directory.GetFiles())
        {
            item.Unblock();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code has been tested on Windows Vista and Windows Server 2008.&lt;/p&gt;
</content:encoded></item><item><title>Automated Web Testing (2) Using Selenium</title><link>https://dixin.github.io/posts/automated-web-testing-2-using-selenium/</link><guid isPermaLink="true">https://dixin.github.io/posts/automated-web-testing-2-using-selenium/</guid><description>is another automated web application testing framework. Unlike ,</description><pubDate>Sat, 07 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://seleniumhq.org/&quot;&gt;Selenium&lt;/a&gt; is another automated web application testing framework. Unlike &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/02/07/Automated-web-testing-2-Using-Selenium.html&quot;&gt;WatiN&lt;/a&gt;, which has only 3 developers, Selenium is developed by a team of programmers and testers in &lt;a href=&quot;http://www.thoughtworks.com/&quot;&gt;ThoughtWorks&lt;/a&gt;, so that it could be more powerful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The tests can be written as HTML tables or coded in a number of popular programming languages, including C#, Perl, Java, PHP, Python, and Ruby;&lt;/li&gt;
&lt;li&gt;The tests can be run in most modern web browsers, including IE, Firefox, Safari, Opera, Chrome;&lt;/li&gt;
&lt;li&gt;Selenium can be deployed on Windows, Linux, and Macintosh.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Last year, I was using Selenium 1.0 beta1 with a lot of issues found, and sometimes the Java source code has to be manually modified. Now the beta2 is released, working much better than before, with a few issues in &lt;a href=&quot;http://www.apple.com/safari/&quot;&gt;Safari&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;p&gt;Selenium has a couple of components. The &lt;a href=&quot;http://seleniumhq.org/download/&quot;&gt;remote control&lt;/a&gt; is going to be used.&lt;/p&gt;
&lt;p&gt;In the downloaded package, two folders are needed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;selenium-server-1.0-beta-2 is the remote control, which is a server written in Java. It simulates a web server to drive the tested page in order to satisfies the JavaScript &lt;a href=&quot;http://en.wikipedia.org/wiki/Same_origin_policy&quot;&gt;same-origin policy&lt;/a&gt;. And the commands for the tested page are received via Http;&lt;/li&gt;
&lt;li&gt;selenium-dotnet-client-driver-1.0-beta-2 is the client driver containing the .NET assemblies we are going to refer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestselenium1_44889169.gif&quot; alt=&quot;webtest-selenium1&quot; title=&quot;webtest-selenium1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Extract these 2 folders to somewhere, like E:\Software\Selenium.&lt;/p&gt;
&lt;p&gt;Since the remote control is written in Java. We also need to install JRE from &lt;a href=&quot;http://www.java.com/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;First of all, start up server, the remote control. We can create a batch file like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java -jar E:\Software\selenium\selenium-server-1.0-beta-2\selenium-server.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes the java command does not work in Windows Server 2008. To resolve this, please:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;use the full path of your java.exe, like C:\Program Files\Java\jre6\bin\java;&lt;/li&gt;
&lt;li&gt;or add the folder path of java.exe to your PATH environment variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After the server is started, we can see its information:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestselenium2_53DBF378.gif&quot; alt=&quot;webtest-selenium2&quot; title=&quot;webtest-selenium2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then in Visual Studio, add a reference to selenium-dotnet-client-driver-1.0-beta-2\ ThoughtWorks.Selenium.Core.dll, and add a test class “SeleniumTest.cs” to our test project. So that we can write a test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;

using Selenium;

[TestClass]
public class SeleniumTest
{
    private DefaultSelenium _firefox;

    [ClassInitialize]
    public void StartSelenium(TestContext testContext)
    {
        this._firefox = new DefaultSelenium(&quot;localhost&quot;, 4444, @&quot;*firefox&quot;, &quot;http://localhost:4444&quot;);
        this._firefox.Start();
    }

    [TestMethod]
    public void GoogleTest()
    {
        bool hasText;

        this._firefox.Open(&quot;http://www.google.com&quot;);
        this._firefox.Type(&quot;name=q&quot;, &quot;Dixin&quot;);
        this._firefox.Click(&quot;name=btnG&quot;);
        this._firefox.WaitForPageToLoad(&quot;10000&quot;);
        hasText = this._firefox.IsTextPresent(&quot;Dixin&quot;);

        Assert.IsTrue(hasText, @&quot;The search result does not contain text &quot;&quot;Dixin&quot;&quot;.&quot;);
    }

    [TestCleanup]
    public void CloseBrowser()
    {
        this._firefox.Close();
    }

    [ClassCleanup]
    public void StopSelenium()
    {
        this._firefox.Stop();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please notice the port used by the remote control is 4444.&lt;/p&gt;
&lt;p&gt;If the browser does not work, add the path of its folder to the PATH environment viarable, and restart the server.&lt;/p&gt;
&lt;p&gt;You can watch how the remote control and the browser work.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestselenium3_1FC75425.gif&quot; alt=&quot;webtest-selenium3&quot; title=&quot;webtest-selenium3&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;More about Selenium&lt;/h2&gt;
&lt;p&gt;Selenium works very differently from WatiN. &lt;a href=&quot;http://seleniumhq.org/projects/core/reference.html&quot;&gt;Here&lt;/a&gt; is the detailed introduction of Selenium, and &lt;a href=&quot;http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/dotnet/index.html&quot;&gt;here&lt;/a&gt; is the document for the client .NET library.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.hanselman.com/blog/UnitTestingSilverlightWithSelenium.aspx&quot;&gt;Here&lt;/a&gt; is another article on writing unit test for Silverlight using Selenium.&lt;/p&gt;
&lt;h2&gt;Tools for Selenium&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestselenium4_7D8F489E.gif&quot; alt=&quot;webtest-selenium4&quot; title=&quot;webtest-selenium4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://seleniumhq.org/projects/ide/&quot;&gt;Selenium IDE&lt;/a&gt; can be used to record, edit, and debug tests. Selenium IDE includes the entire Selenium Core, can be used to easily record and play back tests in the actual environment that they will run. Selenium IDE is not only recording tool, but a complete IDE.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestselenium5_6D33D0E5.gif&quot; alt=&quot;webtest-selenium5&quot; title=&quot;webtest-selenium5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It can be downloaded from &lt;a href=&quot;http://seleniumhq.org/download/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;WatiN vs. Selenium&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2009/02/07/Automated-web-testing-2-Using-Selenium.html&quot;&gt;WatiN&lt;/a&gt; is easy to use and lightweight enough for .NET developers, while its current problem is to cross browsers. But for Selenium, a Java server has to be used. &lt;a href=&quot;http://www.51testing.com/?146934/action_viewspace_itemid_78808.html&quot;&gt;Here&lt;/a&gt; is a detailed table for the comparison.&lt;/p&gt;
</content:encoded></item><item><title>Automated Web Testing (1) Using WatiN</title><link>https://dixin.github.io/posts/automated-web-testing-1-using-watin/</link><guid isPermaLink="true">https://dixin.github.io/posts/automated-web-testing-1-using-watin/</guid><description>(what-in), stands for Web Application Testing In .NET, is a very easy automated web application testing framework. WatiN is developed in C# for web testing with</description><pubDate>Thu, 05 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://watin.sourceforge.net/&quot;&gt;WatiN&lt;/a&gt; (what-in), stands for Web Application Testing In .NET, is a very easy automated web application testing framework. WatiN is developed in C# for web testing with Internet Explorer and &lt;a href=&quot;http://www.firefox.com&quot;&gt;FireFox&lt;/a&gt;. According to &lt;a href=&quot;http://weblogs.asp.net/scottgu/&quot;&gt;Scott Guthrie&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;… it will give you exactly the experience that you&apos;ll have when a customer hits the site, which ends up being a far more accurate assessment of the application quality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This tutorial shows how to use WatiN in &lt;a href=&quot;http://msdn.microsoft.com/en-us/visualc/aa700831.aspx&quot;&gt;Visual Studio 2008&lt;/a&gt;, while it can also work with other popular test frameworks like &lt;a href=&quot;http://www.nunit.org/&quot;&gt;NUnit&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;p&gt;The current RTM version of WatiN is &lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=167632&amp;amp;package_id=190606&amp;amp;release_id=633278&quot;&gt;1.3&lt;/a&gt;, supporting only IE. The latest 2.0 CTP2 supports both IE and Firefox. Let’s go through 1.3 with IE first.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin1_064284C9.gif&quot; alt=&quot;webtest-watin1&quot; title=&quot;webtest-watin1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After the installing, a couple of libraries should be found in the installation folder. Typically, it is C:\Program Files\WatiN\1.3.0-net-2.0\bin. In most of the scenarios we work with WatiN.Core.dll.&lt;/p&gt;
&lt;h2&gt;Getting started with a console application&lt;/h2&gt;
&lt;p&gt;Create a console application project in Visual Studio, and add a reference to WatiN.Core.dll. Then copy and paste the following code and press F5. It should work immediately.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;

using WatiN.Core;

internal class Program
{
    [STAThread]
    private static void Main()
    {
        // Opens an new Internet Explorer window and goto the Google website.
        IE ie = new IE(&quot;http://www.google.com&quot;);

        // Finds the search text field and type &quot;WatiN&quot; in it.
        ie.TextField(Find.ByName(&quot;q&quot;)).TypeText(&quot;Dixin&quot;);

        // Clicks the Google search button.
        ie.Button(Find.ByValue(&quot;Google Search&quot;)).Click();

        // Finds the &amp;lt;p&amp;gt; which shows the search result statistics.
        Div div = ie.Div(Find.ById(&quot;ssb&quot;));
        Para p = div.Paras[0];
        string result = p.Text;

        // Closes Internet Explorer.
        ie.Close();

        // Writes the statistics text to the console window.
        Console.WriteLine(result);

        Console.Read();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can watch from your screen how the IE works. The related elements will be highlighted when being operated.&lt;/p&gt;
&lt;p&gt;Pay attention to the STAThread attribute for the Main method. &lt;a href=&quot;http://watin.sourceforge.net/apartmentstateinfo.html&quot;&gt;It is requried&lt;/a&gt; because the Thread.Apartmentstate should be set to STA when using WatiN.&lt;/p&gt;
&lt;h2&gt;Working in a Visual Studio test project&lt;/h2&gt;
&lt;p&gt;Now let’s write some real test code. Create a unit test project in Visual Studio; add a new test class &quot;WatiNTest.cs&quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin2_43EF6C85.gif&quot; alt=&quot;webtest-watin2&quot; title=&quot;webtest-watin2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In this test class, write a test method like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;

using WatiN.Core;

[TestClass]
public class WatiNTest
{
    [TestMethod]
    public void GoogleTest()
    {
        bool hasText;

        using (IE ie = new IE())
        {
            ie.GoTo(&quot;http://www.google.com&quot;);
            ie.TextField(Find.ByName(&quot;q&quot;)).TypeText(&quot;Dixin&quot;);
            ie.Button(Find.ByName(&quot;btnG&quot;)).Click();
            hasText = ie.ContainsText(&quot;Dixin&quot;);
        }

        Assert.IsTrue(hasText, @&quot;The search result does not contain text &quot;&quot;Dixin&quot;&quot;.&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this scenario, the STAThread attribute is not required for the test methods.&lt;/p&gt;
&lt;p&gt;Run this unit test, and here is the result in my machine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin3_222393F4.gif&quot; alt=&quot;webtest-watin3&quot; title=&quot;webtest-watin3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we know how to write automated web testing code against web products, no matter the product is built with of ASP.NET Web Form, or it is a rich Ajax application.&lt;/p&gt;
&lt;h2&gt;WatiN with Firefox&lt;/h2&gt;
&lt;p&gt;The 2.0 CTP2 supports Firefox, with a lot of problems of course.&lt;/p&gt;
&lt;p&gt;First of all, download the 2.0 CTP2 package from &lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=167632&amp;amp;package_id=266951&amp;amp;release_id=654071&quot;&gt;here&lt;/a&gt;, and extract the WatiN-2.0.1.754-net-2.0 folder to somewhere, like C:\Program Files\WatiN.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin4_2072C820.gif&quot; alt=&quot;webtest-watin4&quot; title=&quot;webtest-watin4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then, pay attention to the path of Firefox.exe. WatiN uses Firefox.GetExecutablePath() method to find Firefox.exe. For example, I am using a green version of Firefox, so I have to modify the source code to make it return &quot;E:\Software\Firefox\FireFox.exe&quot;, which is the path of my Firefox 3.0.6. If you installed your Firefox normally, you can just ignore this step.&lt;/p&gt;
&lt;p&gt;And an &lt;a href=&quot;http://www.firefox.com&quot;&gt;Firefox&lt;/a&gt; add-on, &lt;a href=&quot;http://www.croczilla.com/jssh&quot;&gt;jssh&lt;/a&gt;, need to be installed. It can be found in the WatiN-2.0.1.754-net-2.0\Mozilla folder. For example, if using &lt;a href=&quot;http://www.firefox.com&quot;&gt;Firefox&lt;/a&gt; 3.0, I should install jssh-WINNT-3.x.xpi.&lt;/p&gt;
&lt;p&gt;The last step is to close all instances of Firefox, or WatiN cannot start it.&lt;/p&gt;
&lt;p&gt;Now create a new console application project, and add a reference to the new WatiN.Core.dll. Then run this test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;

using WatiN.Core;
using WatiN.Core.Mozilla;

internal class Program
{
    [STAThread]
    private static void Main()
    {
        // Opens an new Firefox window and goto the Google website.
        FireFox firefox = new FireFox(&quot;http://www.google.com&quot;);

        // Finds the search text field and type &quot;WatiN&quot; in it.
        firefox.TextField(Find.ByName(&quot;q&quot;)).Value = &quot;Dixin&quot;;

        // Clicks the Google search button.
        firefox.Button(Find.ByValue(&quot;Google Search&quot;)).Click();

        // Finds the &amp;lt;p&amp;gt; which shows the search result statistics.
        string result = string.Empty;
        WatiN.Core.Mozilla.Element div = firefox.Element(Find.ById(&quot;ssb&quot;)) as WatiN.Core.Mozilla.Element;
        if (div != null)
        {
            result = div.ChildNodes[1].Text;
        }

        // Closes Firefox immediately.
        firefox.Dispose();

        // Writes the statistics text to the console window.
        Console.WriteLine(result);

        Console.Read();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a sample folder in the WatiN-2.0.1.754-net-2.0. When trying, exceptions are thrown from CrossBrowserTest.ExecuteTest(). So a Thread.Sleep(5000) has to be added between two Firefox test cases, so that WatiN works.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Simple method
program.SearchForWatiNOnGoogleVerbose();

Thread.Sleep(5000);

// Generic method
program.ExecuteTest(program.SearchForWatiNOnGoogleUsingBaseTest);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Tools for WatiN&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/downloadS/details.aspx?familyid=E59C3964-672D-4511-BB3E-2D5E1DB91038&amp;amp;displaylang=en&quot;&gt;IE Developer Toolbar&lt;/a&gt; should be very helpful to inspect the DOM and find the elements / attributes, like id, which makes coding easier.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin5_1083835C.gif&quot; alt=&quot;webtest-watin5&quot; title=&quot;webtest-watin5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://watintestrecord.sourceforge.net/&quot;&gt;WatiN Test Recorder&lt;/a&gt; is another powerful tool. It runs an IE instance, records the actions, and generates C# test codes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/webtestwatin6_1C38CA8E.gif&quot; alt=&quot;webtest-watin6&quot; title=&quot;webtest-watin6&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;WatiN best practices&lt;/h2&gt;
&lt;p&gt;This article, &quot;&lt;a href=&quot;http://blogs.conchango.com/richardgriffin/archive/2006/11/14/Testing-Design-Pattern-for-using-WATiR_2F00_N.aspx&quot;&gt;WATiN/R Testing Design Pattern&lt;/a&gt;&quot;, described some patterns and practices of WatiN. Another one &quot;&lt;a href=&quot;http://infozerk.com/averyblog/watin-testing-pattern/&quot;&gt;WatiN Testing Pattern&lt;/a&gt;&quot; is simpler. Its basic idea is to encapsulate for each page like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SomePage : IE
{
    // Uri of the page
    private const string Uri = &quot;http://localhost&quot;;

    public SomePage()
        : base(Uri)
    {
    }

    // Elements of the page
    public TextField UserNameTextField
    {
        get
        {
            return this.TextField(Find.ByName(&quot;Username&quot;));
        }
    }

    public TextField PasswordTextField
    {
        get
        {
            return this.TextField(Find.ByName(&quot;Password&quot;));
        }
    }

    public Button LogOnButton
    {
        get
        {
            return this.Button(Find.ByName(&quot;LogOn&quot;));
        }
    }

    // Action of the page
    public void LogOn(string userName, string password)
    {
        this.UserNameTextField.TypeText(userName);
        this.PasswordTextField.TypeText(password);
        this.LogOnButton.Click();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then testing code can be easy and clear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestMethod]
public void SomePageTest()
{
    bool hasText;

    using (SomePage somePage = new SomePage())
    {
        somePage.LogOn(&quot;Dixin&quot;, &quot;Password&quot;);
        hasText = somePage.ContainsText(&quot;Dixin&quot;);
    }

    Assert.IsTrue(hasText, &quot;Message&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The future of WatiN&lt;/h2&gt;
&lt;p&gt;WatiN is one of the easiest web testing frameworks for .NET developers / testers. According to the &lt;a href=&quot;http://watinandmore.blogspot.com/&quot;&gt;official blog&lt;/a&gt;, hopefully after finishing Firefox support, Chrome support will be there very quickly. But I am a little confused with the design of WatiN 2.0.&lt;/p&gt;
</content:encoded></item><item><title>IE7 Still Does Not Like PNG: filter Is Faster Than background</title><link>https://dixin.github.io/posts/ie7-still-does-not-like-png-filter-is-faster-than-background/</link><guid isPermaLink="true">https://dixin.github.io/posts/ie7-still-does-not-like-png-filter-is-faster-than-background/</guid><description>Everyone knows IE 6 does not like PNG images. When a transparent PNG is created as a background image,</description><pubDate>Mon, 22 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Everyone knows IE 6 does not like PNG images. When a transparent PNG is created as a background image,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.webos
{
    background: url(Transparent.png);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IE 6 renders it in a wrong way, which causes a lot of trouble in web design. Here a filter has to be used.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.webos
{
    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=&apos;Contents/Transparent.png&apos;, sizingMethod=&apos;scale&apos;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Filter is more difficult to use. One of the biggest trouble is, in the filter, the path of the png file is not related to the CSS file, but the page using the CSS. Usually we share one CSS file among a lot of pages, and if the pages are in different paths, the filter does not work well.&lt;/p&gt;
&lt;p&gt;For these years, I use the following to display transparent PNG background, which I learnt from Micosoft.com source code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.webos
{
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=&apos;Contents/Transparent.png&apos;, sizingMethod=&apos;scale&apos;);
}
.webos[class] /* Does not work in IE6 */
{
    background:url(Transparent.png);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In IE 7, this bug seems to be fixed. But today when writing WebOS, there is a new trouble. A JavaScript animation is created, a div with a transparent PNG background was resized by JavaScript. This animation ran well in Opera, Firefox and Safari, even smoothly in IE 6. But in IE7, it ran extremely slowly, and caused very high CPU usage. Finally, I found the reason: the high CPU usage was caused by the transparent PNG background.&lt;/p&gt;
&lt;p&gt;I changed the CSS for IE 7 to use filter, then the resizing became as smooth as Firefox!&lt;/p&gt;
&lt;p&gt;So the conclusion is, even the bug of transparent is fixed in IE7, it still has performance problem. Filter is much more effective. In IE7, “filter” should still be preferred rather than “background”.&lt;/p&gt;
</content:encoded></item><item><title>Customizing View Folder Path In ASP.NET MVC Beta</title><link>https://dixin.github.io/posts/customizing-view-folder-path-in-asp-net-mvc-beta/</link><guid isPermaLink="true">https://dixin.github.io/posts/customizing-view-folder-path-in-asp-net-mvc-beta/</guid><description>By default, in an ASP.NET MVC Web application, all ViewPages and ViewUserControls should be placed in the default ~/Vews/ directory. But today some one needs to place them into a custom location.</description><pubDate>Tue, 18 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;By default, in an ASP.NET MVC Web application, all ViewPages and ViewUserControls should be placed in the default ~/Vews/ directory. But today some one needs to place them into a custom location.&lt;/p&gt;
&lt;p&gt;There are already some posts, like &quot;&lt;a href=&quot;http://weblogs.asp.net/stephenwalther/archive/2008/07/23/asp-net-mvc-tip-24-retrieve-views-from-different-folders.aspx&quot;&gt;Retrieve Views from Different Folders&lt;/a&gt;&quot; and &quot;&lt;a href=&quot;http://blog.dotnet-expert.de/2008/07/22/ImplementierenEinesEigenenViewLocatorsF%c3%bcrASPNetMVC.aspx&quot;&gt;Implementieren eines eigenen ViewLocators für ASP.Net MVC&lt;/a&gt;&quot;. The former one specifies a view path in the controller action method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductController : Controller
{
    public ActionResult Index()
    {
        return this.View(@&quot;~\CustomDirectory\Index.aspx&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is, a controller should not know how the views are placed.&lt;/p&gt;
&lt;p&gt;The latter one does not work because it relies on an legacy version of ASP.NET MVC. But it makes more sense. It implements a customized controller factory. When controllers are created, a customized ViewLocator are also created and assigned to controller&apos;s ViewEngine property.&lt;/p&gt;
&lt;p&gt;In the latest beta version of ASP.NET MVC, the ViewLocator is removed. Now a static class ViewEngines is used to manage the ViewEngine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ViewEngines
{
    private readonly static ViewEngineCollection _engines = new ViewEngineCollection 
        {
            new WebFormViewEngine() 
        };

    private readonly static AutoViewEngine _defaultEngine = new AutoViewEngine(_engines);

    public static AutoViewEngine DefaultEngine
    {
        get
        {
            return _defaultEngine;
        }
    }

    public static ViewEngineCollection Engines
    {
        get
        {
            return _engines;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, we will have a instance of WebFormViewEngine, which implemented IViewEngine. Here is the definition of WebFormViewEngine, which looks clear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class WebFormViewEngine : VirtualPathProviderViewEngine
{

    public WebFormViewEngine()
    {
        this.MasterLocationFormats = new string[] 
            {
                &quot;~/Views/{1}/{0}.master&quot;,
                &quot;~/Views/Shared/{0}.master&quot;
            };

        this.ViewLocationFormats = new string[] 
            {
                &quot;~/Views/{1}/{0}.aspx&quot;,
                &quot;~/Views/{1}/{0}.ascx&quot;,
                &quot;~/Views/Shared/{0}.aspx&quot;,
                &quot;~/Views/Shared/{0}.ascx&quot;
            };

        this.PartialViewLocationFormats = this.ViewLocationFormats;
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new WebFormView(partialPath, null);
    }

    protected override IView CreateView(
        ControllerContext controllerContext, string viewPath, string masterPath)
    {
        return new WebFormView(viewPath, masterPath);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what need to do is very simple: just add another customized IViewEngine object to the Engines property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ViewEngines.Engines.Add(new WebFormViewEngine()
    {
        MasterLocationFormats = new string[] 
            {
                &quot;~/CustomDirectory/{1}/{0}.master&quot;,
                &quot;~/CustomDirectory/Shared/{0}.master&quot;
            },

        ViewLocationFormats = new string[] 
            {
                &quot;~/CustomDirectory/{1}/{0}.aspx&quot;,
                &quot;~/CustomDirectory/{1}/{0}.ascx&quot;,
                &quot;~/CustomDirectory/Shared/{0}.aspx&quot;,
                &quot;~/CustomDirectory/Shared/{0}.ascx&quot;
            },

        PartialViewLocationFormats = new string[] 
            {
                &quot;~/CustomDirectory/{1}/{0}.aspx&quot;,
                &quot;~/CustomDirectory/{1}/{0}.ascx&quot;,
                &quot;~/CustomDirectory/Shared/{0}.aspx&quot;,
                &quot;~/CustomDirectory/Shared/{0}.ascx&quot;
            }
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it rocks!&lt;/p&gt;
</content:encoded></item><item><title>.NET Framework 3.5 SP1 Beta Installer</title><link>https://dixin.github.io/posts/net-framework-3-5-sp1-beta-installer/</link><guid isPermaLink="true">https://dixin.github.io/posts/net-framework-3-5-sp1-beta-installer/</guid><description>Today when installing .NET Framework 3.5 SP1 Beta, the installer need to close itself to continue.</description><pubDate>Mon, 30 Jun 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today when installing .NET Framework 3.5 SP1 Beta, the installer need to close itself to continue.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/dot_net_3_5_sp1_bata_2000862E.gif&quot; alt=&quot;dot_net_3_5_sp1_bata&quot; title=&quot;dot_net_3_5_sp1_bata&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Fixing The “jQuery.dequeue is not a function” Error</title><link>https://dixin.github.io/posts/fixing-the-quot-jquery-dequeue-is-not-a-function-quot-error/</link><guid isPermaLink="true">https://dixin.github.io/posts/fixing-the-quot-jquery-dequeue-is-not-a-function-quot-error/</guid><description>Today when using  in , an error occured in both IE an Firefox.  displayed such error mess</description><pubDate>Thu, 10 Jan 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today when using &lt;a href=&quot;http://interface.eyecon.ro/&quot;&gt;interface&lt;/a&gt; in &lt;a href=&quot;http://www.coolwebos.com/&quot;&gt;WebOS&lt;/a&gt;, an error occured in both IE an Firefox. &lt;a href=&quot;http://www.getfirebug.com/&quot;&gt;Firebug&lt;/a&gt; displayed such error message: jQuery.dequeue is not a function.&lt;/p&gt;
&lt;p&gt;This is because interface is a plug-in for &lt;a href=&quot;http://www.jquery.com&quot;&gt;jQuery&lt;/a&gt; 1.1. By checking the &lt;a href=&quot;http://interface.eyecon.ro/interface/interface_1.2.zip&quot;&gt;source code&lt;/a&gt;, it invoked the legacy version of the jQuery.dequeue() method. To work with the latest jQuery, all the invocation code need to be changed. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ifx.js, line 472: jQuery.dequeue(elem, &quot;fx&quot;) should be jQuery(elem).dequeue(&quot;fx&quot;);&lt;/li&gt;
&lt;li&gt;ifxtransfer.js, line 120: jQuery.dequeue(z.el.get(0), &apos;interfaceFX&apos;) should be jQuery(z.el.get(0)).dequeue(&apos;interfaceFX&apos;);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
</content:encoded></item><item><title>Understanding .NET Primitive Types</title><link>https://dixin.github.io/posts/understanding-net-primitive-types/</link><guid isPermaLink="true">https://dixin.github.io/posts/understanding-net-primitive-types/</guid><description>Sometimes symbols like “int” and “Int32” can be confusing for developers beginning to use C# / .NET.</description><pubDate>Thu, 20 Dec 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sometimes symbols like “int” and “Int32” can be confusing for developers beginning to use C# / .NET.&lt;/p&gt;
&lt;h2&gt;int vs. System.Int32&lt;/h2&gt;
&lt;p&gt;Several years ago, I started to learn C# programming. Like many other people, I read some FCL source code from &lt;a href=&quot;http://www.red-gate.com/products/reflector/&quot;&gt;Reflector&lt;/a&gt; in C#. The code of System.Int32 looks confusing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct Int32
{
    internal int m_value;

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;a href=&quot;http://msdn.microsoft.com/&quot;&gt;MSDN&lt;/a&gt; said that &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.80).aspx&quot;&gt;in C#, int is just an alias of System.Int32&lt;/a&gt;, the above code should be equal to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public struct Int32
{
    internal Int32 m_value;

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The confusion is, the fore mentioned code cannot be compiled. As we know, when defining an instance field of a class, the type of the field can be the class itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Class
{
    Class _instanceField;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However for a struct:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;struct Struct
{
    Struct _instanceField;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code cannot be compiled and causes this error message: “Struct member &apos;Struct._instanceField&apos; of type &apos;Struct&apos; causes a cycle in the struct layout”. It looks obvious that the above System.Int32 code should not be compiled.&lt;/p&gt;
&lt;p&gt;Actually, if switching to IL code insteading of C#, or just checking the code with &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/f7dy01k1(VS.80).aspx&quot;&gt;IL Disassembler&lt;/a&gt;, we can see another stuff: int32.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.class public sequential ansi serializable sealed beforefieldinit Int32
    extends System.ValueType
    implements System.IComparable, System.IFormattable, System.IConvertible, System.IComparable`1, System.IEquatable`1
{
    .field assembly int32 m_value

    // Other members.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what is the relationship among int32 (IL), int (C#) and System.Int32 (C#)?&lt;/p&gt;
&lt;h2&gt;How does the integer work&lt;/h2&gt;
&lt;p&gt;int32 is a CLR primitive. Then in FCL, it is represented by System.Int32 struct. The integer value of System.Int32 is persisted on its m_value filed, and a lot of integer-related methods are defined on System.Int32.&lt;/p&gt;
&lt;p&gt;In C#, int is just an alias for System.Int32, supported by the C# compiler. So there is no dependency between int and System.Int32, they are not like &lt;a href=&quot;http://www.cnblogs.com/happyhippy/archive/2007/04/12/710928.aspx&quot;&gt;chicken and egg&lt;/a&gt;. These following code are exactly the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int integer = new int();
System.Int32 integer = new System.Int32();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in the first and second code snippet of this post, the actual type of m_value field is not System.Int32 or int, but the int32 CLR primitive type. “int” appears there because &lt;a href=&quot;http://www.red-gate.com/products/reflector/&quot;&gt;Reflector&lt;/a&gt; tries to use a C# symbol to represent the CLR symbol**.** So only the third code snippet of System.Int32 is telling the truth.&lt;/p&gt;
&lt;p&gt;In C#, there are two kinds of scenarios to use integer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When it is presenting a value, like a local variable, it is compiled into CLR int32 primitive;&lt;/li&gt;
&lt;li&gt;When invoking integer-related method (like int.Parse(), int.ToString(), etc.) on it, it is compiled into the FCL System.Int32 struct (Int32.Parse(), Int32.ToString() are invoked).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Primitive type&lt;/h2&gt;
&lt;p&gt;Now the concept of primitive type should be clearer. In C#, there are byte (alias of System.Byte, its value is represented by uint8 in CLR), short (System.Int16), int (System.Int32), long (System.Int64), char, float, double, bool, decimal, object, string…. they are specially treated and because they are so frequently used.&lt;/p&gt;
&lt;p&gt;For example, one special scenario is, in C#, &lt;a href=&quot;http://www.cnblogs.com/AndersLiu/archive/2007/12/20/1007668.html&quot;&gt;when defining an enum, only primitive is allowed&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum Status : int
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The corresponding FCL type cannot be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum Status : Int32
{
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;More confusions from primitive type and FCL type&lt;/h2&gt;
&lt;p&gt;Actually, all we need to know is that the primitive keyword and FCL type name are representing the same thing.&lt;/p&gt;
&lt;p&gt;Sometimes, I ask questions about primitive types during the &lt;a href=&quot;http://www.cnblogs.com/TeamOne/archive/2009/06/14/csharp_int32.html&quot;&gt;interview&lt;/a&gt;. One typical question is, in C# what is the difference between int and System.Int32? The expected answer is just “The same”. But a lot of people, including some senior guys, told me that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Int32 is 32 bit, while int is 64 bit;&lt;/li&gt;
&lt;li&gt;int is 32 bit integer on 32 bit platform, while it is 64 bit on 64 bit platform;&lt;/li&gt;
&lt;li&gt;int is value type, while System.Int32 is reference type;&lt;/li&gt;
&lt;li&gt;int is allocated in the stack, while System.Int32 is allocated in the heap;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Another similar question is, what is the difference between string and String in C#? There are answers like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;string is value type, while String is reference type;&lt;/li&gt;
&lt;li&gt;string is immutable, while String is mutable;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;p&gt;Maybe some people think these knowledge are not important, I insist understanding basic concepts of programming language should be the first step of professional coding.&lt;/p&gt;
&lt;h2&gt;Related resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/happyhippy/archive/2007/04/12/710928.aspx&quot;&gt;Boolean和bool VS 鸡蛋和鸡&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/szw/archive/2007/12/20/1007493.html&quot;&gt;为《理解C#中的System.In32和int：并非鸡和鸡蛋 》做个续&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/AndersLiu/archive/2007/12/20/1007668.html&quot;&gt;也说System.Int32和int&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/TeamOne/archive/2009/06/14/csharp_int32.html&quot;&gt;int与System.Int32有什么区别&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>The Future Of Web Standards: HTML5</title><link>https://dixin.github.io/posts/the-future-of-web-standards-html5/</link><guid isPermaLink="true">https://dixin.github.io/posts/the-future-of-web-standards-html5/</guid><description>hibernated for years:</description><pubDate>Tue, 11 Dec 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.w3.org/&quot;&gt;W3C&lt;/a&gt; hibernated for years:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTML was last updated in 1999;&lt;/li&gt;
&lt;li&gt;XHTML was last updated in 2002.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://www.whatwg.org/&quot;&gt;WHATWG&lt;/a&gt; (Web Hypertext Application Technology Working Group)was started by &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt;, &lt;a href=&quot;http://www.mozilla.org/&quot;&gt;Mozilla&lt;/a&gt;, &lt;a href=&quot;http://www.apple.com/&quot;&gt;Apple&lt;/a&gt; and &lt;a href=&quot;http://www.opera.com/&quot;&gt;Opera&lt;/a&gt; since in 2004 to develop the next generation of Web markups’ standards. Then they submitted an HTML 5 draft proposal, intending to replace the current HTML and XHTML.&lt;/p&gt;
&lt;p&gt;According to a recent &lt;a href=&quot;http://www.w3.org/2002/09/wbs/40318/htmlbg/results&quot;&gt;voting result&lt;/a&gt; of W3C, the future Web Standards will be HTML 5, not XHTML 2. This vote is based on the &lt;a href=&quot;http://lists.w3.org/Archives/Public/public-html/2007Apr/0429.html&quot;&gt;application&lt;/a&gt; of developing HTML5 as Web Standards.&lt;/p&gt;
&lt;p&gt;So W3C decided to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;accept the HTML5 proposal from WHATWG&lt;/li&gt;
&lt;li&gt;release the next version of HTML as HTML5.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unlike usual W3C working groups before, this group consists of members on behalf of key companies which will lead new Web Standards into practice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ian Hickson (&lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;Dave Hyatt (&lt;a href=&quot;http://www.apple.com/&quot;&gt;Apple&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;Chris Wilson (&lt;a href=&quot;http://www.microsoft.com/&quot;&gt;Microsoft&lt;/a&gt;), also the group lead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instead of &lt;a href=&quot;http://www.ibm.com/developerworks/cn/xml/x-futhtml2.html&quot;&gt;bringing a revolution to HTML like XHTML 2&lt;/a&gt;, WHATWG expects a evolution. Some results from the WHATWG spec has been implemented in some browsers, like &amp;lt;&lt;a href=&quot;http://developer.mozilla.org/en/docs/Canvas_tutorial&quot;&gt;canvas&lt;/a&gt;&amp;gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;http://dev.w3.org/html5/html4-differences/Overview.html&quot;&gt;HTML 5 differences from HTML 4&lt;/a&gt; draft, improvements of HTML 5 can be seen, like changes of grammars, and removed elements and attributes.&lt;/p&gt;
&lt;h2&gt;Grammars&lt;/h2&gt;
&lt;p&gt;HTML 5 can be declared via HTML grammar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
        &amp;lt;title&amp;gt;Sample document&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;p&amp;gt;Sample paragraph&amp;lt;/p&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;as well as XML grammar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&amp;gt;
&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Sample document&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;p&amp;gt;Sample paragraph&amp;lt;/p&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Language features&lt;/h2&gt;
&lt;p&gt;Elements like div, li, etc., become more strict. For example, these elements should not includes block level elements and inline elements. These code are valid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt; 
    &amp;lt;em&amp;gt;...&amp;lt;/em&amp;gt; 
    ...
&amp;lt;/div&amp;gt; 
&amp;lt;div&amp;gt; 
    &amp;lt;p&amp;gt;&amp;lt;em&amp;gt;...&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt; 
    &amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt; 
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the following code is invalid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt; 
    &amp;lt;em&amp;gt;...&amp;lt;/em&amp;gt; 
    &amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt; 
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is helpful to identify the level the elements.&lt;/p&gt;
&lt;h3&gt;Removed elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pure presentation: &amp;lt;basefont&amp;gt;, &amp;lt;big, &amp;lt;center&amp;gt;, &amp;lt;font&amp;gt;, &amp;lt;s&amp;gt;, &amp;lt;strike&amp;gt;, &amp;lt;tt&amp;gt;, &amp;lt;u&amp;gt;;&lt;/li&gt;
&lt;li&gt;Negative for usability: &amp;lt;frame&amp;gt;, &amp;lt;frameset&amp;gt;, noframes&amp;gt;;&lt;/li&gt;
&lt;li&gt;Obscure:&amp;lt;acronym&amp;gt; , &amp;lt;applet&amp;gt;, &amp;lt;isindex&amp;gt;, &amp;lt;dir&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Removed attributes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;accesskey attribute of &amp;lt;a, &amp;lt;area&amp;gt;, &amp;lt;button&amp;gt;, &amp;lt;input&amp;gt;, &amp;lt;label&amp;gt;, &amp;lt;legend&amp;gt; and &amp;lt;textarea&amp;gt;;&lt;/li&gt;
&lt;li&gt;rev and charset attributes of &amp;lt;link and &amp;lt;a&amp;gt;;&lt;/li&gt;
&lt;li&gt;sshape and coords attributes of &amp;lt;a&amp;gt;;&lt;/li&gt;
&lt;li&gt;longdesc attribute of &amp;lt;img and &amp;lt;iframe&amp;gt;;&lt;/li&gt;
&lt;li&gt;target attribute of &amp;lt;link&amp;gt;;&lt;/li&gt;
&lt;li&gt;nohref attribute of &amp;lt;area&amp;gt;;&lt;/li&gt;
&lt;li&gt;profile attribute of &amp;lt;head&amp;gt;;&lt;/li&gt;
&lt;li&gt;version attribute of &amp;lt;html&amp;gt;;&lt;/li&gt;
&lt;li&gt;name attribute of &amp;lt;map&amp;gt;, &amp;lt;img&amp;gt;, &amp;lt;object&amp;gt;, &amp;lt;form&amp;gt;, &amp;lt;iframe&amp;gt;, and &amp;lt;a&amp;gt; (should be replaced id attribute);&lt;/li&gt;
&lt;li&gt;scheme attribute of &amp;lt;meta&amp;gt;;&lt;/li&gt;
&lt;li&gt;archive, classid, codebase, codetype, declare and standby attributes of &amp;lt;object&amp;gt;;&lt;/li&gt;
&lt;li&gt;valuetype and type attributes of &amp;lt;param&amp;gt;;&lt;/li&gt;
&lt;li&gt;charset and language attributes of &amp;lt;script&amp;gt;;&lt;/li&gt;
&lt;li&gt;summary attribute of &amp;lt;table&amp;gt;;&lt;/li&gt;
&lt;li&gt;headers, axis and abbr attributes of &amp;lt;td&amp;gt;, and &amp;lt;th&amp;gt;;&lt;/li&gt;
&lt;li&gt;scope attribute of &amp;lt;td&amp;gt;;&lt;/li&gt;
&lt;li&gt;align attribute of &amp;lt;caption, &amp;lt;iframe&amp;gt;, &amp;lt;img&amp;gt;, &amp;lt;input&amp;gt;, &amp;lt;object&amp;gt;, &amp;lt;legend&amp;gt;, &amp;lt;table&amp;gt;, &amp;lt;hr&amp;gt;, &amp;lt;div&amp;gt;, &amp;lt;h1&amp;gt;, &amp;lt;h2&amp;gt;, &amp;lt;h3&amp;gt;, &amp;lt;h4&amp;gt;, &amp;lt;h5&amp;gt;, &amp;lt;h6&amp;gt;, &amp;lt;p&amp;gt;, &amp;lt;col&amp;gt;, &amp;lt;colgroup&amp;gt;, &amp;lt;tbody&amp;gt;, &amp;lt;td&amp;gt;, &amp;lt;tfoot&amp;gt;, &amp;lt;th&amp;gt;, &amp;lt;thead&amp;gt;, &amp;lt;tr&amp;gt;, and &amp;lt;body&amp;gt;;&lt;/li&gt;
&lt;li&gt;alink, link, text and vlink attributes of &amp;lt;body&amp;gt;;&lt;/li&gt;
&lt;li&gt;background attribute of &amp;lt;body&amp;gt;;&lt;/li&gt;
&lt;li&gt;bgcolor attribute of &amp;lt;table&amp;gt;, &amp;lt;tr, &amp;lt;td, &amp;lt;th&amp;gt;, and &amp;lt;body&amp;gt;;&lt;/li&gt;
&lt;li&gt;border attribute of &amp;lt;table&amp;gt;, &amp;lt;img&amp;gt;, and &amp;lt;object&amp;gt;;&lt;/li&gt;
&lt;li&gt;cellpadding and cellspacing attributes of &amp;lt;table&amp;gt;;&lt;/li&gt;
&lt;li&gt;char and charoff attributes of &amp;lt;col&amp;gt;, &amp;lt;colgroup&amp;gt;, &amp;lt;tbody&amp;gt;, &amp;lt;td&amp;gt;, &amp;lt;tfoot&amp;gt;, &amp;lt;th&amp;gt;, &amp;lt;thead&amp;gt;, and &amp;lt;tr&amp;gt;;&lt;/li&gt;
&lt;li&gt;clear attribute of &amp;lt;br&amp;gt;;&lt;/li&gt;
&lt;li&gt;compact attribute of &amp;lt;dl&amp;gt;, &amp;lt;menu&amp;gt;, &amp;lt;ol&amp;gt;, and &amp;lt;u&amp;gt;;&lt;/li&gt;
&lt;li&gt;frame attribute of &amp;lt;table&amp;gt;;&lt;/li&gt;
&lt;li&gt;frameborder attribute of &amp;lt;iframe&amp;gt;;&lt;/li&gt;
&lt;li&gt;height attribute of &amp;lt;iframe&amp;gt;, &amp;lt;td&amp;gt; and &amp;lt;th&amp;gt;;&lt;/li&gt;
&lt;li&gt;hspace and vspace attributes of &amp;lt;img&amp;gt; and &amp;lt;object&amp;gt;;&lt;/li&gt;
&lt;li&gt;marginheight and marginwidth attributes of &amp;lt;iframe&amp;gt;;&lt;/li&gt;
&lt;li&gt;noshade attribute of &amp;lt;hr&amp;gt;;&lt;/li&gt;
&lt;li&gt;nowrap attribute of &amp;lt;td&amp;gt;, and &amp;lt;th&amp;gt;;&lt;/li&gt;
&lt;li&gt;rules attribute of &amp;lt;table&amp;gt;;&lt;/li&gt;
&lt;li&gt;scrolling attribute of &amp;lt;iframe&amp;gt;;&lt;/li&gt;
&lt;li&gt;size attribute of &amp;lt;hr&amp;gt;, &amp;lt;input&amp;gt;, and &amp;lt;select&amp;gt;;&lt;/li&gt;
&lt;li&gt;style attribute of all elements with the exception of &amp;lt;font&amp;gt;;&lt;/li&gt;
&lt;li&gt;type attribute of &amp;lt;li&amp;gt;, &amp;lt;ol&amp;gt;, and &amp;lt;ul&amp;gt;;&lt;/li&gt;
&lt;li&gt;valign attribute of &amp;lt;col&amp;gt;, &amp;lt;colgroup&amp;gt;, &amp;lt;tbody&amp;gt;, &amp;lt;td&amp;gt;, &amp;lt;tfoot&amp;gt;, &amp;lt;th&amp;gt;, &amp;lt;thead&amp;gt;, and &amp;lt;tr&amp;gt;;&lt;/li&gt;
&lt;li&gt;width attribute of &amp;lt;hr&amp;gt;, &amp;lt;table&amp;gt;, &amp;lt;td&amp;gt;, &amp;lt;th&amp;gt;, &amp;lt;col&amp;gt;, &amp;lt;colgroup&amp;gt;, &amp;lt;iframe&amp;gt;, and &amp;lt;pre&amp;gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently, regarding future compatibility, these removed elements and attributes should be avoided.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ibm.com/developerworks/library/x-futhtml1/?S_TACT=105AGX52&amp;amp;S_CMP=cn-a-x&quot;&gt;The future of HTML, Part 1: WHATWG&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ibm.com/developerworks/xml/library/x-futhtml2.html?S_TACT=105AGX52&amp;amp;S_CMP=cn-a-x&quot;&gt;The future of HTML, Part 2: XHTML 2.0&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.w3.org/html5/html4-differences/Overview.html&quot;&gt;HTML 5 differences from HTML 4&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Customizing IE Scrollbar</title><link>https://dixin.github.io/posts/customizing-ie-scrollbar/</link><guid isPermaLink="true">https://dixin.github.io/posts/customizing-ie-scrollbar/</guid><description>Today someone is asking how to customize the color of IE scrollbar. The following code works for HTML:</description><pubDate>Thu, 22 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today someone is asking how to customize the color of IE scrollbar. The following code works for HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;body
{
    scrollbar-face-color: #E3F1D1;
    scrollbar-highlight-color: #FFFFFF;
    scrollbar-shadow-color: #ABD48F;
    scrollbar-3dlight-color: #D1D7DC;
    scrollbar-arrow-color: #247624;
    scrollbar-track-color: #ededed;
    scrollbar-darkshadow-color: #247624;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But not for XHTML. For XHTML page, it should be like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;html
{
    scrollbar-face-color: #E3F1D1;
    scrollbar-highlight-color: #FFFFFF;
    scrollbar-shadow-color: #ABD48F;
    scrollbar-3dlight-color: #D1D7DC;
    scrollbar-arrow-color: #247624;
    scrollbar-track-color: #ededed;
    scrollbar-darkshadow-color: #247624;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These CSS work in IE 6 and IE 7, and is not supported by Firefox, Opera, Safari. In those browsers, the customized scrollbar has to be emulated. And here are some resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.hesido.com/web.php?page=customscrollbar&quot;&gt;fleXcroll&lt;/a&gt;: Supports keyboard, mouse wheel, and text selection aid;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jools.net/projects/javascript/scrollable-divs/&quot;&gt;Custom Scrollbars&lt;/a&gt;: Based on &lt;a href=&quot;http://www.prototypejs.org/&quot;&gt;Prototype&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://onewww.net/blog/article.asp?id=95&quot;&gt;LinScroll&lt;/a&gt;: Based on &lt;a href=&quot;http://www.jquery.com/&quot;&gt;jQuery&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>document.getElementById() In Browsers</title><link>https://dixin.github.io/posts/document-getelementbyid-in-browsers/</link><guid isPermaLink="true">https://dixin.github.io/posts/document-getelementbyid-in-browsers/</guid><description>For non-form elements, like &lt;div&gt;, etc., document.getElementById() usually works stably, except Opera:</description><pubDate>Fri, 26 Oct 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For non-form elements, like &amp;lt;div&amp;gt;, etc., document.getElementById() usually works stably, except Opera:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div name=&quot;userName&quot;&amp;gt;1&amp;lt;/div&amp;gt;
&amp;lt;div id=&quot;userName&quot;&amp;gt;2&amp;lt;/div&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    alert(document.getElementById(&quot;userName&quot;).innerHTML);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Opera also checks name attribute, so the alerted message is “1”.&lt;/p&gt;
&lt;p&gt;For form elements, IE and Opera have the same behavior:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;text&quot; name=&quot;userName&quot; value=&quot;1&quot; /&amp;gt;
&amp;lt;input type=&quot;text&quot; id=&quot;userName&quot; value=&quot;2&quot; /&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    alert(document.getElementById(&quot;userName&quot;).value);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here IE and Opera alerts “1”.&lt;/p&gt;
&lt;p&gt;Actually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IE 6: Also checks name for form elements;&lt;/li&gt;
&lt;li&gt;IE 7: The same as IE 6;&lt;/li&gt;
&lt;li&gt;Firefox 2.0.0.8: Normal;&lt;/li&gt;
&lt;li&gt;Opera 9.24: Also checks name for any elements;&lt;/li&gt;
&lt;li&gt;Safari 3.0.3: Normal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For complex web pages, it would be good if there is a spec for elements naming.&lt;/p&gt;
</content:encoded></item><item><title>JavaScript: Can document Object Be Optimized?</title><link>https://dixin.github.io/posts/javascript-can-document-object-be-optimized/</link><guid isPermaLink="true">https://dixin.github.io/posts/javascript-can-document-object-be-optimized/</guid><description>In JavaScript, document is a property of window. When access document directly, window.document is accessed. Recently, a colleague demonstrated a way to optimize document, which looks weird:</description><pubDate>Thu, 25 Oct 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In JavaScript, document is a property of window. When access document directly, window.document is accessed. Recently, a colleague demonstrated a way to optimize document, which looks weird:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Accessing _document might be faster than accessing document;
var _document = window.document;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To avoid changing context code accessing document, like document.getElementById() invocation, etc., the above code should be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var document = window.document;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this results an error in most browsers. There is one way to work around:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
    var _document = window.document;
    eval(&quot;var document = _document&quot;);
}
catch (error) { 
}
finally {
    _document = null;
    delete _document;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the test code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&amp;gt;
&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&amp;gt;
        &amp;lt;title&amp;gt;Test document&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div id=&quot;testDocument&quot;&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
            var testDocument = function() {
                var start = new Date();
                for (var i = 0; i &amp;lt; 10000; i++) {
                    document.getElementById(&quot;testDocument&quot;);
                }
                return new Date() - start;
            }

            var time = testDocument();

            try {
                var _document = window.document;
                eval(&quot;var document = _document&quot;); // Fails in Firefox.
            }
            catch (error) {
                // Firefox: &quot;TypeError: Redeclareation of const document&quot;.
            }
            finally {
                _document = null;
                delete _document;
            }

            alert((testDocument() / time * 100) + &quot;%&quot;);
        &amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The alerted message is the rate of the normal document accessing time / “optimized” document accessing time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IE 6: 50%~65%;&lt;/li&gt;
&lt;li&gt;IE 7: 45%~70%;&lt;/li&gt;
&lt;li&gt;Firefox 2.0.0.8: Cannot work in firefox;&lt;/li&gt;
&lt;li&gt;Opera 9.24: 40%~70%;&lt;/li&gt;
&lt;li&gt;Safari 3.0.3: Unstable, sometimes 50%, sometimes 100%, sometimes 200%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am not the developer of Web browsers. If you knows how does this work, please tell me.&lt;/p&gt;
</content:encoded></item><item><title>Confirmed by Microsoft: Cannot Install HD Audio Driver On Windows Server 2003 SP2 / R2</title><link>https://dixin.github.io/posts/confirmed-by-microsoft-cannot-install-hd-audio-driver-on-windows-server-2003-sp2-r2/</link><guid isPermaLink="true">https://dixin.github.io/posts/confirmed-by-microsoft-cannot-install-hd-audio-driver-on-windows-server-2003-sp2-r2/</guid><description>On Winodws Server 2003 SP2 / R2, HD (High Definition) audio driver cannot be installed. This happens for both 32 bit and 64 bit versions of Windows.</description><pubDate>Sun, 14 Oct 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On Winodws Server 2003 SP2 / R2, HD (High Definition) audio driver cannot be installed. This happens for both 32 bit and 64 bit versions of Windows.&lt;/p&gt;
&lt;p&gt;Windows XP SP2 also has problem with HD audio. It can be resolved by installing the famous UAA (Universal Audio Architecture) fix &lt;a href=&quot;http://support.microsoft.com/kb/888111/en-us&quot;&gt;KB888111&lt;/a&gt;. For Winodws Server 2003 SP1, just install the corresponding KB901105. However neither KB888111 nor KB901105 can be installed on Winodws Server 2003 SP2 / R2.&lt;/p&gt;
&lt;p&gt;I search the Web. It is said that this way might work: On Windows Server 2003 SP1, install KB901105, then install HD audio driver, then install SP2. The problem is, my installer is R2, which integrates SP2 and cannot rollback to SP1.&lt;/p&gt;
&lt;p&gt;I called Microsoft China (+86-800-820-3800) for support, the support engineer went and asked the author of KB888111. After several days, and the final answer is confirmed: no solution.&lt;/p&gt;
&lt;p&gt;This problem does not exist in Windows Vista / Windows Server 2008.&lt;/p&gt;
</content:encoded></item><item><title>A Simple CSS hack</title><link>https://dixin.github.io/posts/a-simple-css-hack/</link><guid isPermaLink="true">https://dixin.github.io/posts/a-simple-css-hack/</guid><description>This following hack works for IE6 / IE7 / Firefox:</description><pubDate>Fri, 21 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This following hack works for IE6 / IE7 / Firefox:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.some-class
{
    color: #FF0000 !important; /* For firefox, safari and opera */
    color: #00FF00; /* For ie6 */
}

*html .some-class
{
    color: #0000FF; /* For ie7 */
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Caution! Different Language Versions Of Firefox Renders Differently</title><link>https://dixin.github.io/posts/caution-different-language-versions-of-firefox-renders-differently/</link><guid isPermaLink="true">https://dixin.github.io/posts/caution-different-language-versions-of-firefox-renders-differently/</guid><description>For the same HTML:</description><pubDate>Fri, 21 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For the same HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;file&quot; style=&quot;width:160px;&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Firefox has problem in different language versions:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aspblogs.z22.web.core.windows.net/dixin/Media/firefox_cn_en_6FF8CAEF.gif&quot; alt=&quot;firefox_cn_en&quot; title=&quot;firefox_cn_en&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The top control is the representation in Chinese version of Firefox, which looks fine, but it breaks in the English version Firefox (the second control in the picture).&lt;/p&gt;
&lt;p&gt;So special attention should be paid when testing Web pages in Firefox.&lt;/p&gt;
</content:encoded></item><item><title>Chinese Translation: Truly Understanding ViewState</title><link>https://dixin.github.io/posts/chinese-translation-truly-understanding-viewstate/</link><guid isPermaLink="true">https://dixin.github.io/posts/chinese-translation-truly-understanding-viewstate/</guid><description>Dave Reed has a great article: , and I have translated it into Chinese. Plea</description><pubDate>Wed, 19 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Dave Reed has a great article: &lt;a href=&quot;http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx&quot;&gt;Truly Understanding ViewState&lt;/a&gt;, and I have translated it into Chinese. Please click &lt;a href=&quot;http://www.cnblogs.com/dixin/archive/2007/09/19/understanding-asp_net-viewstate.html&quot;&gt;here to read&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item></channel></rss>