如何在c#中使用linq/lambda获得数据的副本而不是引用

本文关键字:数据 副本 引用 lambda linq | 更新日期: 2023-09-27 18:19:19

是否有一种简单的方法基本上只是获得数据的副本,而不是使用此方法的引用?我尝试了。toarray (). where(),但这似乎仍然传递一个引用。

的例子:

static void Main(string[] args)
{
    List<ob> t = new List<ob>();
    t.Add(new ob() { name = "hello" });
    t.Add(new ob() { name = "test" });
    ob item = t.Where(c => c.name == "hello").First();
    // Changing the name of the item changes the original item in the list<>
    item.name = "burp";
    foreach (ob i in t)
    {
        Console.WriteLine(i.name);
    }
    Console.ReadLine();
}
public class ob
{
    public string name;
}

如何在c#中使用linq/lambda获得数据的副本而不是引用

您需要自己创建ob的副本- LINQ不提供。

您可以在现有的protected MemberwiseClone方法的基础上定义一个Clone方法:

public class Item
{
    public Item Clone()
    {
        return (Item)this.MemberwiseClone();
    }
}

:

ob item = t.Where(c => c.name == "hello").First().Clone();

由于ob是一个类,它是一个引用类型,因此ob的任何实例,当分配给不同的变量时(就像在ob item = t.Where(c => c.name == "hello").First();行中发生的那样)将自动将引用复制到原始实例,而不是复制实际实例本身。这是一个关于对象复制的通用。net主题,与LINQ/Lambda,

为了实现你想要的,你需要从你的LINQ投影中创建一个结果实例的浅拷贝或深拷贝。

对于你的ob类,一个浅拷贝就足够了(浅拷贝通常尽可能少地复制,而DeepCopy复制一切 -一个很好的参考差异可以在这里找到)。

要执行对象的ShallowCopy,您可以使用MemberwiseClone,这是一个. net对象类型的内置方法,由所有对象继承。

对于更重要的东西,您必须实现自己的DeepCopy函数,但这可能相对简单。类似于这里和这里指定的这些实现

一种更简单的方法是简单地将数据序列化为json,然后再返回。它对性能的影响很小,但它更安全,因为它更不容易出错,而且你不需要修改所有的类。

只是做:

var json = JsonConvert.SerializeObject(myObject)
var clone = JsonConvert.DeserializeObject<T>(json)