为什么一个扩展名会突变而另一个扩展名却没有

时间:2020-06-18 00:43:26

标签: c# extension-methods

我在玩C#扩展,并对mutate方法感到困惑。

下面是两个应该更改调用列表的代码示例。第一个(随机播放)有效,而第二个(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<T>中删除的)

这不是

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

1 个答案:

答案 0 :(得分:1)

在第一个示例中,您将覆盖List<T>中的元素。这会就地改变列表。

在第二个示例中,您将创建一个新列表并替换本地参考 list,该参数是使用{{ 1}},因此它在方法范围之外没有影响。您的ref实例未在foo中进行突变。

C#中的扩展方法无法使用CustomExtension传递this参数,因此您不能覆盖调用者的实例引用。

如果使用ref参数将方法和调用站点更改为普通方法,则它可以按预期工作(但它仍然没有对ref进行突变,而是将其替换了):< / p>

foo