【问题标题】:how to override set in C# of automatic properties如何覆盖在 C# 中设置的自动属性
【发布时间】:2012-01-03 20:05:33
【问题描述】:

我想使用自动实现的属性,但同时我想在每次更改属性时调用一个方法。

public float inverseMass
{
    get;
    set
    {
        onMassChanged();
        inverseMass = value;
    }
}

前面的代码是否对属性进行了递归调用?如果有,如何实现?

【问题讨论】:

  • 你不能在 C# 中做到这一点。您必须使用支持字段。
  • 答案是肯定的......它会创建一个连续的循环。
  • @UweKeim,这应该是一个答案。
  • github.com/Fody/PropertyChanged 将为您编写 INotifyPropertyChanged 代码(它可以节省大量输入)如果您拥有那条路线

标签: c# c#-3.0 properties automatic-properties


【解决方案1】:

如果您提供自己的 get/set,那么您需要为变量提供自己的存储空间。

private float _inverseMass;

public float inverseMass
{
    get { return _inverseMass; }
    set
    {
        _inverseMass = value;
        onMassChanged();
    }
}

【讨论】:

  • 可惜了。最好使用某种常见的预定义词,例如value,而不是创建自动属性。
【解决方案2】:

改为使用支持字段:

public float inverseMass
{
    get
    {
        return _inverseMass;
    }
    set
    {
        _inverseMass = value;
        onMassChanged();
    }
}

private float _inverseMass;

我曾经在某处读到 C# 人员决定他们想用这些自动属性覆盖广泛的使用场景,但对于特殊情况,您必须回到良好的旧支持字段。

(说实话,我相信 Jon Skeet 告诉他们如何实现它们)

【讨论】:

    【解决方案3】:

    您需要将上述内容分解为私有/公共成员,这样您就不会遇到递归问题:

    private float _inverseMass;
    public float inverseMass
    {
      get { return this._inverseMass; }
      set { this._inverseMass = value; onMassChanged(); }
    }
    

    但是,您是否查看过INotifyPropertyChanged 界面?它几乎可以满足您的需求,并且根据您正在编写的内容,它可能会受到原生支持。

    public class MyClass : INotifyPropertyChanged
    {
      public event PropertyChangedEventHandler PropertyChanged;
      private void NotifyPropertyChanged(String property)
      {
        var event = this.PropertyChanged;
        if (event != null)
        {
          event(this, new PropertyChangedEventArgs(property));
        }
      }
    
      private float _inverseMass;
      public float inverseMass
      {
        get { return this._inverseMass; }
        set { this._inverseMass = value; NotifyPropertyChanged("inverseMass"); }
      }
    }
    

    【讨论】:

      【解决方案4】:

      你不能在 C# 中做到这一点。

      它是自动属性或带有支持字段的属性。

      【讨论】:

        【解决方案5】:

        这不会编译,所以很难说它是否是递归的。

        您不能只指定自动属性的一部分。在这种情况下,您将需要使用支持字段:

        private float _inverseMass;
        public float inverseMass 
        { 
            get { return _inverseMass; }
            set 
            { 
                onMassChanged(); 
                _inverseMass = value; 
            } 
        }
        

        不过,像 PostSharp 这样的面向切面的编程框架或许可以帮助您。

        【讨论】:

          【解决方案6】:

          上面给出了正确答案,但如果您想在 Visual Studio 中快速完成此操作,您可以改用代码片段来为您生成属性。

          阅读这篇文章应该会更好地解释它:http://www.roelvanlisdonk.nl/?p=1007

          如果需要,您甚至可以创建自己的代码 sn-p 来添加重复代码。您甚至可以使用它来快速生成如上所述的 INotifyPropertyChanged 实现。

          【讨论】:

            【解决方案7】:

            使用私有变量作为公共属性的备份字段。

            private float inverseMass;
            
            public float InverseMass{
            
               set
               {
                    onMassChanged();
                    inverseMass=value;
               }
               get
               {
                  return inverseMass;
               }
            
            }
            

            【讨论】:

              【解决方案8】:
              public float inverseMass
              {
                  get;
                  set
                  {
                      if (inverseMass != value)
                      {
                          inverseMass = value;
                          onMassChanged();
                      }
                  }
              }  
              

              【讨论】:

              • 你在这里想说什么?此答案无法编译。
              猜你喜欢
              • 1970-01-01
              • 2017-08-29
              • 1970-01-01
              • 1970-01-01
              • 2019-07-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-02-27
              相关资源
              最近更新 更多