【问题标题】:Does C# return by reference or value?C# 是按引用还是按值返回?
【发布时间】:2016-04-07 18:33:03
【问题描述】:

在以下场景中,“Pool”是按值返回还是按引用返回?

private static List<Item> Pool;

public static List<Item> GetPool()
{
    return Pool;
}

我想实现在请求列表时循环遍历列表的能力(以便另一个线程可以从列表中添加/删除项目,但调用线程的列表保持不变,以便 foreach 循环不会导致例外)。如果它是按值返回的,那么它将是它自己的列表,而如果它是一个引用,我仍然有修改列表的危险。如有错误请指正,这只是我的理解

【问题讨论】:

  • 为什么不设置一个测试场景并在调试器中检查它以找出答案?通过您发布的 5 行代码,我认为您已经完成了 50% 的可行测试设置。
  • 你为什么不看看 .net 4.0+ 中的 BlockingCollection 或 ConcurrentBag 日期类型 - 它应该适合你的任务

标签: c#


【解决方案1】:

所有方法总是返回一个值。他们永远无法返回引用。

如果它是按值返回的,那么它将是它自己的列表,而如果它是一个引用,我仍然有修改列表的危险。

这是错误的。返回的值不是列表,而是对列表对象的引用,因为List 是引用类型,所以任何使用从该方法返回的值的代码和任何直接访问该字段的代码都使用不同的引用副本相同的列表。

【讨论】:

    【解决方案2】:

    Pool 是List&lt;Item&gt; 类型的变量。因此它持有对List&lt;Item&gt; 类型对象的引用,或者它是null。话虽如此,当您读取此值时(实际上是 GetPool 所做的),您将获得对该对象的引用(或 null)。

    让我们更清楚一点,值类型和引用类型之间的主要区别是什么。 int 是一个值类型。让我们考虑以下代码。

    int a = 4;
    int b = a;
    a = 5;
    

    上述声明和赋值完成后a和b的值是多少?

    a 的值为 5,b 的值为 4。为什么?第一条语句将文字值 4 复制到 a。第二条语句将a 的值复制到b。因此b 的值为 4。请注意,a 的四个与b 的四个不同。 (就像你有两本同一本书。一份属于a,另一份属于b)。在第三条语句之后,a 的值为 5。

    另一方面,类是引用类型。让我们声明以下类:

    public Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    

    现在让我们考虑一下我们有以下代码。

    var personA = new Person { FirstName = "Bob", LastName = "Barney" };
    var personB = personA;
    personA.FirstName = "Jack";
    

    personA.FirstName 和 personB.FirstName 的值是多少?

    它们将完全相同,Jack。为什么?

    因为在这一行

    var personB = personA;
    

    我们有一个引用复制(因为类是引用类型)。就我们上面提到的这本书的范式而言,这意味着什么?现在就像我们扔了一本书的物理副本,我们共享了一个 URL,我们可以在其中阅读这本书。因为,我们都有相同的引用,所以当第 30 页发生变化时,我们双方都可以看到。

    【讨论】:

      【解决方案3】:

      C# 总是按值返回*。但是,在 C# 中,大多数类型都是引用类型,这意味着该类型的任何变量都是引用;它是按值返回的引用。

      (*) 也就是说,直到 ref 返回 make it in (C# 7?)。

      【讨论】:

      • C#通过引用返回引用类型。
      • @Bauss 不,它没有。它按值返回所有类型。
      • 在他的示例中,函数返回的值将是对声明列表的引用。您可以更改引用是完全不同的话题,并且与 C# 缺乏不变性有关。
      • @Bauss 是的,返回的是 value,而不是返回的 reference,因为该方法(就像 C# 中的每个方法一样)返回一个值.
      • @Bauss 是的,那些引用从方法返回时是按值传递的。
      猜你喜欢
      • 2011-11-10
      • 1970-01-01
      • 2014-04-08
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2019-04-04
      相关资源
      最近更新 更多