如何定义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的扩展方法<Enum>?
- 2. 返回IEnumerable的<dynamic>从方法
- 3. Linq返回IEnumerable <T>
- 4. 无扩展主题为<IEnumerable的<Obj>>以主题为<IEnumerable的<AggregatedObj >>
- 5. 通用扩展方法返回的IEnumerable <T>不使用反射
- 6. IEnumerable <T>作为返回类型
- 7. IEnumerable - 我的扩展方法
- 8. 扩展方法上的IEnumerable
- 9. 如何将IEnumerable <IEnumerable <IGrouping <int,string> >>转换为IEnumerable <IEnumerable <string>>
- 10. 无法从IEnumerable <T>转换为IEnumerable <T>
- 11. IEnumerable的总和方法扩展<TimeSpan>
- 12. 如何编写泛型IEnumerable <SelectListItem>扩展方法
- 13. 如何将IEnumerable <IEnumerable <T>>转换为IEnumerable <T>
- 14. 平展IEnumerable <IEnumerable <>>;了解泛型
- 15. 分组IEnumerable <IEnumerable <int>>
- 16. 从IEnumerable <IEnumerable <T>>
- 17. 铸造IEnumerable <Derived> IEnumerable <BaseClass>
- 18. IEnumerable <IEnumerable <T>> to string [] []
- 19. 什么时候必须为IEnumerable扩展方法指定类型<T>?
- 20. 从IEnumerable获取泛型GetOnlyKeys的C#扩展方法<KeyValuePair <int, string>>
- 21. Lambda扩展方法转换IEnumerable <T>到列表<SelectListItem>
- 22. 返回列表<object>自IEnumerable C#
- 23. 如何使用ADO.NET返回IEnumerable <>?
- 24. 更好的方式来使用IEnumerable <IEnumerable <string>>
- 25. 如何测试返回IEnumerable的方法<int>?
- 26. 如何将IEnumerable <IEnumerable <Foo>>减少到IEnumerable <Foo>?
- 27. IEnumerable的<IEnumerable的<T>>到的IEnumerable <T>使用LINQ
- 28. 如何将List <IEnumerable <ProductViewModel >>转换为<IEnumerable <ProductViewModel >>?
- 29. 集合<T>:它为什么既实现IEnumerable又实现IEnumerable <T>?
- 30. 为什么ICollection <T>实现IEnumerable <T>和IEnumerable
与不使用参数的方法似乎只是错误的。 – 2008-11-10 22:20:24
它*是*使用....只是由编译器,而不是运行时; - – 2008-11-11 05:23:17