Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#默认情况下,传递参数的是ByRef而不是ByVal_C# - Fatal编程技术网

C#默认情况下,传递参数的是ByRef而不是ByVal

C#默认情况下,传递参数的是ByRef而不是ByVal,c#,C#,我知道C#中的默认值是ByVal。我在很多地方使用了相同的变量名,然后我注意到传递的值发生了变化并返回。我想我知道C的作用域机制是错误的。此处,公共许可证覆盖本地许可证值。我知道我可以很容易地重命名冲突中的变量名,但我想了解有关范围的事实 public static class LicenseWorks { public static void InsertLicense(License license) { license.registered =

我知道C#中的默认值是ByVal。我在很多地方使用了相同的变量名,然后我注意到传递的值发生了变化并返回。我想我知道C的作用域机制是错误的。此处,公共许可证覆盖本地许可证值。我知道我可以很容易地重命名冲突中的变量名,但我想了解有关范围的事实

  public static class LicenseWorks
  {
     public static void InsertLicense(License license)
     {
        license.registered = true;
        UpdateLicense(license);
     }
  }

  public partial class formMain : Form
  {
     License license;

     private void btnPay_Click(object sender, EventArgs e)
     {
          license.registered = false;
          LicenseWorks.InsertLicense(license);

          bool registered = license.registered; //Returns true!
      }
  }    
更新:我添加了以下解决方案:

    public static void InsertLicense(License license)
    {

        license = license.Clone();
        ...
     }

参数是按值传递的-但参数不是对象,而是引用。该引用正在通过值传递,但调用方仍将看到通过该引用对对象所做的任何更改

这与通过引用进行的实际传递非常不同,其中对参数本身的更改如下:

 public static void InsertLicense(ref License license)
 {
    // Change to the parameter itself, not the object it refers to!
    license = null;
 }
现在,如果调用
InsertLicense(ref-foo)
,之后它将使
foo
null。如果没有裁判,就不会

有关更多信息,请参阅我写的两篇文章:

  • (值类型和引用类型之间的差异)

您需要了解参考类型值类型之间的区别。这里我假定您使用的是引用类型许可证,这意味着您实际上正在解析对所讨论实例的引用

见:


虽然不一定正确,但值类型通常在堆栈上或引用类型内分配。虽然引用类型总是在托管堆上分配。

在InsertLicense中传递许可证时,不是按值传递,而是作为引用传递。
这意味着当将注册项更改为true时,它将更改该值,并且在返回引用后,注册项将为true。

您正在按值传递许可证参数;本质上,这意味着您可以修改对象的任何公共属性。但是,如果您将许可证对象的引用重新指定给新对象,即如果您这样做:

public static void InsertLicense(License license)      
{         
   license = new Licence();         
   UpdateLicense(license);      
}
调用方不会引用静态方法中定义的新许可证对象,除非您通过ref传递它


请记住,除非您使用ref或out关键字,否则所有参数都是按值传递到方法中的。

遇到了这个问题,并认为我应该分享Microsoft的说法:

“不要混淆通过引用传递的概念和引用类型的概念。这两个概念不一样。方法参数可以通过ref修改,无论它是值类型还是引用类型。通过引用传递时,值类型没有装箱。”


不要将引用称为“指针”。他们是完全不同的动物!我知道,但为了解释这一点,我认为它最清楚,这也是为什么我把它放在引号里。好了,我认为它被复制了。精彩,易于理解,并且(至少对我来说)具有启示性。回答得好!你应该就此写一本书;-)