【问题标题】:How to get a copy of data instead of a reference using linq/lambda in c#?如何在 c# 中使用 linq/lambda 获取数据副本而不是引用?
【发布时间】:2012-01-04 09:15:35
【问题描述】:

有没有一种简单的方法可以使用这种方法来获取数据的副本而不是引用?我尝试了 .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


    【解决方案1】:

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

    【讨论】:

    • 尝试通过ob类型实现IClonable。然后你可以使用t.Where(c =&gt; c.name == "hello").First().Clone()
    【解决方案2】:

    您可以基于现有的protected MemberwiseClone 方法定义Clone 方法:

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

    然后:

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

    【讨论】:

      【解决方案3】:

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

      为了实现您想要的,您需要从您的 LINQ 投影创建一个 Shallow Copy or a Deep Copy 的结果实例。

      对于您的ob 课程,浅复制就足够了(浅复制通常尽可能少复制,而深度复制复制所有内容 - 可以找到关于差异的良好参考here)。

      要执行对象的 ShallowCopy,您可以使用简单的 MemberwiseClone,它是 .NET 对象类型的内置方法,由所有对象继承。

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

      【讨论】:

        【解决方案4】:

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

        简单地做:

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

        【讨论】:

        • 虽然不优雅,但它非常适合处理 HttpRuntime.Cache 对象。微不足道的打击并返回完成任务,而不是四处寻找同样会影响性能的克隆解决方案。
        猜你喜欢
        • 2010-10-01
        • 2017-02-19
        • 1970-01-01
        • 2015-01-20
        • 2013-07-06
        • 2013-12-16
        • 1970-01-01
        相关资源
        最近更新 更多