For the complete documentation index, see llms.txt. This page is also available as Markdown.

Collection Extensions

Enumerable, CollectionUtility, DictionaryUtility, and collection extension methods.

Collection extension types provide a set of low-level utility methods for handling synchronous/asynchronous enumeration, reflective collection operations, dictionary conversions, key-value pair construction, and synchronization packaging.

Type Relationship

Type
Description

Enumerable

Synchronous/asynchronous enumeration adaptation, empty enumeration, single value enumeration and typed enumeration.

CollectionUtility

Perform reflective Add and Remove on unknown collection objects.

DictionaryUtility

Perform reflective Add, Remove and key extraction on unknown dictionary objects.

KeyValuePairExtension

Create an array of key-value pairs and convert between an array of key-value pairs and an array of objects.

DictionaryExtension

Dictionary reading, conversion, synchronization packaging and enumeration to dictionary items.

HashSetExtension

Copy HashSet<T> Source as an array.

ListUtility

Wrap IList<T> Source as SynchronizedList<T>.

Enumerable

Enumerable mainly handles the scenario where "the object may be a value, a synchronous enumeration, or an asynchronous enumeration".

Source: framework/Zongsoft.Core/test/Collections/EnumerableTest.cs (excerpt; see source for context).

EnumerableTest.cs
public async Task EnumerateAdapters_PrioritizeCollectionsAndConvertScalarValues()
{
	var items = new List<int>([1, 2]);
	var syncObjects = Enumerable.Enumerate<object>(items);
	var asyncObjects = Enumerable.EnumerateAsync<object>(items);
	var syncDecimals = Enumerable.Enumerate<decimal>(10);
	var asyncDecimals = Enumerable.EnumerateAsync<decimal>(10);

	Assert.Collection(syncObjects,
		item => Assert.Equal(1, item),
		item => Assert.Equal(2, item));
	Assert.Collection(await CollectAsync(asyncObjects),
		item => Assert.Equal(1, item),
		item => Assert.Equal(2, item));
	Assert.Equal([10m], syncDecimals);
	Assert.Equal([10m], await CollectAsync(asyncDecimals));
}

Common capabilities include:

  • Empty(Type): Creates an empty enumeration by runtime type.

  • Empty<T>(): Creates an empty asynchronous enumeration.

  • First<T>(), FirstOrDefault<T>(): Get the first element asynchronously, and pass the cancellation and release enumerators; the former throws an exception when the sequence is empty, and the latter returns the default value of the element type. For actual usage of Discussions, see Asynchronous query.

  • Asynchronize<T>(): Wrap synchronous enumeration into asynchronous enumeration.

  • Synchronize<T>(): Convert asynchronous enumeration to blocking synchronous enumeration.

  • Enumerate<T>(object): Convert the object to IEnumerable<T> Source.

  • EnumerateAsync<T>(object): Convert the object to IAsyncEnumerable<T> Source.

These methods preferentially identify synchronous or asynchronous collections as sequences, and only non-collection objects are type-converted according to single values; single-value enumerators only borrow the object, and releasing the enumerator does not release the element itself.

Asynchronize<T> and EnumerateAsync<T> only perform enumeration form adaptation and will not arrange synchronized enumeration to background threads. After the asynchronous enumerator receives the cancellation mark, it will throw OperationCanceledException Source; when EnumerateAsync<T> receives both method-level and enumerator-level cancellation marks, either cancellation will terminate the enumeration. Synchronize<T> will block the current thread waiting for asynchronous enumeration. await foreach should be used directly in the asynchronous call chain.

When the source sequence implements IPageable, the adaptation results of Asynchronize<T>, EnumerateAsync<T> and Synchronize<T> continue to implement IPageable, and forward the dynamic Suppressed state and Paginated event; the event sender is the outer result object held by the caller.

CollectionUtility

CollectionUtility is used in scenarios where the target object type is undefined, but may implement ICollection<T> Source or the non-generic IList Source.

Source: framework/Zongsoft.Core/test/Collections/CollectionTest.cs (excerpt; see source for context).

It will try to convert the incoming value to the collection element type, and then call the corresponding Add or Remove.

DictionaryUtility

DictionaryUtility is used in scenarios where the target object type is undefined, but may implement IDictionary<TKey, TValue> Source or the non-generic IDictionary Source.

Source: framework/Zongsoft.Core/test/Collections/DictionaryTest.cs (excerpt; see source for context).

TryGetEntry can extract keys and values from DictionaryEntry Source or KeyValuePair<TKey, TValue> Source.

Dictionary Expansion

DictionaryExtension provides TryGetValue, dictionary type conversion and synchronization wrappers for non-generic dictionaries.

These extensions can only be used by reflection calls such as data service and configuration binding. See DictionaryExtension source code for specific conversion rules.

A generic dictionary can be wrapped by Synchronize into SynchronizedDictionary<TKey, TValue>.

Key-value Pairs and Hash Set Extensions

KeyValuePairExtension.CreatePairs can create a key-value pair array based on a key name array and a value array.

When a key-value pair needs to be constructed, the key array and value array must be organized in the same order; see KeyValuePairExtension source code for their length check and combination method.

HashSetExtension.ToArray will create a new array and call HashSet<T>.CopyTo, which is suitable for scenarios that require array snapshots.

Last updated