定义一个扩展方法的IEnumerable< T>它返回的IEnumerable< T&GT ;? [英] Define an Extension Method for IEnumerable<T> which returns IEnumerable<T>?

查看:169
本文介绍了定义一个扩展方法的IEnumerable< T>它返回的IEnumerable< T&GT ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何定义下一个扩展方法IEnumerable&; T> 返回的IEnumerable< T>
的目标是使可用于所有的扩展方法的IEnumerable 的IEnumerable< T> ,其中 T 可以是匿名类型。

How do I define an Extension Method for IEnumerable<T> which returns IEnumerable<T>? The goal is to make the Extension Method available for all IEnumerable and IEnumerable<T> where T can be an anonymous type.

推荐答案

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

The easiest way to write any iterator is with an iterator block, for example:

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



这里的关键是收益回报率,果然方法到迭代器块,与编译器生成一个枚举( 的IEnumerator< T>) 。调用时,泛型类型推断处理 T 自动,所以你只需要:

The key here is the "yield return", which turns the method into an iterator block, with the compiler generating an enumerator (IEnumerator<T>) that does the same. When called, generic type inference handles the T automatically, so you just need:

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



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

The above can be used with anonymous types just fine.

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

You can, of coure, specify the T if you want (as long as it isn't anonymous):

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



RE 的IEnumerable (非通用),好了,最简单的方法是调用者使用 .Cast< T>(...) .OfType< T>(... )来获得的IEnumerable< T> 第一。你可以通过在本的IEnumerable 在上面,但主叫方必须指定 T 自己,而不是让编译器推断它。你不能用 T 是一个匿名类型使用,所以这里的寓意是:不要使用的非一般形式的IEnumerable 匿名类型。

Re IEnumerable (non-generic), well, the simplest approach is for the caller to use .Cast<T>(...) or .OfType<T>(...) to get an IEnumerable<T> first. You can pass in this IEnumerable in the above, but the caller will have to specify T themselves, rather than having the compiler infer it. You can't use this with T being an anonymous type, so the moral here is: don't use the non-generic form of IEnumerable with anonymous types.

有一些稍微复杂的场景中方法签名是这样的编译器不能识别 T (当然你不能指定它为匿名类型)。在这种情况下,通常可能重新因素纳入不同的签名,编译器的可以的推断与使用(可能通过一个直通法),但你需要张贴实际的代码来在这里提供的答案。

There are some slightly more complex scenarios where the method signature is such that the compiler can't identify the T (and of course you can't specify it for anonymous types). In those cases, it is usually possible to re-factor into a different signature that the compiler can use with inference (perhaps via a pass-thru method), but you'd need to post actual code to provide an answer here.


(更新)

经过讨论,这里有一个办法,把杠杆演员LT; T> 匿名类型。关键是要提供一种可用于该类型推断(即使从未使用的参数)的参数。例如:

Following discussion, here's a way to leverage Cast<T> with anonymous types. The key is to provide an argument that can be used for the type inference (even if the argument is never used). For example:

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

这篇关于定义一个扩展方法的IEnumerable&LT; T&GT;它返回的IEnumerable&LT; T&GT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆