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.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