[英]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自动属性”将引导您访问有关该主题的几篇博文和文章。 这是一个:
有人问过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.