作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前在为类成员使用自动生成的属性时遇到问题。调用类上的方法应该更新属性,但它似乎不起作用。
我正在更新一些旧的 C# 代码,VS2017 为我提供了一些重构技巧,例如,将手动提供的属性设置为自动生成的属性的私有(private)成员。
VS 只需单击几下即可轻松完成此操作,一切都可以正常编译。问题是代码无法像以前那样工作。
考虑以下简化的代码示例:
using System;
public class Program
{
struct A
{
public A(int x) : this()
{
X = x;
}
public int X { get; private set; }
public void Update(int y)
{
X += y;
}
}
class B
{
private A _secondVar;
public B()
{
}
public A MyVar { get; set; }
public A SecondVar
{
get { return _secondVar; }
protected set { _secondVar = value; }
}
public void Foo(int z)
{
MyVar.Update(z);
_secondVar.Update(z);
}
}
public static void Main()
{
B b = new B();
Console.WriteLine("BEFORE: b.MyVar: " + b.MyVar.X + ", b.SecondVar: " + b.SecondVar.X );
b.Foo(23);
Console.WriteLine("AFTER: b.MyVar: " + b.MyVar.X + ", b.SecondVar: " + b.SecondVar.X );
}
}
输出是:
BEFORE: b.MyVar: 0, b.SecondVar: 0
AFTER: b.MyVar: 0, b.SecondVar: 23
我希望调用 MyVar.Update(z)
会更新该属性,随后对 MyVar.X
的调用应该提供更新后的值。
这是预期的行为,还是 C# 中的错误?
最佳答案
您正在使用可变结构,正是出于这个原因,强烈建议不要这样做。
您的代码在这里:
public void Foo(int z)
{
MyVar.Update(z);
_secondVar.Update(z);
}
等同于:
public void Foo(int z)
{
A tmp = MyVar; // Creates a copy
tmp.Update(z);
_secondVar.Update(z);
}
您的 _secondVar.Update(z)
代码更改了 _secondVar
的值,因为您直接在变量上调用它。您的属性不是这种情况 - 使用属性 getter 是有效地调用返回值的方法,该值是变量值的副本。
如果您要使用类,您会看到预期的行为,因为那样您就不会尝试更改基础变量的值,而是更改它所引用的对象中的内容。
关于c# - 属性总是不可变的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54215650/
COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。 一般来说复制就是创建出完全相同的两份,两份是独立的: 但是,有的时候复制这件事没多大必要
我是一名优秀的程序员,十分优秀!