为什么一个扩展会发生变异而另一个不会
Why does one extension mutate but the other doesn't
我在玩 C# 扩展,对 mutate 方法感到困惑。
下面是两个应该更改调用列表的代码示例。第一个 (shuffle) 有效,但第二个 (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>
中的元素。这会就地改变列表。
在第二个示例中,您正在创建一个新列表并替换 本地引用 list
,这是一个 not 使用 ref
传递,因此它在方法范围之外没有影响。您的 foo
实例未在 CustomExtension
.
中发生突变
C# 中的扩展方法无法使用 ref
传递 this
参数,因此您无法覆盖调用方的实例引用。
如果您将方法和调用站点更改为带有 ref
参数的普通方法,那么它会按预期工作(但它仍然没有变异 foo
,它正在替换它) :
static void CustomExtension(ref IList<int> list)
{
list = new List<int>() { 9, 10, 11 };
}
CustomExtension( ref foo );
我在玩 C# 扩展,对 mutate 方法感到困惑。
下面是两个应该更改调用列表的代码示例。第一个 (shuffle) 有效,但第二个 (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>
中的元素。这会就地改变列表。
在第二个示例中,您正在创建一个新列表并替换 本地引用 list
,这是一个 not 使用 ref
传递,因此它在方法范围之外没有影响。您的 foo
实例未在 CustomExtension
.
C# 中的扩展方法无法使用 ref
传递 this
参数,因此您无法覆盖调用方的实例引用。
如果您将方法和调用站点更改为带有 ref
参数的普通方法,那么它会按预期工作(但它仍然没有变异 foo
,它正在替换它) :
static void CustomExtension(ref IList<int> list)
{
list = new List<int>() { 9, 10, 11 };
}
CustomExtension( ref foo );