C# 
- Extensões para IEnumerable
    
    ![]()  | 
    Hoje vou apresentar algumas extensões para a interface IEnumerable. | 
Na linguagem C#, IEnumerable continua sendo uma interface fundamental no .NET para representar uma sequência de elementos e fornece um mecanismo para iterar sobre esses elementos de forma genérica.
A interface IEnumerable define um método chamado GetEnumerator() que permite percorrer sequencialmente os elementos da coleção usando um iterador.
Ela é amplamente utilizada para representar e manipular coleções de elementos e permite a iteração sobre uma sequência de elementos, seja uma lista, um array, uma consulta LINQ ou qualquer outra estrutura de dados que implemente a interface IEnumerable.
Podemos estender as funcionalidades de IEnumerable por meios de métodos de extensão de forma bem simples.
A seguir vou apresentar alguns métodos de extensão de IEnumerable:
1- Extensão para verificar se uma sequência está vazia
| 
		public
		static
		bool
		IsEmpty<T>(this 
		IEnumerable<T> source) { foreach (var item in source) { return false; } return true; }  | 
	
Uso:
| 
		using 
		CSharpExtensionsIEnumerable; List< int> numeros = new List<int> { 1, 2, 3, 4, 5 };bool isEmpty = numeros.IsEmpty(); | 
	
2 - Extensão para filtrar elementos de uma sequência com base em um predicado
| 
		public
		static 
		IEnumerable<T> Filter<T>(this 
		IEnumerable<T> source, Func<T, 
		bool> 
		predicate) { foreach (var item in source) { if (predicate(item)) { yield return item; } } }  | 
	
Uso:
| 
		List<int> 
		numeros = new 
		List<int> 
		{ 1, 2, 3, 4, 5 }; IEnumerable< int> numerosFiltrados = numeros.Filter(x => x % 2 == 0);// Resultado: 2, 4  | 
	
3 - Extensão para converter uma sequência em um dicionário usando uma chave seletora
| 
		public
		static 
		Dictionary<TKey, TValue> ToDictionaryExt<T,
		TKey,
		 TValue>(this IEnumerable<T> source, Func<T, TKey> keySelector, Func<T, TValue> valueSelector) { var dictionary = new Dictionary<TKey, TValue>(); foreach (var item in source) { var key = keySelector(item); var value = valueSelector(item); dictionary[key] = value; } return dictionary; }  | 
	
Uso:
| 
		List<int> 
		numeros = new 
		List<int> 
		{ 1, 2, 3, 4, 5 }; Dictionary<int, string> dicionario = numeros.ToDictionaryExt(x => x, x => $"Item {x}"); // Resultado: { 1: "Item 1" }, { 2: "Item 2" }, { 3: "Item 3" }, { 4: "Item 4" }, { 5: "Item 5" }  | 
	
4- Extensão para verificar se um tipo é nulo ou vazio
| 
		public
		static
		bool 
		IsNullOrEmpty<T>(this 
		IEnumerable<T>? source) { return source is null || !source.Any(); }  | 
	
Uso:
| 
		 var result1 = Enumerable.Empty<int>().IsNullOrEmpty(); //true var result2 = new[] { 1, 2, 3 }.IsNullOrEmpty(); // false var result3 = ((IEnumerable<int>)null).IsNullOrEmpty(); // true  | 
	
5- Extensão para particionar duas coleções
| 
		public
		static 
		(IEnumerable<T1>, IEnumerable<T2>)  Partition<T1, T2>(this IEnumerable<T1> source1, IEnumerable<T2> source2, int size) { ArgumentNullException.ThrowIfNull(source1); ArgumentNullException.ThrowIfNull(source2); var partition1 = source1.Take(size); var partition2 = source2.Take(size); return (partition1, partition2); }  | 
	
Essa extensão de método Partition recebe duas coleções de tipos diferentes (source1 e source2) e um parâmetro size que define o tamanho de cada partição.
Ela retorna um par de sequências particionadas, uma para source1 e outra para source2, onde cada sequência tem o tamanho especificado por size.
Uso:
| List<int> 
		inteiros = 
		new List<int> 
		{ 1, 2, 3, 4, 5 }; List<string> frutas = new List<string> { "caju", "maça", "jaca", "kiwi", "uva" }; var particoes = inteiros.Partition(frutas, 3);// Resultado: particoes.Item1 = { 1, 2, 3 }, particoes.Item2 = { "caju", "maça", "jaca" }  | 
	
6- Extensão para calcular a mediana de uma lista de números
| 
		public
		static
		double 
		Mediana<T>(this 
		IEnumerable<T> source) 
		where 
		T : IComparable<T> { var sortedList = source.OrderBy(x => x).ToList(); int count = sortedList.Count; if (count == 0) throw new InvalidOperationException("A lista está vazia."); int mid = count / 2; if (count % 2 == 0) { T value1 = sortedList[mid - 1]; T value2 = sortedList[mid]; return Convert.ToDouble(Convert.ToDouble(value1) + Convert.ToDouble(value2)) / 2; } else { return Convert.ToDouble(sortedList[mid]); } }  | 
	
Uso:
| 
		using 
		CSharpExtensionsIEnumerable; List< int> numeros = new List<int> { 4, 8, 15, 16, 23, 42 };double mediana = numeros.Mediana();// Resultado: 15.5 List< double> valores = new List<double> { 2.5, 4.7, 6.1, 8.2, 10.9 };double medianaDouble = valores.Mediana(); // Resultado: 6.1  | 
	
Essa extensão de método calcula a mediana ordenando a lista e selecionando o 
valor do meio ou a média dos dois valores do meio, dependendo se a contagem da 
lista é ímpar ou par. É importante notar que a lista deve ser numérica e que o 
tipo T deve implementar a interface 
IComparable<T>
Segue o código das extensões : CSharpExtensionsIEnumerable.zip
E estamos conversados.
![]()
"Em tudo somos atribulados, mas não angustiados; perplexos, mas não desanimados.
Perseguidos, mas não desamparados; abatidos, mas não destruídos;
Trazendo 
sempre por toda a parte a mortificação do Senhor Jesus no 
corpo, para que a 
vida de Jesus se manifeste também no nosso corpo;"
2 Coríntios 4:8-10
Referências: