c# – 是否有规范方法来“修复”“动态”IEnumerable?

c# – 是否有规范方法来“修复”“动态”IEnumerable?,第1张

概述IEnumerable不保证枚举两次会产生相同的结果.实际上,创建一个示例,其中myEnumerable.First()在执行两次时返回不同的值非常容易: class A { public A(string value) { Value = value; } public string Value {get; set; } }static IEnumerable<A> get IEnumerable不保证枚举两次会产生相同的结果.实际上,创建一个示例,其中myEnumerable.First()在执行两次时返回不同的值非常容易:
class A {    public A(string value) { Value = value; }    public string Value {get; set; } }static IEnumerable<A> getFixedIEnumerable() {    return new A[] { new A("Hello"),new A("World") };}static IEnumerable<A> getDynamicIEnumerable() {    yIEld return new A("Hello");    yIEld return new A("World");}static voID Main(string[] args){    IEnumerable<A> fix = getFixedIEnumerable();    IEnumerable<A> dyn = getDynamicIEnumerable();    Console.Writeline(fix.First() == fix.First()); // true    Console.Writeline(dyn.First() == dyn.First()); // false}

这不仅仅是一个学术性的例子:使用流行的… in …选择新的A(…)将创造这种情况.这可能会导致意外行为:

fix.First().Value = "NEW";Console.Writeline(fix.First().Value); // prints NEWdyn.First().Value = "NEW";Console.Writeline(dyn.First().Value); // prints Hello

我理解为什么会这样.我也知道这可以通过在Enumerable上执行ToList()或通过覆盖==来替代A来解决.这不是我的问题.

问题是:当你编写一个采用任意IEnumerable的方法并且你想要一次只评估序列的属性(然后引用是“固定的”)时,这样做的规范方法是什么? ToList()似乎主要用于,但如果源已经修复(例如,如果源是一个数组),引用将被复制到一个列表(不必要的,因为我需要的只是固定属性).是否有更合适的东西或ToList()这个问题的“规范”解决方案?

解决方法 ToList绝对是最佳选择.

它有一些优化:如果输入枚举是ICollection(例如数组或列表),它将调用ICollection.copyTo将集合复制到数组而不是实际枚举 – 因此除非集合很大,否则成本不太可能很大.

恕我直言,一般来说,大多数方法返回ICollection< T>是更好的.或IList< T>而不是IEnumerable< T>,除非你想向消费者暗示该实现可能使用延迟评估(例如yIEld)的方法.

在方法应该返回不可变列表的情况下,返回只读包装器(ReadonlyCollection< T>),例如,通过调用ToList().AsReadonly(),但仍返回接口类型IList< T>.

如果您遵循此指南,该方法的使用者将不需要对ToList进行不必要的调用.

总结

以上是内存溢出为你收集整理的c# – 是否有规范方法来“修复”“动态”IEnumerable?全部内容,希望文章能够帮你解决c# – 是否有规范方法来“修复”“动态”IEnumerable?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1249447.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存