c# - 属性总是不可变的吗?

标签 c# properties

我目前在为类成员使用自动生成的属性时遇到问题。调用类上的方法应该更新属性,但它似乎不起作用。

我正在更新一些旧的 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/

相关文章:

c# - 如何使用自定义身份验证和内存托管进行 ASP.NET Web API 集成测试

java - 使用 Android 将数据插入 Windows Azure 表?

C# 4.0 动态对象和 WinAPI 接口(interface),如 IShellItem(无需在 C# 源代码中定义它们)

c# - 我可以使用启动期间配置的 MvcJsonOptions 在自定义中间件中进行序列化吗?

java - Java 应用程序的 Linux 文件路径转义字符?

c# - .NET - 是否有翻转时钟控件?

python - 属性(property)似乎没有以正确的方式运作

java - 如果我使用 -D 设置系统属性,我可以从我的代码中访问它吗?

Objective-C 设置nil和释放的区别

Spring &JSP : how to evaluate expression in a variable?