Как получить копию данных вместо ссылки, используя linq / lambda в c #? - PullRequest
7 голосов
/ 04 января 2012

Существует ли простой способ получить копию данных вместо ссылки, используя этот метод? Я попытался .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;
}

Ответы [ 4 ]

6 голосов
/ 04 января 2012

Вам нужно создать копию своего ob самостоятельно - это не то, что предоставляет LINQ.

3 голосов
/ 04 января 2012

Вы можете определить метод Clone на основе существующего метода protected MemberwiseClone:

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

Тогда:

ob item = t.Where(c => c.name == "hello").First().Clone();
2 голосов
/ 04 января 2012

Поскольку ob является классом, это ссылочный тип и, следовательно, любой экземпляр ob при назначении другой переменной (как это происходит в строке ob item = t.Where(c => c.name == "hello").First();) будет автоматически скопируйте ссылку в исходный экземпляр, а не копируйте сам фактический экземпляр. Это общая тема .NET, касающаяся копирования объектов, и она отделена от LINQ / Lambda,

Чтобы достичь желаемого, вам необходимо создать Shallow Copy или Deep Copy результирующего экземпляра из вашей проекции LINQ.

Для вашего ob класса достаточно мелкой копии (ShallowCopy обычно копирует как можно меньше, тогда как DeepCopy копирует все - Хорошую ссылку на различия можно найти здесь ).

Чтобы выполнить ShallowCopy объекта, вы можете использовать просто MemberwiseClone, который является встроенным методом типа объекта .NET, унаследованным всеми объектами.

Для чего-то более существенного вам придется реализовать собственную функцию DeepCopy, но это может быть относительно просто. Нечто похожее на эти реализации, как указано здесь и здесь .

0 голосов
/ 27 июня 2014

Более простой способ - просто сериализовать ваши данные в json, а затем снова вернуться. Это требует небольшого снижения производительности, но это более безопасно, так как менее подвержено ошибкам и вам не нужно изменять все ваши классы.

просто сделайте:

var json = JsonConvert.SerializeObject(myObject)
var clone = JsonConvert.DeserializeObject<T>(json)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...