-1

我想做一个 convertAll 通用的函数,比如

public static Iout ConvertAll<Iin, Iout, T, TOutput>(this Iin source, Converter<T, TOutput> converter)
        where Iin : IEnumerable<T>
        where Iout : IEnumerable<TOutput>
    {
        foreach (var item in source)
            yield return converter(item);
    }

问题是视觉工作室告诉我:

'Sgd.CollectionExtensions.ConvertAll(Iin, System.Converter)' 的主体不能是迭代器块,因为 'Iout' 不是迭代器接口类型

问题是我有 where 子句,所以它应该像迭代器一样被识别,不是吗?

我也尝试:

public static I<TOutput> ConvertAll<I, T, TOutput>(this I<T> source, Converter<T, TOutput> converter)
        where I : IEnumerable
    {
        foreach (var item in source)
            yield return converter(item);
    }

但它说

类型参数“I”不能与类型参数一起使用

所以我不知道该怎么办。我不想要这样的功能:

public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> source, Converter<T, TOutput> converter)
    {
        foreach (var item in source)
            yield return converter(item);
    }

它更简单并且可以正常工作,但是它返回一个 IEnumerable 并且我希望输出中的迭代器与输入中的迭代器相同

希望你能帮助我谢谢

4

1 回答 1

2

因此,假设您希望输出为List. List<T>实现IEnumerable<T>。您在哪里定义新列表的创建?您在哪里定义如何将新项目添加到列表中?

你不是。

yield return表示构造的类将实现IEnumerable<T>or IEnumerator<T>。这就是它知道如何构建的全部内容。您可以接受除 之外的其他内容的输入IEnumerable<T>。例如,您可以接受 的输入List<T>。但话又说回来,即使使用最后一个函数(你不喜欢的那个)你也可以这样做,你不需要使用早期的语法来获得那个功能。

您可以为您需要的两个操作添加额外的委托参数(或者实际上是一个,因为您可以为创建添加通用约束)。

public static TOut ConvertAll<TIn, TOut, T, TOutput>(this TIn source
    , Converter<T, TOutput> converter
    , Action<TOut, TOutput> adder)
    where TIn : IEnumerable<T>
    where TOut : IEnumerable<TOutput>, new()
{
    TOut output = new TOut();
    foreach (var item in source)
        adder(output, converter(item));
    return output;
}

请注意,尽管如此,您已经失去了所有延迟执行。

于 2013-08-15T19:41:36.093 回答