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: