【问题标题】:Extension method for IEnumerable<T> which returns type of -this-IEnumerable<T> 的扩展方法,它返回 -this- 类型
【发布时间】:2015-02-23 18:18:46
【问题描述】:

如我所见,大多数 IEnumerable 扩展会吃掉 IEnumerable,然后也会吐出 IEnumerable。是否可以制作一个扩展方法,它可以吃任何 IEnumerable(如 List),然后返回相同的类型 - List?

例如,我想遍历collection,如果有问题,我会抛出异常,但如果一切正常,我需要返回相同的实例(相同的类型)。

【问题讨论】:

  • 请注意,您的建议意味着使用 IEnumerable,因此您失去了按需(惰性)迭代和副作用。

标签: c# ienumerable


【解决方案1】:

您需要使用两个通用参数:

public static TEnumerable Foo<TEnumerable, TItem>(this TEnumerable sequence)
    where TEnumerable: IEnumerable<TItem>
{
    return sequence;
}

请注意,由于此更改,您将无法在调用此方法时推断通用参数;您将不得不明确指定它们。

【讨论】:

    【解决方案2】:

    我看不出这样做有什么好处,但您可以像这样解决问题的泛型部分:

    public static TEnumerable MyExtensionMethod<T, TEnumerable>(this TEnumerable enumerable)
        where TEnumerable : IEnumerable<T>
    {
        ...
    }
    

    但是,您可能会发现实际实现这样的事情很困难,因为没有通用的方法来创建您想要返回的TEnumerable

    例如,我想遍历collection,如果有问题,我会抛出异常,但如果一切正常,我需要返回相同的实例(相同的类型)。

    下面的扩展方法不能实现你真正想要的吗?我不明白你为什么要返回同一个实例。

    public static void Consume<T>(this IEnumerable<T> enumerable)
    {
        foreach (var item in enumerable)
        {
            // Do nothing
        }
    }
    

    【讨论】:

    • 根据他的问题,他总是会返回提供的论点。
    • 返回源序列允许链接这个或其他序列操作,而不强制创建局部变量。
    • 所以要调用它,我不得不使用 list.MyExtensionMethod (); ???然后 .Cast();长度几乎相同。
    • @zgnilec 是的,正如我在回答中所说的那样。也就是说,除非您还提供 T 类型的参数或使用 T 作为通用参数。
    • @Servy 是的,我当然明白这是意图。我的观点是,它似乎不适合链式。 “比如我想遍历collection,如果有问题,我会抛出异常,但如果一切正常,我需要返回相同的实例(相同的类型)。” SelectWhere 等已经这样做了——如果被枚举的集合有问题,它们就会抛出。那么为什么要额外的扩展方法,除非它是独立完成的(而不是在调用链中)?
    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 2010-09-27
    相关资源
    最近更新 更多