代码之家  ›  专栏  ›  技术社区  ›  SharePoint Newbie

定义IEnumerable<t>的扩展方法,该方法返回IEnumerable<t>?

  •  22
  • SharePoint Newbie  · 技术社区  · 16 年前

    如何定义扩展方法 IEnumerable<T> 哪些回报 IEnumerable<t> ? 目标是使扩展方法对所有人都可用 IEnumerable IEnumerable<t> 哪里 T 不能是匿名类型。

    3 回复  |  直到 10 年前
        1
  •  38
  •   Marc Gravell    16 年前

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

    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 作为一个匿名的类型,这里的寓意是:不要使用 可枚举的 匿名类型。

    有一些稍微复杂一些的场景,其中方法签名使得编译器无法识别 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);
    }
    
        2
  •  3
  •   Howard Pinsley    16 年前
    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;
                }
            }
        }
    }
    
        3
  •  0
  •   Community CDub    8 年前

    这篇文章可以帮助你开始: How do you write a C# Extension Method for a Generically Typed Class . 我不确定这是否正是你想要的,但它可能会让你开始。