read explained example c# .net extension-methods

explained - read ienumerable c#



Definir un método de extensión para IEnumerable<T> que devuelve IEnumerable<T>? (3)

La forma más fácil de escribir cualquier iterador es con un bloque iterador, por ejemplo:

static IEnumerable<T> Where<T>(this IEnumerable<T> data, Func<T, bool> predicate) { foreach(T value in data) { if(predicate(value)) yield return value; } }

La clave aquí es el " yield return ", que convierte el método en un bloque de iteradores, con el compilador generando un enumerador ( IEnumerator<T> ) que hace lo mismo. Cuando se invoca, la inferencia de tipo genérico maneja la T automáticamente, por lo que solo necesita:

int[] data = {1,2,3,4,5}; var odd = data.Where(i=>i%2 != 0);

Lo anterior se puede usar con tipos anónimos bien.

Puede, de acuerdo, especificar la T si lo desea (siempre que no sea anónimo):

var odd = data.Where<int>(i=>i%2 != 0);

Re IEnumerable (no genérico), bueno, el enfoque más simple es que la persona que llama use .Cast<T>(...) o .OfType<T>(...) para obtener un IEnumerable<T> primero. Puede pasar this IEnumerable en el punto anterior, pero el que llama tendrá que especificar T sí mismo, en lugar de que el compilador lo infiera. No puede usar esto con T siendo un tipo anónimo, por lo que la moraleja es: no use la forma no genérica de IEnumerable con tipos anónimos.

Hay algunos escenarios ligeramente más complejos en los que la firma del método es tal que el compilador no puede identificar el T (y, por supuesto, no puede especificarlo para los tipos anónimos). En esos casos, generalmente es posible volver a factorizar en una firma diferente que el compilador puede usar con la inferencia (quizás a través de un método de paso directo), pero necesitaría publicar el código actual para proporcionar una respuesta aquí.

(actualizado)

Tras la discusión, aquí hay una forma de aprovechar Cast<T> con tipos anónimos. La clave es proporcionar un argumento que pueda usarse para la inferencia de tipo (incluso si el argumento nunca se usa). Por ejemplo:

static void Main() { IEnumerable data = new[] { new { Foo = "abc" }, new { Foo = "def" }, new { Foo = "ghi" } }; var typed = data.Cast(() => new { Foo = "never used" }); foreach (var item in typed) { Console.WriteLine(item.Foo); } } // note that the template is not used, and we never need to pass one in... public static IEnumerable<T> Cast<T>(this IEnumerable source, Func<T> template) { return Enumerable.Cast<T>(source); }

¿Cómo puedo definir un Método de extensión para IEnumerable<T> que devuelve IEnumerable<T> ? El objetivo es hacer que el Método de extensión esté disponible para todo IEnumerable e IEnumerable<T> donde T puede ser de tipo anónimo.


using System; using System.Collections.Generic; namespace ExtentionTest { class Program { static void Main(string[] args) { List<int> BigList = new List<int>() { 1,2,3,4,5,11,12,13,14,15}; IEnumerable<int> Smalllist = BigList.MyMethod(); foreach (int v in Smalllist) { Console.WriteLine(v); } } } static class EnumExtentions { public static IEnumerable<T> MyMethod<T>(this IEnumerable<T> Container) { int Count = 1; foreach (T Element in Container) { if ((Count++ % 2) == 0) yield return Element; } } } }