How to get a copy of data instead of a reference u

2019-04-25 12:27发布

Is there an easy way to basically just get a copy of the data instead of a reference using this method? I tried .ToArray().Where() but that still seems to pass a reference.

Example:

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
4条回答
Luminary・发光体
2楼-- · 2019-04-25 12:37

A much easier way to go is to simply serialize your data to json and then back again. It takes a small performance hit but it is safer as it less error prone and you don't need to modify all your classes.

simply do:

var json = JsonConvert.SerializeObject(myObject)
var clone = JsonConvert.DeserializeObject<T>(json)
查看更多
仙女界的扛把子
3楼-- · 2019-04-25 12:47

As ob is a class, it is a reference type and therefore any instance of ob, when assigned to a different variable (as is happening within the line ob item = t.Where(c => c.name == "hello").First();) will automatically copy the reference to the original instance, and not copy the actual instance itself. This is a general .NET topic regarding object copying and is separate from LINQ/Lambda,

In order to achieve what you want, you'll need to either create a Shallow Copy or a Deep Copy of the resulting instance from your LINQ projection.

For your ob class, a Shallow Copy would suffice (ShallowCopy generally copies as little as possible whereas DeepCopy copies everything - A good reference for the differences can be found here).

To perform a ShallowCopy of an object, you can use a simply MemberwiseClone which is a built-in method of .NET object type, inherited by all objects.

For something more substantial, you'll have to implement your own DeepCopy function, but that can be relatively simple. Something similar to these implementations as specified here and here.

查看更多
做自己的国王
4楼-- · 2019-04-25 12:48

You need to create a copy of your ob yourself - it's not something LINQ provides.

查看更多
姐就是有狂的资本
5楼-- · 2019-04-25 13:00

You could define a Clone method based on the existing protected MemberwiseClone method:

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

Then:

ob item = t.Where(c => c.name == "hello").First().Clone();
查看更多
登录 后发表回答