为什么一个扩展名突变却另一个不突变

问题描述 投票:0回答:1

我在玩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();
c# extension-methods
1个回答
0
投票

在第一个示例中,您要覆盖List<T>内部的元素。这将原位更改列表。

在第二个示例中,您正在创建一个新列表并替换local reference list,这是使用ref传递的not参数,因此它在外部无效方法的范围。您的foo实例未在CustomExtension中进行变异。

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

如果您使用ref参数将方法和调用站点更改为普通方法,则它将按预期工作(但仍然没有使foo发生变异,而是将其替换了):

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

CustomExtension( ref foo );
© www.soinside.com 2019 - 2024. All rights reserved.