对于某些人来说,这可能是一个基本问题,但它会影响我设计一个程序的方式。
我有一个类型为A的集合:
IEnumerable<A> myCollection;
我按照两个不同的标准过滤我的收藏:
IEnumerable<A> subCollection1 = myCollection.Where(x => x.Count > 10);
etc.
现在,我知道.Where表达式将返回IEnumerable的新实例,但是新集合是否包含对'myCollection'引用的类型A实例的相同引用,或者是否创建了类型A的新副本?如果创建了类型为“A”的新实例,是否可以说“subCollection1”引用与“myCollection”引用相同的A实例?
编辑:添加进一步说明。
我正在寻找一种方法,以便当我对'subCollection1'中的'A'实例进行更改时,它也会针对'myCollection'进行修改。
答案 0 :(得分:42)
如果它们是类,则实例相同,但如果它们是结构/值类型则复制。
int,byte和double是value types,结构(如System.Drawing.Point
和自定义结构)也是如此。
但是字符串,你自己的所有类,基本上都是“其余的”,都是reference types。
注意:LINQ使用与所有其他任务相同的规则。
对象:
Person p1 = new Person();
p1.Name = "Mr Jones";
Person p2 = p1;
p2.Name = "Mr Anderssen";
// Now p1.Name is also "Mr Anderssen"
结构:
Point p1 = new Point();
p1.x = 5;
Point p2 = p1;
p2.x = 10;
// p1.x is still 5
使用LINQ时适用相同的规则。
答案 1 :(得分:12)
实际上这取决于收藏品。在某些情况下,Linq方法可以返回克隆对象而不是对原始文件的引用,请看一下这个测试:
[Test]
public void Test_weird_linq()
{
var names = new[]{"Fred", "Roman"};
var list = names.Select(x => new MyClass() { Name = x });
list.First().Name = "Craig";
Assert.AreEqual("Craig", list.First().Name);
}
public class MyClass
{
public string Name { get; set; }
}
即使很多人认为在“list.First()”中会返回相同的对象,但是这个测试会失败,但是如果你使用“用ToList()修改的另一个集合”,它将会起作用
var list = names.Select(x => new MyClass() { Name = x }).ToList();
我不知道为什么它会以这种方式工作,但是在编写代码时需要注意的事项:)
答案 2 :(得分:9)
它们是相同的对象。 Where
仅过滤,Select
生成(可生成)新实例。
答案 3 :(得分:1)
制作一个作为参考类型的新对象并非易事。 LINQ不知道该怎么做。在处理引用类型时,LINQ总是返回相同的实例。
答案 4 :(得分:0)
我只想添加其他一些答案 - 一般来说,当我不确定某些东西但需要特定行为时,我会为它添加一个单元测试。您可以轻松地将其置于测试中,然后检查是否相等,这将告诉您是否正在查看原始容器中对象的引用。有些人可能认为这是愚蠢的,因为你“应该只知道”会发生什么,但对我来说,我知道我要么1)不确定,因为我不是一个很棒的程序员,2)总是有我需要燃烧的夜晚午夜的油,最好让人放心,你需要的东西就像你需要的那样。