【问题标题】:C# pass by value/ref?C#按值/引用传递?
【发布时间】:2009-01-12 20:59:39
【问题描述】:

常见问题,但我可以使用“英语”解释。

是不是像Java一样

Cat myCat

其实是指向Cat的指针?

我真的应该在 C# 中创建复制构造函数吗?


我知道我们是按值传递的,但现在我的问题是我们是按指针值传递还是对象的完整副本传递?

如果是后者,那是不是太昂贵的性能/内存明智?那是你必须使用 ref 关键字的时候吗?

【问题讨论】:

    标签: c#


    【解决方案1】:

    正如@rstevens 回答的那样,如果它是一个类,myCat 就是一个引用。但是如果你将 myCat 传递给一个方法调用,那么引用本身是按值传递的——即参数本身将引用同一个对象,但它是一个全新的引用,所以如果你将它分配给 null,或者创建一个新对象,旧的 myCat 引用仍将指向原始对象。

    SomeMethod(myCat);
    
    void SomeMethod(Cat cat)
    {
        cat.Miau(); //will make the original myCat object to miau
        cat = null; //only cat is set to null, myCat still points to the original object
    }
    

    Jon Skeet 对此有很好的article

    【讨论】:

      【解决方案2】:

      请记住,指针与引用并不完全相同,但如果你愿意,你可以这样想。

      我发誓我在 10 分钟前看到了另一个关于此的 SO 问题,但我现在找不到链接。在我看到的另一个问题中,他们正在谈论通过 ref 与按值传递参数,归结为:

      在 .Net 中默认情况下,您不会通过引用传递对象。您按值传递对对象的引用。

      区别很微妙,但很重要,尤其是当您想在方法中分配给您传递的对象时。

      【讨论】:

        【解决方案3】:

        如果你将 Cat 声明为

        class Cat {...}
        

        原来如此。

        如果你把 Cat 称为

        struct Cat {...}
        

        那么你的变量“就是”结构本身。

        这是.Net中引用类型和值类型的区别。

        【讨论】:

          【解决方案4】:

          是的,它是关于指针,但不是真的......最初让我感到困惑的是,它并不是真正关于保护你的变量免受方法内的更改。如果您在方法内更改对象,则这些更改对外部方法可见,无论是否在“ref”中传递。

          区别(据我所知)是如果您更改变量引用的对象,您发送的变量是否会更新其引用。所以给定这个方法

          public void DoSomething(ref CoolShades glasses)
          {
              glasses.Vendor = "Ray Ban";
              glasses = new CoolShades();
          }
          

          您作为参数传入的变量现在包含对新 CoolShades 的引用,而不是之前引用的任何对象。无论您是否传递了参数ref,原始参数对象的Vendor属性都会更改为“雷朋”。

          【讨论】:

            猜你喜欢
            • 2011-05-08
            • 2023-03-02
            • 2012-07-29
            • 2023-03-07
            • 1970-01-01
            • 2014-04-08
            • 2014-12-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多