属性总是不可变的吗?

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


我正在更新一些旧的 C# 代码,VS2017 建议我提供一些重构技巧,例如,将具有手动提供的属性的私有成员转换为自动生成的属性。


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# 中的错误?


茅侃侃
浏览 89回答 1
1回答

元芳怎么了

您正在使用可变结构,正是出于这个原因,强烈建议您不要这样做。你的代码在这里: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因为您直接在变量上调用它。您的属性并非如此 - 使用属性获取器实际上是调用一个返回值的方法,该值是变量值的副本。如果您要使用类,您会看到您期望的行为,因为这样您就不会尝试更改底层变量的值,而是更改它所引用的对象中的内容。
打开App,查看更多内容
随时随地看视频慕课网APP