c# - 带有 ref 的扩展方法不适用于数组

标签 c# generics extension-methods

我写了这段代码:

public static T[][] Populate<T>(this ref T[][] arg, T with) where T : struct
{
    for (int i = 0; i < arg.Length; i++)
    {
        for (int j = 0; j < arg[i].Length; j++)
        {
            arg[i][j] = with;
        }
    }
    return arg;
}

我收到以下错误:

error 为什么这不起作用?当 this 被拿走时,类似的情况会起作用,不是吗?并且似乎满足了限制:我指定 T 必须是 struct;我知道 arg 实际上是一个数组,但这有什么区别呢?是不是数组默认按引用传递,所以无效?

是否有任何我可以编写的不会产生错误的等效语句?

哎呀,很抱歉提出所有问题。谢谢。

最佳答案

ref 必须在方法声明和调用时指定。

如果扩展的 this 参数可以通过引用传递,则在调用该方法时将无法指定它。

someObject.CallSomeExtensionMethod();

我们将把 ref 放在哪里?无处可去。

如果我们可以通过引用传递一个值而不知道我们正在通过引用传递它,那么奇怪的事情就会发生。调用修改作为第一个参数传递的值的扩展方法是正常的。例如,我们可以编写一个扩展方法来打乱列表:

list.Shuffle();

我们希望修改列表。但是想象一下,如果扩展方法实际上导致 list 指向一个完全不同的 List 实例,我们会感到惊讶。即使我们知道它正在发生,那也会很奇怪,但如果这种行为不明确,那将是困惑的。我们可以调用一个不是 ref 的扩展,有人可以将它更改为 ref 而不会破坏任何东西,引入各种疯狂的、不可预测的效果。

在方法和使用它的地方都有 ref 就像一个契约(Contract) - 该方法告诉我们它可以替换我们的引用,并且我们给予它明确的许可。

关于c# - 带有 ref 的扩展方法不适用于数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56485448/

相关文章:

c# - 从桌面客户端调用时 SessionState 集合项消失

java - Scala 泛型混淆

c - 冲洗替代品

c# - .NET 随机数生成 - 自动种子

c# - 可移植类库和表达式混合

scala - 在 Scala 中绑定(bind)引用自身的类型是什么意思?

c# - ASP.NET 中继器交替行突出显示没有完全成熟 <alternatingitemtemplate/>

c# - Enum 的 Count 和 ToList 扩展方法?

c# - C# dll 中的扩展方法不能作为 VB.NET 中的扩展使用

c# - 这是重载方法的坏习惯吗?