C#默认情况下,传递参数的是ByRef而不是ByVal
我知道C#中的默认值是ByVal。我在很多地方使用了相同的变量名,然后我注意到传递的值发生了变化并返回。我想我知道C的作用域机制是错误的。此处,公共许可证覆盖本地许可证值。我知道我可以很容易地重命名冲突中的变量名,但我想了解有关范围的事实C#默认情况下,传递参数的是ByRef而不是ByVal,c#,C#,我知道C#中的默认值是ByVal。我在很多地方使用了相同的变量名,然后我注意到传递的值发生了变化并返回。我想我知道C的作用域机制是错误的。此处,公共许可证覆盖本地许可证值。我知道我可以很容易地重命名冲突中的变量名,但我想了解有关范围的事实 public static class LicenseWorks { public static void InsertLicense(License license) { license.registered =
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修改,无论它是值类型还是引用类型。通过引用传递时,值类型没有装箱。”
不要将引用称为“指针”。他们是完全不同的动物!我知道,但为了解释这一点,我认为它最清楚,这也是为什么我把它放在引号里。好了,我认为它被复制了。精彩,易于理解,并且(至少对我来说)具有启示性。回答得好!你应该就此写一本书;-)