2008-11-10 56 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; 
      } 
     } 
    } 
} 
相關問題