为了账号安全,请及时绑定邮箱和手机立即绑定

属性总是不可变的吗?

属性总是不可变的吗?

C#
茅侃侃 2022-07-23 09:01:27
我目前在为类成员使用自动生成的属性时遇到问题。在类上调用方法应该更新属性,但它似乎不起作用。我正在更新一些旧的 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: 0AFTER: b.MyVar: 0, b.SecondVar: 23我希望调用MyVar.Update(z)会更新属性,并且后续调用MyVar.X应该提供更新的值。这是预期的行为,还是 C# 中的错误?
查看完整描述

1 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

您正在使用可变结构,正是出于这个原因,强烈建议您不要这样做。


你的代码在这里:


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因为您直接在变量上调用它。您的属性并非如此 - 使用属性获取器实际上是调用一个返回值的方法,该值是变量值的副本。


如果您要使用类,您会看到您期望的行为,因为这样您就不会尝试更改底层变量的值,而是更改它所引用的对象中的内容。


查看完整回答
反对 回复 2022-07-23
  • 1 回答
  • 0 关注
  • 88 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信