【问题标题】:can somebody explain me what does "passing by value" and "Passing by reference" mean in C#?有人可以解释一下 C# 中的“按值传递”和“按引用传递”是什么意思吗?
【发布时间】:2013-10-30 14:51:16
【问题描述】:

我不太确定 c# 中的“按值传递”和“按引用传递”的概念。 我认为按值传递意味着:

    int i = 9;

我们将 int i 传递给一个方法,例如:method(i) 通过引用传递意味着准确地传递它的位置,例如:

    Class.method.variable

它会给出值。 谁能帮帮我??

【问题讨论】:

    标签: c# reference parameter-passing


    【解决方案1】:

    简单来说...

    “按值传递”是指将变量的实际值传递给函数。因此,在您的示例中,它将传递值 9。

    “通过引用传递”意味着您将变量本身传递给函数(不仅仅是值)。因此,在您的示例中,它将传递一个值为 9 的整数对象。

    这会产生不同的后果,并且在不同的情况下都有用。

    这个答案有更全面的信息: What's the difference between passing by reference vs. passing by value?

    【讨论】:

      【解决方案2】:

      按值传递意味着您将实际引用传递给该对象在内存中的位置。所以如果你有一个类,比如:

      CustomObj aObj = New CustomObj();
      aObj.SomeString = "Test";
      someMethod(aObj);
      

      还有一个像这样的方法头:

      someMethod(CustomObj objIn){
           objIn.SomeString = "Changing by value";
      }
      

      然后写到控制台:

      Console.WriteLine(aObj.SomeString)
      

      它将产生"Changing by value" 而不是"Test",因为我们有一个对该对象的引用

      相反,按价值计算,这种方式不起作用。继续我们上面的例子:

      int byValue = 0;
      someMeothd(byValue);
      
      someMethod(int numIn){
         numIn++;
      } 
      
      Console.WriteLine(byValue);
      

      会产生"0"

      【讨论】:

      • 这些都不是通过引用传递的。在 C# 中,通过引用传递需要使用 refout 修饰符。
      • 啊,我以为他只是在问传递引用或值类型的概念
      • @Lee 我很好奇,为什么选择的答案和我做的一样?
      • 就目前而言,您的答案讨论了按值传递引用类型变量 (CustomObj) 和按值传递值类型变量之间的区别,即您可以通过不同的副本来改变对象相同的参考。接受的答案解释说,通过引用传递会为调用方法中的变量创建一个别名,因此object o; SomeMethod(out o); 实际上会导致o 本身被修改,而不仅仅是它指向的对象。
      【解决方案3】:

      这是一个非常广泛的主题,所以我只会尝试回答您的直接问题。通过值或对方法的引用传递某些内容将取决于您实际发送的内容。

      如果是值类型,它将按值发送,如果是引用类型,它将按值发送引用。基本上它会将变量本身发送给方法。

      如果你想要真正的引用,你必须使用ref关键字。

      一个展示它的例子:

      void Main()
      {
          int x = 5;
          Console.WriteLine (x);
          Test(x);
          Console.WriteLine (x);
      
          MyClass c = new MyClass();
          c.Name = "Jay";
          Console.WriteLine (c.Name);
          TestClass(c);
          Console.WriteLine (c.Name);
      }
      
      private void Test(int a){
       a += 5;
      }
      
      private void TestClass(MyClass c){
       c.Name = "Jeroen";
      }
      
      public class MyClass {
       public String Name {get; set; }
      }
      

      输出:

      5
      5
      周杰伦
      杰伦

      int 是一个值类型,因此它的值被发送到方法。这意味着对该参数的任何调整都只会在方法内的本地副本上进行。

      但是,类是引用类型,因此myClass 将发送其内存位置。这意味着通过更改给定对象内部的数据,这也将更改此类在不同范围内的值,因为它们都引用相同的内存位置。

      如果您使用ref 关键字,则会传输引用。

      如果你想要moreinformation,请从比我更有经验的人那里获得。

      【讨论】:

      • 谢谢伙计,这真的很有帮助;)
      • "它将通过引用按值发送。"什么?
      • @newacct:听起来确实有点尴尬。
      【解决方案4】:

      几点:

      在 C# 中,除非您使用 ref 关键字,否则它始终是按值传递。

      按值传递: 如果是值类型 - 它只是值类型变量的另一个副本。

      在引用类型的情况下 - 它是引用(或指针)的副本,指向在堆中分配内存的确切位置。

      按参考传递:

      对于引用类型变量——使用关键字将其传递给另一个方法仅在传递的变量可以在被调用的方法中重新分配的情况下有用。 这意味着:

      假设 - 外部(调用者)方法 A 内部(调用)方法 B

      引用类型对象 R - 从方法 A 传递给方法 B 那么如果你在方法 B 中重新分配对象 R 的内存位置 那么这些变化不会在对象 R 的方法 A 中看到,除非您使用 ref 关键字传递对象 R(即通过引用传递)。

      【讨论】:

      • In C# unless, you use ref keyword, it is always Pass By Value. 这是不正确的。这对于 int 和 bool 等简单类型是正确的,但默认情况下通过引用传递一个类。
      • @paqogomez - 默认情况下,类类型的实例通过引用传递,refout 在 C# 中需要通过引用传递。
      • @paqogomez:不,它是 100% 正确的。引用类型与所有其他类型的工作方式相同。没有refout 它是按值传递。
      • Jon Skeet 很好地解决了这个问题:stackoverflow.com/a/8708674/543538jonskeet.uk/csharp/parameters.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 2012-07-29
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      相关资源
      最近更新 更多