2008-11-10 89 views

回答

33

写任何迭代器的最简单的方法是使用迭代器块,例如:

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

这里的关键是“yield return”,它变成该方法进入迭代器块,与编译器产生统计员(IEnumerator<T>)也是如此。当被调用时,泛型类型推断自动处理T,所以你只需要:

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

以上可以用匿名类型就好使用。

您可以课的,请指定T,如果你想(只要它不是匿名):

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

重新IEnumerable(非通用),那么,最简​​单的方法是为呼叫者先使用.Cast<T>(...).OfType<T>(...)先得到IEnumerable<T>。您可以在上面传入this IEnumerable,但调用者必须自己指定T,而不是让编译器推断它。你不能在T是匿名类型的情况下使用它,所以这里的道德是:不要使用具有匿名类型的非通用形式IEnumerable

有一些稍微复杂的方案,其中方法签名是这样的,编译器无法识别T(当然,您不能为匿名类型指定它)。在这些情况下,通常可以重新编入一个不同的签名,编译器可以使用进行推理(也许通过pass-thru方法),但是您需要发布实际代码以提供答案。


(更新)

经过讨论,这里是利用Cast<T>匿名类型的方式。关键是要提供一个可用于类型推断的参数(即使参数从未使用过)。例如:

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); 
} 
+0

与不使用参数的方法似乎只是错误的。 – 2008-11-10 22:20:24

+2

它*是*使用....只是由编译器,而不是运行时; - – 2008-11-11 05:23:17

2
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; 
      } 
     } 
    } 
} 
相关问题