作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对以下 linq except 行为感到非常惊讶,有人可以解释为什么吗?我列出了我对 linq 工作原理的理解/假设。至少其中一个是错误的。
public class Obj {
public string Name;
public Obj(string name)
{
this.Name = name;
}
}
class Program
{
public static void Main(string[] args)
{
var list1 = "a,b"
.Split(',')
.Select(x => new Obj(x));
var list2 = list1.Where(x => x.Name == "b");
var list3 = list1.Except(list2).ToList();
}
}
但显然,事实并非如此。在调试器中检查时,list3 包含 {Obj('a'), Obj('b')},并且这些对象不是 list1 所包含内容的引用。并且 Obj 构造函数被调用了 4 次。
linq Where 和 Excet 方法不应该只是将对象引用从一个 IEnumerable 复制到另一个 IEnumerable 吗?谁在创建对象副本?
最佳答案
问题是您的列表并不是真正的列表——它们是惰性求值序列。当这段代码执行时:
var list1 = "a,b"
.Split(',')
.Select(x => new Obj(x));
... Split
被立即调用,然后 Where
被调用以在该数组上设置延迟计算序列。如果您根本不遍历 list1
,则不会创建 Obj
的实例。如果多次遍历 list1
,每次都会获得新对象。
要使代码正常工作,您需要做的就是通过转换为列表(或者数组也可以)具体化查询:
var list1 = "a,b"
.Split(',')
.Select(x => new Obj(x))
.ToList();
或者,您可以覆盖 Obj
中的 Equals
和 GetHashCode
,这样 Except
就会考虑不同但-适本地相等对象。
关于c# - 令人惊讶的 linq 除了行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57567298/
我是一名优秀的程序员,十分优秀!