我在玩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();
答案 0 :(得分:1)
在第一个示例中,您将覆盖List<T>
中的元素。这会就地改变列表。
在第二个示例中,您将创建一个新列表并替换本地参考 list
,该参数是使用{{ 1}},因此它在方法范围之外没有影响。您的ref
实例未在foo
中进行突变。
C#中的扩展方法无法使用CustomExtension
传递this
参数,因此您不能覆盖调用者的实例引用。
如果使用ref
参数将方法和调用站点更改为普通方法,则它可以按预期工作(但它仍然没有对ref
进行突变,而是将其替换了):< / p>
foo