IEnumerable<T>.ConvertAll & DDD

n8w*_*wrl 2 ienumerable domain-driven-design

I have an interesting need for an extension method on the IEumerable interface - the same thing as List.ConvertAll. This has been covered before here and I found one solution here. What I don't like about that solution is he builds a List to hold the converted objects and then returns it. I suspect LINQ wasn't available when he wrote his article, so my implementation is this:

public static class IEnumerableExtension
{
    public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> collection, Func<T, TOutput> converter)
    {
        if (null == converter)
            throw new ArgumentNullException("converter");

        return from item in collection
               select converter(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢这个是我无需加载任何TOutput的整个列表即可"转换".请注意,我还更改了委托的类型 - 从Converter到Func.编译是一样的,但我认为它使我的意图更清晰 - 我不是故意这只是类型转换.

这引出了我的问题:在我的存储库层中,我有很多查询返回ID的列表 - 实体的ID.我曾经有过几个类,它们以各种方式将这些ID"转换"为实体.使用这种扩展方法,我可以将所有这些简化为代码,如下所示:

IEnumerable<Part> GetBlueParts()
{
    IEnumerable<int> keys = GetBluePartKeys();
    return keys.ConvertAll<Part>(PartRepository.Find);
}
Run Code Online (Sandbox Code Playgroud)

其中'转换器'实际上是存储库的Find-by-ID方法.就我而言,'转换器'可能会做很多事情.有没有人看到这种方法有任何问题?

Ree*_*sey 10

我用这种方法看到的主要问题是完全没必要.

您的ConvertAll方法Enumerable.Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)与标准LINQ运算符没什么区别.没有理由为框架中已有的东西编写扩展方法.

你可以这样做:

IEnumerable<Part> GetBlueParts() 
{ 
    IEnumerable<int> keys = GetBluePartKeys(); 
    return keys.Select<int,Part>(PartRepository.Find); 
} 
Run Code Online (Sandbox Code Playgroud)

注意:您的方法也需要<int,Part>编译,除非PartRepository.Find只适用于int,并且只返回Part实例.如果你想避免这种情况,你可以这样做:

IEnumerable<Part> GetBlueParts() 
{ 
    IEnumerable<int> keys = GetBluePartKeys(); 
    return keys.Select(i => PartRepository.Find<Part>(i)); // I'm assuming that fits your "Find" syntax...
} 
Run Code Online (Sandbox Code Playgroud)