gpt4 book ai didi

c# - 为返回 IEnumerable 的 IEnumerable 定义扩展方法?

转载 作者:IT王子 更新时间:2023-10-29 04:29:45 25 4
gpt4 key购买 nike

如何为 IEnumerable<T> 定义扩展方法返回 IEnumerable<T> ?目标是使扩展方法可用于所有 IEnumerableIEnumerable<T>其中 T可以是匿名类型。

最佳答案

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

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”,它把方法变成一个迭代器 block ,编译器生成一个枚举器(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 (当然你不能为匿名类型指定它)。在这些情况下,通常可以重构为编译器可以用于推理的不同签名(可能通过直通方法),但您需要将实际代码发布到在这里提供答案。


(更新)

经过讨论,这是一种利用 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);
}

关于c# - 为返回 IEnumerable<T> 的 IEnumerable<T> 定义扩展方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/277150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com