/// Update the property value of the items of the collection.
/// Update the property value of the items of the collection.
/// </summary>
/// </summary>
public static void SetPropertyValue<T>(this IEnumerable<T> items, Action<T> updateMethod)
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
{
foreach (T item in items)
foreach (T item in source)
{
action(item);
updateMethod(item);
}
}
}
public static IEnumerable<T> SetPropertyValue2<T>(this IEnumerable<T> items, Action<T> updateMethod)
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
{
foreach (T item in items)
foreach (T item in source)
{
{
updateMethod(item);
action(item);
yield return item;
yield return item;
}
}
Version du 9 septembre 2024 à 15:34
Disponible à partir de C# 3, elles permettent d'ajouter des méthodes à une classe ou à une structure sans en modifier son code.
Les méthodes doivent être déclarées dans une classe static.
Les méthodes qui étendent une classe ou une structure ne peuvent accéder qu’aux membres publics.
// Déclaration de la méthode d'extension dans une classe staticpublicstaticclassStringExtensions
{
///<summary>/// A Contains method with a comparison type.///</summary>publicstaticboolContains(thisstringsource, stringvalue, StringComparisoncomparisonType)
{
return source.IndexOf(value, comparisonType) >= 0;
}
}
// Utilisation de la méthode d'extension : comparaison de string en ignorant la cassevarmonString = "ASTRINGTOTEST";
monString.Contains("string", StringComparison.OrdinalIgnoreCase);
Useful extension methods
CollectionExtension
CollectionExtension.cs
///<summary>/// Adds each item to the list.///</summary>///<remarks>/// The <see cref="IList{T}" /> interface does not have AddRange in its contract, contrary to the <see cref="List{T}" /> implementation./// The latter uses an optimized routine for adding a range of elements, and naming this extension method AddRange too would give the wrong impression of performance./// Additionally, for collections that notify of their changes, AddRange reads as if there would be only one notification of change after all elements have been added, when in fact there would probably by as many notifications as items being added.///</remarks>publicstaticvoidAddEach<T>(thisICollection<T> collection, IEnumerable<T> elements)
{
ArgumentNullException.ThrowIfNull(collection);
ArgumentNullException.ThrowIfNull(elements);
if (collection is List<T> list)
{
list.AddRange(elements);
}
else
{
foreach (var element in elements)
{
collection.Add(element);
}
}
}
///<summary>/// Removes each item from the list.///</summary>///<remarks>/// This method is not named RemoveRange, because it does not have the same purpose as <see cref="List{T}.RemoveRange" />.///</remarks>publicstaticvoidRemoveEach<T>(thisICollection<T> collection, IEnumerable<T> elements)
{
ArgumentNullException.ThrowIfNull(collection);
ArgumentNullException.ThrowIfNull(elements);
foreach (var element in elements)
{
collection.Remove(element);
}
}
publicstaticvoidRemove<T>(thisICollection<T> collection, Func<T, bool> predicate)
{
ArgumentNullException.ThrowIfNull(collection);
collection.RemoveEach(collection.Where(predicate));
}
publicstaticvoidRemoveSingle<T>(thisICollection<T> collection, Func<T, bool> predicate)
{
ArgumentNullException.ThrowIfNull(collection);
collection.Remove(collection.Single(predicate));
}
IEnumerableExtension
IEnumerableExtension.cs
///<summary>/// Update the property value of the items of the collection.///</summary>publicstaticvoidForEach<T>(thisIEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
publicstaticIEnumerable<T> ForEach<T>(thisIEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
yieldreturn item;
}
}
///<summary>/// Sorts the elements of a sequence according to an element's property.///</summary>publicstaticIEnumerable<T> OrderBy<T>(
thisIEnumerable<T> source,
stringpropertyName,
boolascendingOrder)
{
varpropertyDescriptor = TypeDescriptor.GetProperties(typeof(T))
.Find(propertyName, false);
if (propertyDescriptor == null)
thrownewException($"Property '{propertyName}' not found.");
return ascendingOrder ?
source.OrderBy(x => propertyDescriptor.GetValue(x)) :
source.OrderByDescending(x => propertyDescriptor.GetValue(x));
}