如何定義IEnumerable<T>
的擴展方法,它返回IEnumerable<T>
? 目標是使擴展方法適用於所有IEnumerable
和IEnumerable<T>
,其中T
可以是匿名類型。爲IEnumerable定義擴展方法<T>它返回IEnumerable <T>?
20
A
回答
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
這篇文章可能會幫助您開始:How do you write a C# Extension Method for a Generically Typed Class。我不確定它是否正是你正在尋找的東西,但它可能會讓你開始。
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;
}
}
}
}
相關問題
- 1. 產量返回IEnumerable <IEnumerable <...>>
- 2. IEnumerable的擴展方法<Enum>?
- 3. 返回IEnumerable的<dynamic>從方法
- 4. Linq返回IEnumerable <T>
- 5. 將IEnumerable <T>與IEnumerable比較IEnumerable <IEnumerable <T>>
- 6. 無擴展主題爲<IEnumerable的<Obj>>以主題爲<IEnumerable的<AggregatedObj >>
- 7. 通用擴展方法返回的IEnumerable <T>不使用反射
- 8. IEnumerable <T>作爲返回類型
- 9. 爲什麼IEnumerable的<T>被定義爲IEnumerable <out T>,不IEnumerable的<T>
- 10. IEnumerable - 我的擴展方法
- 11. IQueryable與IEnumerable ...擴展方法
- 12. 擴展方法上的IEnumerable
- 13. 如何將IEnumerable <IEnumerable <IGrouping <int,string> >>轉換爲IEnumerable <IEnumerable <string>>
- 14. Moq:返回值作爲IEnumerable的值傳入方法<T>
- 15. 的IEnumerable <T>作爲返回類型WCF方法
- 16. 無法從IEnumerable <T>轉換爲IEnumerable <T>
- 17. 如何編寫泛型IEnumerable <SelectListItem>擴展方法
- 18. IEnumerable的總和方法擴展<TimeSpan>
- 19. 如何將IEnumerable <IEnumerable <T>>轉換爲IEnumerable <T>
- 20. 平展IEnumerable <IEnumerable <>>;瞭解泛型
- 21. 鑄造IEnumerable <Derived> IEnumerable <BaseClass>
- 22. 從IEnumerable <IEnumerable <T>>
- 23. 分組IEnumerable <IEnumerable <int>>
- 24. IEnumerable <IEnumerable <T>> to string [] []
- 25. 什麼時候必須爲IEnumerable擴展方法指定類型<T>?
- 26. 曖昧的IQueryable <T>。凡和IEnumerable <T>。凡在擴展方法
- 27. 單的擴展方法<K,IEnumerable的/ IList的/ ICollection的<V>>
- 28. Lambda擴展方法轉換IEnumerable <T>到列表<SelectListItem>
- 29. 從IEnumerable獲取泛型GetOnlyKeys的C#擴展方法<KeyValuePair <int, string>>
- 30. 返回列表<object>自IEnumerable C#
與不使用參數的方法似乎只是錯誤的。 – 2008-11-10 22:20:24
它*是*使用....只是由編譯器,而不是運行時; - – 2008-11-11 05:23:17