mirror of
https://github.com/m-lamonaca/dev-notes.git
synced 2025-06-08 10:47:13 +00:00
Rename .NET folder to DotNet
This commit is contained in:
parent
68723844c3
commit
d2148a38ee
32 changed files with 0 additions and 0 deletions
88
DotNet/C#/Async Programming.md
Normal file
88
DotNet/C#/Async Programming.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
# [Async Programming](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/)
|
||||
|
||||
## Task Asynchronous Programming Model ([TAP][tap_docs])
|
||||
|
||||
[tap_docs]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/task-asynchronous-programming-model
|
||||
|
||||
It's possible to avoid performance bottlenecks and enhance the overall responsiveness of an application by using asynchronous programming. However, traditional techniques for writing asynchronous applications can be complicated, making them difficult to write, debug, and maintain.
|
||||
|
||||
C# 5 introduced a simplified approach, **async programming**, that leverages asynchronous support in the .NET Framework 4.5 and higher, .NET Core, and the Windows Runtime. The compiler does the difficult work that the developer used to do, and the application retains a logical structure that resembles synchronous code.
|
||||
|
||||
Asynchrony is essential for activities that are *potentially blocking*, such as web access. Access to a web resource sometimes is slow or delayed. If such an activity is blocked in a synchronous process, the entire application must wait. In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.
|
||||
|
||||
The `async` and `await` keywords in C# are the heart of async programming.
|
||||
|
||||
By using those two keywords, it's possible to use resources in .NET Framework, .NET Core, or the Windows Runtime to create an asynchronous method almost as easily as a synchronous method. Asynchronous methods defined by using the `async` keyword are referred to as **async methods**.
|
||||
|
||||
```cs
|
||||
public async Task<TResult> MethodAsync
|
||||
{
|
||||
Task<TResult> resultTask = obj.OtherMethodAsync();
|
||||
|
||||
DoIndependentWork();
|
||||
|
||||
TResult result = await resultTask;
|
||||
|
||||
// if the is no work to be done before awaiting
|
||||
TResutl result = await obj.OtherMethodAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
Characteristics of Async Methods:
|
||||
|
||||
- The method signature includes an `async` modifier.
|
||||
- The name of an async method, by convention, ends with an "Async" suffix.
|
||||
- The return type is one of the following types:
|
||||
- `Task<TResult>` if the method has a return statement in which the operand has type `TResult`.
|
||||
- `Task` if the method has no return statement or has a return statement with no operand.
|
||||
- `void` if it's an async event handler.
|
||||
- Any other type that has a `GetAwaiter` method (starting with C# 7.0).
|
||||
- Starting with C# 8.0, `IAsyncEnumerable<T>`, for an async method that returns an async stream.
|
||||
|
||||
The method usually includes at least one `await` expression, which marks a point where the method can't continue until the awaited asynchronous operation is complete. In the meantime, the method is suspended, and control returns to the method's caller.
|
||||
|
||||
### Threads
|
||||
|
||||
Async methods are intended to be non-blocking operations. An `await` expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.
|
||||
|
||||
The `async` and `await` keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. It's possible to use `Task.Run` to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.
|
||||
|
||||
The async-based approach to asynchronous programming is preferable to existing approaches in almost every case. In particular, this approach is better than the `BackgroundWorker` class for I/O-bound operations because the code is simpler and there is no need to guard against race conditions.
|
||||
In combination with the `Task.Run` method, async programming is better than `BackgroundWorker` for CPU-bound operations because async programming separates the coordination details of running the code from the work that `Task.Run` transfers to the thread pool.
|
||||
|
||||
### Naming Convention
|
||||
|
||||
By convention, methods that return commonly awaitable types (for example, `Task`, `Task<T>`, `ValueTask`, `ValueTask<T>`) should have names that end with "Async". Methods that start an asynchronous operation but do not return an awaitable type should not have names that end with "Async", but may start with "Begin", "Start", or some other verb to suggest this method does not return or throw the result of the operation.
|
||||
|
||||
## [Async Return Types](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/async-return-types)
|
||||
|
||||
### `Task` return type
|
||||
|
||||
Async methods that don't contain a return statement or that contain a return statement that doesn't return an operand usually have a return type of `Task`. Such methods return `void` if they run synchronously.
|
||||
If a `Task` return type is used for an async method, a calling method can use an `await` operator to suspend the caller's completion until the called async method has finished.
|
||||
|
||||
### `Task<TResult>` return type
|
||||
|
||||
The `Task<TResult>` return type is used for an async method that contains a return statement in which the operand is `TResult`.
|
||||
|
||||
The `Task<TResult>.Result` property is a **blocking property**. If it's accessed it before its task is finished, the thread that's currently active is blocked until the task completes and the value is available. In most cases, access the value by using `await` instead of accessing the property directly.
|
||||
|
||||
### `void` return type
|
||||
|
||||
The `void` return type is used in asynchronous event handlers, which require a `void` return type. For methods other than event handlers that don't return a value, it's best to return a `Task` instead, because an async method that returns `void` can't be awaited. Any caller of such a method must continue to completion without waiting for the called async method to finish. The caller must be independent of any values or exceptions that the async method generates.
|
||||
|
||||
The caller of a void-returning async method *can't catch exceptions thrown from the method*, and such unhandled exceptions are likely to cause the application to fail. If a method that returns a `Task` or `Task<TResult>` throws an exception, the exception is stored in the returned task. The exception is rethrown when the task is awaited. Therefore, make sure that any async method that can produce an exception has a return type of `Task` or `Task<TResult>` and that calls to the method are awaited.
|
||||
|
||||
### Generalized async return types and `ValueTask<TResult>`
|
||||
|
||||
Starting with C# 7.0, an async method can return any type that has an accessible `GetAwaiter` method.
|
||||
|
||||
Because `Task` and `Task<TResult>` are **reference types**, memory allocation in performance-critical paths, particularly when allocations occur in tight loops, can adversely affect performance. Support for generalized return types means that it's possible to return a lightweight **value type** instead of a reference type to avoid additional memory allocations.
|
||||
|
||||
.NET provides the `System.Threading.Tasks.ValueTask<TResult>` structure as a lightweight implementation of a generalized task-returning value. To use the `System.Threading.Tasks.ValueTask<TResult>` type, add the **System.Threading.Tasks.Extensions** NuGet package to the project.
|
||||
|
||||
### Async streams with `IAsyncEnumerable<T>`
|
||||
|
||||
Starting with C# 8.0, an async method may return an async stream, represented by `IAsyncEnumerable<T>`. An async stream provides a way to enumerate items read from a stream when elements are generated in chunks with repeated asynchronous calls.
|
305
DotNet/C#/C# Collections.md
Normal file
305
DotNet/C#/C# Collections.md
Normal file
|
@ -0,0 +1,305 @@
|
|||
# C# Collections
|
||||
|
||||
## Arrays
|
||||
|
||||
An array is an object that contains multiple elements of a particular type. The number of elements is fixed for the lifetime of the array, so it must be specied when the array is created.
|
||||
|
||||
An array type is always a reference type, regardless of the element type. Nonetheless, the choice between reference type and value type elements makes a significant difference in an array’s behavior.
|
||||
|
||||
```cs
|
||||
type[] array = new type[dimension];
|
||||
type array[] = new type[dimension]; //invalid
|
||||
|
||||
type[] array = {value1, value2, ..., valueN}; // initializer
|
||||
var array = new type[] {value1, value2, ..., valueN}; // initializer (var type needs new operator)
|
||||
var array = new[] {value1, value2, ..., valueN}; // initializer w/ element type inference (var type needs new operator), can be used as method arg
|
||||
|
||||
array[index]; // value acces
|
||||
array[index] = value; // value assignement
|
||||
array.Lenght; // dimension of the array
|
||||
|
||||
// from IEnumerable<T>
|
||||
array.OfType<Type>(); // filter array based on type, returns IEnumerable<Type>
|
||||
```
|
||||
|
||||
### [Array Methods](https://docs.microsoft.com/en-us/dotnet/api/system.array?view=netcore-3.1#methods)
|
||||
|
||||
```cs
|
||||
// overloaded search methods
|
||||
Array.IndexOf(array, item); // return index of searched item in passed array
|
||||
Array.LastIndexOf(array, item); // return index of searched item staring from the end of the arrary
|
||||
Array.FindIndex(array, Predicate<T>) // returns the index of the first item matching the predicate (can be lambda function)
|
||||
Array.FindLastIndex(array, Predicate<T>) // returns the index of the last item matching the predicate (can be lambda function)
|
||||
Array.Find(array, Predicate<T>) // returns the value of the first item matching the predicate (can be lambda function)
|
||||
Array.FindLast(array, Predicate<T>) // returns the value of the last item matvhing the predicate (can be lambda function)
|
||||
Array.FindAll(array, Predicate<T>) // returns array of all items matching the predicate (can be lambda function)
|
||||
Array.BinarySearch(array, value) // Searches a SORTED array for a value, using a binary search algorithm; retuns the index of the found item
|
||||
|
||||
Array.Sort(array);
|
||||
Array.Reverse(array); // reverses the order of array elements
|
||||
Array.Clear(start_index, x); //removes reference to x elements starting at start index. Dimension of array uncanged (cleared elements value is set tu null)
|
||||
Array.Resize(ref array, target_dimension); //expands or shrinks the array dimension. Shrinking drops trailing values. Array passed by reference.
|
||||
|
||||
// Copies elements from an Array starting at the specified index and pastes them to another Array starting at the specified destination index.
|
||||
Array.Copy(sourceArray, sourceStartIndex, destinationArray, destinationStartIndex, numItemsToCopy);
|
||||
// Copies elements from an Array starting at the first element and pastes them into another Array starting at the first element.
|
||||
Array.Copy(sourceArray, destinationArray, numItemsToCopy);
|
||||
Array.Clone(); // returns a shallow copy of the array
|
||||
```
|
||||
|
||||
### Multidimensional Arrays
|
||||
|
||||
C# supports two multidimensional array forms: [jagged][jagg_arrays] arrays and [rectangular][rect_arrays] arrays (*matrices*).
|
||||
|
||||
[jagg_arrays]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/jagged-arrays
|
||||
[rect_arrays]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/multidimensional-arrays
|
||||
|
||||
```cs
|
||||
//specify first dimension
|
||||
type[][] jagged = new type[][]
|
||||
{
|
||||
new[] {item1, item2, item3},
|
||||
new[] {item1},
|
||||
new[] {item1, item2},
|
||||
...
|
||||
}
|
||||
|
||||
// shorthand
|
||||
type[][] jagged =
|
||||
{
|
||||
new[] {item1, item2, item3},
|
||||
new[] {item1},
|
||||
new[] {item1, item2},
|
||||
...
|
||||
}
|
||||
|
||||
// matrices
|
||||
type[,] matrix = new type[n, m]; // n * m matrix
|
||||
type[,] matrix = {{}, {}, {}, ...}; // {} for each row to initialize
|
||||
type[, ,] tensor = new type[n, m, o] // n * m * o tensor
|
||||
|
||||
matrix.Length; // total numeber of elements (n * m)
|
||||
matrix.GetLenght(int dimension); // get the size of a particular direction
|
||||
// row = 0, column = 1, ...
|
||||
```
|
||||
|
||||
## [Lists](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1)
|
||||
|
||||
`List<T>` stores sequences of elements. It can grow or shrink, allowing to add or remove elements.
|
||||
|
||||
```cs
|
||||
using System.Collections.Generics;
|
||||
|
||||
List<T> list = new List<T>();
|
||||
List<T> list = new List<T> {item_1, ...}; // initialized usable since list implements IEnumerable<T> and has Add() method (even extension method)
|
||||
List<T> list = new List<T>(dimension); // set list starting dimension
|
||||
List<T> list = new List<T>(IEnumerable<T>); // create a list from an enumerable collection
|
||||
|
||||
|
||||
list.Add(item); //item insertion into the list
|
||||
list.AddRange(IEnumerable<T> collection); // insert multiple items
|
||||
list.Insert(index, item); // insert an item at the specified index
|
||||
list.InsertRange(index, item); // insert items at the specified index
|
||||
|
||||
list.IndexOf(item); // return index of searched item in passed list
|
||||
list.LastIndexOf(item); // return index of searched item staring from the end of the arrary
|
||||
list.FindIndex(Predicate<T>) // returns the index of the first item matching the predicate (can be lambda function)
|
||||
list.FindLastIndex(Predicate<T>) // returns the index of the last item matching the predicate (can be lambda function)
|
||||
list.Find(Predicate<T>) // returns the value of the first item matching the predicate (can be lambda function)
|
||||
list.FindLast(Predicate<T>) // returns the value of the last item matvhing the predicate (can be lambda function)
|
||||
list.FindAll(Predicate<T>) // returns list of all items matching the predicate (can be lambda function)
|
||||
list.BinarySearch(value) // Searches a SORTED list for a value, using a binary search algorithm; retuns the index of the found item
|
||||
|
||||
list.Remove(item); // remove item from list
|
||||
list.RemoveAt(index); // remove item at specified position
|
||||
list.RemoveRange(index, quantity); // remove quantity items at specified position
|
||||
|
||||
list.Contains(item); // check if item is in the list
|
||||
list.TrueForAll(Predicate<T>); // Determines whether every element matches the conditions defined by the specified predicate
|
||||
|
||||
list[index]; // access to items by index
|
||||
list[index] = value; // modify to items by index
|
||||
list.Count; // number of items in the list
|
||||
|
||||
list.Sort(); // sorts item in crescent order
|
||||
list.Reverse(); // Reverses the order of the elements in the list
|
||||
|
||||
// from IEnumerable<T>
|
||||
list.OfType<Type>(); // filter list based on type, returns IEnumerable<Type>
|
||||
list.OfType<Type>().ToList(); // filter list based on type, returns List<Type>
|
||||
```
|
||||
|
||||
## [Iterators](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/iterators)
|
||||
|
||||
An iterator can be used to step through collections such as lists and arrays.
|
||||
|
||||
An iterator method or `get` accessor performs a custom iteration over a collection. An iterator method uses the `yield return` statement to return each element one at a time.
|
||||
When a `yield return` statement is reached, the current location in code is remembered. Execution is restarted from that location the next time the iterator function is called.
|
||||
|
||||
It's possible to use a `yield break` statement or exception to end the iteration.
|
||||
|
||||
**Note**: Since an iteartor returns an `IEnumerable<T>` is can be used to implement a `GetEnumerator()`.
|
||||
|
||||
```cs
|
||||
// simple iterator
|
||||
public static System.Collections.IEnumerable<int> IterateRange(int start = 0, int end)
|
||||
{
|
||||
for(int i = start; i < end; i++){
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## List & Sequence Interfaces
|
||||
|
||||
### [`IEnumerable<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1)
|
||||
|
||||
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
|
||||
|
||||
```cs
|
||||
public interface IEnumerable<out T> : IEnumerable
|
||||
{
|
||||
IEnumerator<T> GetEnumerator(); // retrun an enumerator
|
||||
}
|
||||
|
||||
// iterate through a collection
|
||||
public interface IEnumerator<T>
|
||||
{
|
||||
// properties
|
||||
object Current { get; } // Get the element in the collection at the current position of the enumerator.
|
||||
|
||||
// methods
|
||||
void IDisposable.Dispose(); // Perform application-defined tasks associated with freeing, releasing, or resetting unmanaged resources
|
||||
bool MoveNext(); // Advance the enumerator to the next element of the collection.
|
||||
void Reset(); // Set the enumerator to its initial position, which is before the first element in the collection.
|
||||
}
|
||||
```
|
||||
|
||||
**Note**: must call `Dispose()` on enumerators once finished with them, because many of them rely on this. `Reset()` is legacy and can, in some situations, throw `NotSupportedException()`.
|
||||
|
||||
### [`ICollection<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.icollection-1)
|
||||
|
||||
```cs
|
||||
public interface ICollection<T> : IEnumerable<T>
|
||||
{
|
||||
// properties
|
||||
int Count { get; } // Get the number of elements contained in the ICollection<T>
|
||||
bool IsReadOnly { get; } // Get a value indicating whether the ICollection<T> is read-only
|
||||
|
||||
// methods
|
||||
void Add (T item); // Add an item to the ICollection<T>
|
||||
void Clear (); // Removes all items from the ICollection<T>
|
||||
bool Contains (T item); // Determines whether the ICollection<T> contains a specific value
|
||||
IEnumerator GetEnumerator (); // Returns an enumerator that iterates through a collection
|
||||
bool Remove (T item); // Removes the first occurrence of a specific object from the ICollection<T>
|
||||
}
|
||||
```
|
||||
|
||||
### [`IList<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ilist-1)
|
||||
|
||||
```cs
|
||||
public interface IList<T> : ICollection<T>, IEnumerable<T>
|
||||
{
|
||||
// properties
|
||||
int Count { get; } // Get the number of elements contained in the ICollection<T>
|
||||
bool IsReadOnly { get; } // Get a value indicating whether the ICollection<T> is read-only
|
||||
T this[int index] { get; set; } // Get or set the element at the specified index
|
||||
|
||||
// methods
|
||||
void Add (T item); // Add an item to the ICollection<T>
|
||||
void Clear (); // Remove all items from the ICollection<T>
|
||||
bool Contains (T item); // Determine whether the ICollection<T> contains a specific value
|
||||
void CopyTo (T[] array, int arrayIndex); // Copy the elements of the ICollection<T> to an Array, starting at a particular Array index
|
||||
IEnumerator GetEnumerator (); // Return an enumerator that iterates through a collection
|
||||
int IndexOf (T item); // Determine the index of a specific item in the IList<T>
|
||||
void Insert (int index, T item); // Insert an item to the IList<T> at the specified index
|
||||
bool Remove (T item); // Remove the first occurrence of a specific object from the ICollection<T>
|
||||
oid RemoveAt (int index); // Remove the IList<T> item at the specified index
|
||||
}
|
||||
```
|
||||
|
||||
## `Span<T>`
|
||||
|
||||
```cs
|
||||
t[] array = {...}
|
||||
Span<T> wholeArraySpan = array;
|
||||
Span<T> slice = array[start..end];
|
||||
ReadOnlySpan<T> slice = array[start..end];
|
||||
```
|
||||
|
||||
## [Dictioanaries](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2)
|
||||
|
||||
[ValueCollection](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.valuecollection)
|
||||
[KeyCollection](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.keycollection)
|
||||
|
||||
**Notes**:
|
||||
|
||||
- Enumerating a dictionary will return `KeyValuePair<TKey, TValue>`.
|
||||
- The `Dictionary<TKey, TValue>` collection class relies on hashes to offer fast lookup (`TKey` should have a good `GetHashCode()`).
|
||||
|
||||
```cs
|
||||
Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(); // init empty dict
|
||||
Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(IEqualityComparer<TKey>); // specify key comparer (TKey must implement Equals() and GetHashCode())
|
||||
|
||||
// initializer (implicitly uses Add method)
|
||||
Dictionary<TKey, TValue> dict =
|
||||
{
|
||||
{ key, value }
|
||||
{ key, value },
|
||||
...
|
||||
}
|
||||
|
||||
// object initializer
|
||||
Dictionary<TKey, TValue> dict =
|
||||
{
|
||||
[key] = value,
|
||||
[key] = value,
|
||||
...
|
||||
}
|
||||
|
||||
// indexer access
|
||||
dict[key]; // read value associted with key (throws KeyNotFoundException if key does not exist)
|
||||
dict[key] = value; // modify value associted with key (throws KeyNotFoundException if key does not exist)
|
||||
|
||||
dict.Count; // numer of key-value pair stored in the dict
|
||||
dict.Keys; // Dictionary<TKey,TValue>.KeyCollection containing the keys of the dict
|
||||
dict.Values; // Dictionary<TKey,TValue>.ValueCollection containing the values of the dict
|
||||
|
||||
dict.Add(key, value); // ArgumentException if the key already exists
|
||||
dict.Clear(); // empty the dictionary
|
||||
dict.ContainsKey(key); // check if a key is in the dictionary
|
||||
dict.ContainsValue(value); // check if a value is in the dictionary
|
||||
dict.Remove(key); // remove a key-value pair
|
||||
dict.Remove(key, out var); // remove key-value pair and copy TValue to var parameter
|
||||
dict.TryAdd(key, value); // adds a key-value pair; returns true if pair is added, false otherwise
|
||||
dict.TryGetValue(key, out var); // put the value associated with kay in the var parameter; true if the dict contains an element with the specified key, false otherwise.
|
||||
```
|
||||
|
||||
## [Sets](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1)
|
||||
|
||||
Collection of non duplicate items.
|
||||
|
||||
```cs
|
||||
HashSet<T> set = new HashSet<T>();
|
||||
|
||||
set.Add(T); // adds an item to the set; true if the element is added, false if the element is already present.
|
||||
set.Clear(); //Remove all elements from a HashSet<T> object.
|
||||
set.Contains(T); // Determine whether a HashSet<T> object contains the specified element.
|
||||
set.CopyTo(T[]); // Coy the elements of a HashSet<T> object to an array.
|
||||
set.CopyTo(T[], arrayIndex); // Copy the elements of a HashSet<T> object to an array, starting at the specified array index.
|
||||
set.CopyTo(T[], arrayIndex, count); // Copies the specified number of elements of a HashSet<T> object to an array, starting at the specified array index.
|
||||
set.CreateSetComparer(); // Return an IEqualityComparer object that can be used for equality testing of a HashSet<T> object.
|
||||
set.ExceptWith(IEnumerable<T>); // Remove all elements in the specified collection from the current HashSet<T> object.
|
||||
set.IntersectWith(IEnumerable<T>); // Modify the current HashSet<T> object to contain only elements that are present in that object and in the specified collection.
|
||||
set.IsProperSubsetOf(IEnumerable<T>); // Determine whether a HashSet<T> object is a proper subset of the specified collection.
|
||||
set.IsProperSupersetOf(IEnumerable<T>); // Determine whether a HashSet<T> object is a proper superset of the specified collection.
|
||||
set.IsSubsetOf(IEnumerable<T>); // Determine whether a HashSet<T> object is a subset of the specified collection.
|
||||
set.IsSupersetOf(IEnumerable<T>); // Determine whether a HashSet<T> object is a superset of the specified collection.
|
||||
set.Overlaps(IEnumerable<T>); // Determine whether the current HashSet<T> object and a specified collection share common elements.
|
||||
set.Remove(T); // Remove the specified element from a HashSet<T> object.
|
||||
set.RemoveWhere(Predicate<T>); // Remove all elements that match the conditions defined by the specified predicate from a HashSet<T> collection.
|
||||
set.SetEquals(IEnumerable<T>); // Determine whether a HashSet<T> object and the specified collection contain the same elements.
|
||||
set.SymmetricExceptWith(IEnumerable<T>); // Modify the current HashSet<T> object to contain only elements that are present either in that object or in the specified collection, but not both.
|
||||
set.UnionWith(IEnumerable<T>); // Modify the current HashSet<T> object to contain all elements that are present in itself, the specified collection, or both.
|
||||
set.TryGetValue(T, out T); // Search the set for a given value and returns the equal value it finds, if any.
|
||||
```
|
2879
DotNet/C#/C#.md
Normal file
2879
DotNet/C#/C#.md
Normal file
File diff suppressed because it is too large
Load diff
76
DotNet/C#/LINQ.md
Normal file
76
DotNet/C#/LINQ.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# LINQ
|
||||
|
||||
## LINQ to Objects
|
||||
|
||||
<!-- Page: 423/761 of "Ian Griffiths - Programming C# 8.0 - Build Cloud, Web, and Desktop Applications.pdf" -->
|
||||
|
||||
The term **LINQ to Objects** refers to the use of LINQ queries with any `IEnumerable` or `IEnumerable<T>` collection directly, without the use of an intermediate LINQ provider or API such as [LINQ to SQL](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/) or [LINQ to XML](https://docs.microsoft.com/en-us/dotnet/standard/linq/linq-xml-overview).
|
||||
|
||||
LINQ to Objects will be used when any `IEnumerable<T>` is specified as the source, unless a more specialized provider is available.
|
||||
|
||||
### Query Expressions
|
||||
|
||||
All query expressions are required to begin with a `from` clause, which specifies the source of the query.
|
||||
The final part of the query is a `select` (or `group`) clause. This determines the final output of the query and its sytem type.
|
||||
|
||||
```cs
|
||||
// query expression
|
||||
var result = from item in enumerable select item;
|
||||
|
||||
// where clause
|
||||
var result = from item in enumerable where condition select item;
|
||||
|
||||
// ordering
|
||||
var result = from item in enumerable orderby item.property select item; // ordered IEnumerble
|
||||
|
||||
// let clause, assign expression to variable to avoid re-evaluetion on each cycle
|
||||
var result = from item in enumerable let tmp = <sub-expr> ... // BEWARE: compiled code has a lot of overhead to satisfy let caluse
|
||||
|
||||
// grouping (difficult to re-implement to obtain better performance)
|
||||
var result = from item in enumerable group item by item.property; // returns IEnumerable<IGrouping<TKey,TElement>>
|
||||
```
|
||||
|
||||
### How Query Expressions Expand
|
||||
|
||||
The compiler converts all query expressions into one or more method calls. Once it has done that, the LINQ provider is selected through exactly the same mechanisms that C# uses for any other method call.
|
||||
The compiler does not have any built-in concept of what constitutes a LINQ provider.
|
||||
|
||||
```cs
|
||||
// expanded query expression
|
||||
var result = Enumerable.Where(item => condition).Select(item => item);
|
||||
```
|
||||
|
||||
The `Where` and `Select` methods are examples of LINQ operators. A LINQ operator is nothing more than a method that conforms to one of the standard patterns.
|
||||
|
||||
### Methods on `Enumerable` or `IEnumerable<T>`
|
||||
|
||||
```cs
|
||||
Enumerable.Range(int start, int end); // IEnumerable<int> of values between start & end
|
||||
|
||||
IEnumerable<TSource>.Select(Func<TSource, TResult> selector) // map
|
||||
IEnumerable<TSource>.Where(Func<T, bool> predicate) // filter
|
||||
|
||||
IEnumerable<T>.FirstOrDefault() // first element of IEnumerable or default(T) if empty
|
||||
IEnumerable<T>.FirstOrDefault(Func<T, bool> predicate) // first element to match predicate or default(T)
|
||||
|
||||
// T must implement IComparable<T>
|
||||
IEnumerable<T>.Max();
|
||||
IEnumerable<T>.Min();
|
||||
|
||||
IEnumerable<T>.All(Func<T, bool> predicate); // check if condition is true for all elements
|
||||
IEnumerable<T>.Any(Func<T, bool> predicate); // check if condition is true for at least one element
|
||||
|
||||
IEnumerable<T>.Concat(IEnumerable<T> enumerable);
|
||||
|
||||
// Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results.
|
||||
IEnumerable<TFirst>.Zip(IEnumerable<TSecond> enumerable, Func<TFirst, TSecoind, TResult> func);
|
||||
IEnumerable<TFirst>.Zip(IEnumerable<TSecond> enumerable); // Produces a sequence of tuples with elements from the two specified sequences.
|
||||
```
|
||||
|
||||
**NOTE**: `Enumerable` provides a set of `static` methods for querying objects that implement `IEnumerable<T>`. Most methods are extensions of `IEnumerable<T>`
|
||||
|
||||
```cs
|
||||
Enumerable.Method(IEnumerable<T> source, args);
|
||||
// if extension method same as
|
||||
IEnumerable<T>.Method(args)
|
||||
```
|
39
DotNet/C#/Reactive Extensions.md
Normal file
39
DotNet/C#/Reactive Extensions.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Reactive Extensions (Rx)
|
||||
|
||||
The **Reactive Extensions** for .NET, or **Rx**, are designed for working with asynchro‐nous and event-based sources of information.
|
||||
Rx provides services that help orchestrate and synchronize the way code reacts to data from these kinds of sources.
|
||||
|
||||
Rx’s fundamental abstraction, `IObservable<T>`, represents a sequence of items, and its operators are defined as extension methods for this interface.
|
||||
|
||||
This might sound a lot like LINQ to Objects, and there are similarities, not only does `IObservable<T>` have a lot in common with `IEnumerable<T>`, but Rx also supports almost all of the standard LINQ operators.
|
||||
|
||||
The difference is that in Rx, sequences are less passive. Unlike `IEnumerable<T>`, Rx sources do not wait to be asked for their items, nor can the consumer
|
||||
of an Rx source demand to be given the next item. Instead, Rx uses a *push* model in which *the source notifies* its recipients when items are available.
|
||||
|
||||
Because Rx implements standard LINQ operators, it's possible to write queries against a live source. Rx goes beyond standard LINQ, adding its own operators that take into account the temporal nature of a live event source.
|
||||
|
||||
## Foundamental Interfaces
|
||||
|
||||
The two most important types in Rx are the `IObservable<T>` and `IObserver<T>` interfaces. They are important enough to be in the System namespace.
|
||||
The other parts of Rx are in the `System.Reactive` NuGet package.
|
||||
|
||||
```cs
|
||||
public interface IObservable<out T>
|
||||
{
|
||||
IDisposable Subscribe(IObserver<T> observer);
|
||||
}
|
||||
|
||||
public interface IObserver<in T>
|
||||
{
|
||||
void OnCompleted();
|
||||
void OnError(Exception error);
|
||||
void OnNext(T value);
|
||||
}
|
||||
```
|
||||
|
||||
The fundamental abstraction in Rx, `IObservable<T>`, is implemented by *event sources*. Instead of using the `event` keyword, it models events as a *sequence of items*. An `IObservable<T>` provides items to subscribers as and when it’s ready to.
|
||||
|
||||
It's possible to subscribe to a source by passing an implementation of `IObserver<T>` to the `Subscribe` method.
|
||||
The source will invoke `OnNext` when it wants to report events, and it can call `OnCompleted` to indicate that there will be no further activity.
|
||||
If the source wants to report an error, it can call `OnError`.
|
||||
Both `OnCompleted` and `OnError` indicate the end of the stream, an observable should not call any further methods on the observer after that.
|
66
DotNet/C#/Unit Testing.md
Normal file
66
DotNet/C#/Unit Testing.md
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Unit Testing
|
||||
|
||||
## MSTest
|
||||
|
||||
[Microsoft Unit Testing Tutorial](https://docs.microsoft.com/en-us/visualstudio/test/walkthrough-creating-and-running-unit-tests-for-managed-code?view=vs-2019)
|
||||
|
||||
To test a project add a **MSTest Test Projet** to the solution.
|
||||
|
||||
The test runner will execute any methods marked with `[TestInitialize]` once for every test the class contains, and will do so before running the actual test method itself.
|
||||
The `[TestMethod]` attribute tells the test runner which methods represent tests.
|
||||
|
||||
In `TestClass.cs`:
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Project.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class TestClass
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethod()
|
||||
{
|
||||
Assert.AreEqual(expected, actual);
|
||||
Assert.IsTrue(bool);
|
||||
Assert.IsFalse(bool);
|
||||
Assert.IsNotNull(nullable);
|
||||
|
||||
// assertions on collections
|
||||
CollectionAssert.AreEqual(expexcted, actual),
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[UnitTest Overloaded Methods](https://stackoverflow.com/a/5666591/8319610)
|
||||
[Naming standards for unit tests](https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html)
|
||||
|
||||
## xUnit
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Project.Tests
|
||||
{
|
||||
public class ClassTest
|
||||
{
|
||||
[Fact]
|
||||
public void TestMethod()
|
||||
{
|
||||
Assert.Equal(expected, actual); // works on collections
|
||||
Assert.True(bool);
|
||||
Assert.False(bool);
|
||||
Assert.NotNull(nullable);
|
||||
|
||||
// Verifies that all items in the collection pass when executed against action
|
||||
Assert.All<T>(IEnumerable<T> collection, Action<T> action);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue