【问题标题】:Invoke method on every object in a list, or pass list of objects to method and return new list?对列表中的每个对象调用方法,或者将对象列表传递给方法并返回新列表?
【发布时间】:2013-09-30 23:04:44
【问题描述】:

这个问题可能太笼统了,所以让我补充一些细节:

我有一个实体对象列表,我需要使用 AutoMapper 将其转换为另一个对象。

我已经有一个方法,它接受一个实体作为参数,并在调用 AutoMapper 的 .Map() 后返回另一个对象

我的问题是哪个更便宜?

-对列表中的每个实体调用我预先存在的方法?

使用类似foreach.Select(x => transformer.transform(x))

-将实体列表传递给执行 foreach 的新方法,然后返回新列表

这有一般规则吗?

【问题讨论】:

  • 我的日常困境!
  • “linq 还是不 linq,这是个问题!”
  • 它们同样不贵。两者都很便宜。注意.Select(x => transformer.transform(x))也可以写成.Select(transformer.transform),那么Func<,>实例会直接引用tranform方法,而不是引用匿名函数。但它同样便宜,在我看来更漂亮。
  • 我始终牢记,调用额外的函数/方法需要额外的时间。
  • @JeppeStigNielsen 感谢您的洞察力!

标签: c# list


【解决方案1】:

您列出的每种方法的开销都非常低。我会选择最易读的,IMO 是Select。否则是premature optimization

IList<NewT> newList = oldList.Select(transformer.transform).ToList();

x =&gt; transformer.transform(x) 在这样的上下文中可以简单地写成transformer.transform,因为该方法与Select 需要的Func&lt;,&gt; 兼容,感谢Jeppe 注意到这里)

但是,如果您分析了您的应用程序并发现您在此 LINQ 代码上花费了大量时间(不仅仅是在transform 部分),最快的方法可能是写出for循环自己(无论是内联还是在其他方法中都无关紧要,我希望 JITter 在运行时内联它,或者有这么小的开销,这无关紧要)。

IList<NewT> newList = new List<NewT>(oldList.Count);
for (int i = 0; i < oldList.Count; i++)
    newList[i] = transformer.transform(oldList[i]);

但是,我发现这不太可能,因为与 LINQ 相比,从数据库中提取实体和自动映射非常缓慢。

【讨论】:

  • +1 用于用已知的Count 初始化new List&lt;&gt;。你也可以使用一个数组(为什么,你把它转换成接口IList&lt;&gt;,所以一个简单的数组就是一个IList&lt;&gt;)。
  • 欣赏洞察力!
【解决方案2】:

您无需遍历要映射的列表。 AutoMapper 能够将一个列表转换为另一个列表。 例如;如果将 TSource 映射到 Tdestination,则可以将 IEnumerable 转换为 IEnumerable。

在这里查看:http://automapper.codeplex.com/wikipage?title=Lists%20and%20Arrays

【讨论】:

  • 感谢自动映射提示!
【解决方案3】:

您的答案似乎将取决于列表的使用 - 您是否会将其视为 IQueryable&lt;T&gt;IEnumerable&lt;T&gt;List&lt;T&gt; - 越接近您需要的具体数组结构清单是,它越贵。如果您可能会使用 LINQ 来减少通过 AutoMapper 转换的调用次数...

那么,你真的想从List&lt;T&gt; 转换为List&lt;T&gt; 是应该指导你的问题。

【讨论】:

    猜你喜欢
    • 2018-08-19
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2013-10-05
    • 1970-01-01
    相关资源
    最近更新 更多