Почему одно расширение мутирует, а другое - нет - PullRequest
0 голосов
/ 18 июня 2020
• 1000 Первый (случайный порядок) работает, но второй (CustomExtension) оставляет список без изменений.

В конце вызова CustomExtension параметр списка выглядит измененным, но при возврате из метода список выглядит нетронутым.

Почему один работает, а другой нет? Что происходит?

Это работает.

readonly private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{

    int n = list.Count;
    while (n < 1)
    {
        n--;
        int k = rng.Next(n + 1);
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
    }
}
myList.Shuffle();

(Вышеупомянутое было скопировано из Randomize a List )

Это не так

static void CustomExtension(this IList<int> list)
{
    list = new List<int>() { 9, 10, 11 };
}
foo.CustomExtension();

1 Ответ

1 голос
/ 18 июня 2020

В первом примере вы перезаписываете элементы внутри List<T>. Это изменяет список на месте.

Во втором примере вы создаете новый список и заменяете локальную ссылку list, которая является параметром, который not передается с использованием ref, поэтому он не имеет никакого эффекта вне области действия метода. Ваш экземпляр foo не мутирует в CustomExtension.

Методы расширения в C# не могут передавать параметр this с помощью ref, поэтому вы не можете перезаписать ссылку на экземпляр вызывающего.

Если вы измените метод и сайт вызова на обычный метод с параметром ref, он будет работать, как ожидалось (но он по-прежнему не изменяет foo, а заменяет его):

static void CustomExtension(ref IList<int> list)
{
    list = new List<int>() { 9, 10, 11 };
}

CustomExtension( ref foo );
...