使用参考值作为参数,带或不带“ref”? [复制]

Posted

技术标签:

【中文标题】使用参考值作为参数,带或不带“ref”? [复制]【英文标题】:Using a reference value as parameter, with or without "ref"? [duplicate] 【发布时间】:2015-11-02 01:29:57 【问题描述】:

我遇到了两个解决方案(都有效):

 public List<Label> foo1(ref ISomeInterface[] all)

 public List<Label> foo2(ISomeInterface[] all)

有区别吗,我选哪一个有关系吗?接口是一个参考值,无论如何都会将参数作为参考,“ref”也会获得参考......我想我可以忽略“ref”......我想知道为什么编译器没有给我一个错误......

【问题讨论】:

【参考方案1】:

有区别吗?

是的,有。 C# 中的所有内容按值传递。当您通过ref 传递引用类型时,您传递的是实际的引用指针而不是副本。这样,如果您通过 ref 传递引用类型并通过 new 关键字将其设置为新引用,您将更改引用。

一个例子:

public static void Main(string[] args)

    ISomeInterface[] somes = new[]  new SomeConcreteType() 
    Foo(somes);
    Console.WriteLine(somes.Length) // Will print 1
    Foo(ref somes);
    Console.WriteLine(somes.Length) // Will print 0


public List<Label> Foo(ref ISomeInterface[] all)

    all = new ISomeInterface[0];

public List<Label> Foo(ISomeInterface[] all)

    all = new ISomeInterface[0];

【讨论】:

【参考方案2】:

在第一种情况下,您替换“全局”(方法外)参数all。在第二种情况下,您将替换 all 参数的本地副本。

public List<Label> foo1(ref ISomeInterface[] all)

    all = new ISomeInterface[0]; //you will get empty array outside method


public List<Label> foo1(ISomeInterface[] all)

    all = new ISomeInterface[0]; //you will get empty array only inside method

【讨论】:

只是我的一个小问题:即使对于数组,它在 C# 中是否总是“按值调用”?我的意思是这听起来很不寻常,但有可能。这意味着它需要在没有引用的情况下将整个数组复制到函数调用的堆栈中。 @Matthias id 总是按值调用。但它不会复制数组,它只会复制引用(指针)到数组。这里的 value 只是一个小指针 好的。所以它只是关于指针而不是有效负载。 我觉得如果不复制数组应该叫“引用调用”吧? @Matthias 不,看起来,但不。这是一个指针。他的值是数组的地址。当您在没有ref 的情况下调用时,您将传递值并将其复制到具有相同值(同一数组的地址)的本地指针。您可以修改此本地指针(使用new),它不会影响具有相同值(数组地址)的另一个变量。当您传递 ny ref 时,您没有额外的局部变量。这就是“引用调用”【参考方案3】:

这取决于你想对数组做什么。 如果要修改 foo1 方法中的值并在 foo1 方法之外使用这些修改,则可能需要使用 ref 类型版本

如果你只想使用返回的List&lt;Label&gt;,你应该使用不带参考的选项。

【讨论】:

以上是关于使用参考值作为参数,带或不带“ref”? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何定义带参数或不带参数调用的函数? [复制]

带或不带`.min`的样式表参考

-XX:MaxPermSize 带或不带 -XX:PermSize

定义带或不带导出的变量

使用带或不带括号的 python 装饰器

在 ES6 中导入带或不带大括号 [重复]