繁体   English   中英

C#中自动实现的属性

[英]Auto implemented properties in C#

当调用Set时,有没有办法继续使用自动实现的属性,同时仍然会引发更改事件,例如INotifyPropertyChanged

代替:

private string _value;
public string Value
{
  get 
  { 
    return this._value;
  }
  set
  {
    this._value = value;
    this.ValueChanged(this,EventArgs.Empty);
  }
}

我可以这样做:

public string Value 
{ 
   get; 
   set 
   { 
     this.ValueChanged(this,EventArgs.Empty); 
   }
}

虽然setter看起来不对,但是可以在不使用后备存储变量填充我的类的情况下执行此操作吗?

更新:看起来我的懒惰目标没有标准的解决方案,我认为最好的解决方案是使用CodeRush或Resharper为我生成所有后备存储。

你不能这样做。 自动实现的属性的规范非常清楚:

自动实现(自动实现)属性可自动执行此模式。 更具体地说,允许非抽象属性声明具有分号存取器主体。 两个访问器必须存在且两者都必须具有分号主体,但它们可以具有不同的可访问性修饰符。 当像这样指定属性时,将自动为该属性生成一个支持字段,并且将实现访问器以读取和写入该支持字段。 支持字段的名称是编译器生成的,用户无法访问。

换句话说,它们只能具有“ get; ”和“ set; ”,并且具有访问修饰符的可能性。

不,你不能,因为你无权访问为该属性生成的私有字段

快速谷歌搜索“inotifypropertychanged自动属性”将引导您访问有关该主题的几篇博文和文章。 这是一个:

INotifyPropertyChanged自动接线或如何摆脱冗余代码

有人问过C#3.0背后的微软团队,他们确实说他们会想一想,请在这里阅读。

在评论中,您将找到更多信息,包括为什么如果您需要更多控制,以及实现它的方法,这是一个坏主意。

你可以使用像PostSharp这样的AOP框架。

但它可以降低性能和构建时间。

自从我问这个问题以来,这个问题实际上已经解决了属性和构建任务: https//github.com/demigor/kindofmagic

可以使用代理工厂类型生成器完成此行为。 我已经在我的开发框架中完成了这个。 如果使用System.Reflection.Emit,则可以创建类型代理。 考虑下面的例子:

var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors
a.PropertyAccessed += ...

Fody加载项PropertyChanged就是这样做的。 就像KindOfMagic一样, Fody使用Mono.Cecil在编译时修改.net程序集的IL。 PropertyChanged文档中列出了以下示例:

你写:

[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}

编译的内容:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

维基包含一些更高级的示例。

它可以使用NuGet:

PM> Install-Package PropertyChanged.Fody

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM