Почему не обновляется свойство объекта, являющееся ссылкой - PullRequest
0 голосов
/ 16 июня 2020

Рассмотрим этот код

class Program
{
    static void Main(string[] args)
    {
        var lst = new List<MyObj>()
        {
            new MyObj() {name = "Old1", weight = 1},
            new MyObj() {name = "Old2", weight = 2}
        };

        lst.Join(GetList(), p => p.weight, q => q, (p, q) =>
        {
            p.name = "new";
            return p;
        });

        lst.ForEach(p => Console.WriteLine(p.name));
    }
    public class MyObj
    {
        public string name { get; set; }
        public int weight { get; set; }
    }

    public static List<int> GetList()
    {
        return new List<int>() {1,2};
    }
}

Результатом этого кода будет Old1, Old2. Я не понимаю, почему «имя» не обновляется внутри функции resultSelector. Это мое мышление: экземпляр MyObj является ссылочным типом, мы присоединяемся к нему и собираем его в переменной p (которая, я думаю, является ссылочным типом, т.е. содержит ссылку на исходный MyObj). Итак, внутри функции для создания результата она обновит свойство «name» (опять же, будет передана ссылка) в том месте памяти, где существует исходный MyObj. Почему это не так? Где я ошибаюсь?

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Вы не присвоили результат Join какой-либо переменной, но он возвращает IEnumerable<T>. Попробуйте немного обновить свой код, сохранить результат соединения и перебрать его

var result = lst.Join(GetList(), p => p.weight, q => q, (p, q) =>
{
    p.name = "new";
    return p;
}).ToList();

result.ForEach(p => Console.WriteLine(p.name));

В текущем коде вы просматриваете исходный код lst, который остается неизменным.

Если вы хотите увидеть обновленное имя и изменения в исходных объектах, просто материализуйте свой запрос, используя ToList() (потому что Join реализовано с использованием отложенного выполнения), чтобы получить изменения сделано p.name = "new";

lst.Join(GetList(), p => p.weight, q => q, (p, q) =>
{
    p.name = "new";
    return p;
}).ToList();
0 голосов
/ 16 июня 2020

Метод Join() возвращает новый IEnumberable<>, он не изменяет исходный список. https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.join?view=netcore-3.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...