我在玩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();
在第一个示例中,您要覆盖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 );