当调用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为我生成所有后备存储。
答案 0 :(得分:6)
你不能这样做。自动实现的属性的规范非常清楚:
自动实施 (自动实现)属性自动化 这种模式。进一步来说, 非抽象财产声明是 允许使用分号访问器 身体。两个访问者必须存在 两者都必须有分号体, 但他们可以有所不同 辅助功能修饰符。当一个 属性是这样指定的,a 支持字段将自动成为 为财产而生成的,以及 将实现访问器以进行读取 来自并写入该支持领域。 支持字段的名称是 编译器生成并且无法访问 用户。
换句话说,他们只能拥有“get;
”和“set;
”,并且可以使用访问修饰符。
答案 1 :(得分:4)
不,你不能,因为你无权访问为该属性生成的私有字段
答案 2 :(得分:4)
快速Google搜索“inotifypropertychanged自动属性”将引导您访问有关此主题的多篇博文和文章。这是一个:
INotifyPropertyChanged auto wiring or how to get rid of redundant code
答案 3 :(得分:1)
有人问过C#3.0背后的微软团队,他们确实说过会考虑它,请阅读here。
在评论中,您将找到更多信息,包括为什么如果您需要更多控制权,以及实现目标的方法,这是一个坏主意。
答案 4 :(得分:1)
您可以使用某些AOP框架,例如PostSharp。
但它可以降低性能和建立时间。
答案 5 :(得分:1)
由于我问过这个问题,这个问题实际上已经解决了属性和构建任务: https://github.com/demigor/kindofmagic
答案 6 :(得分:0)
可以使用代理工厂类型生成器完成此行为。我已经在我的开发框架中完成了这个。如果使用System.Reflection.Emit,则可以创建类型代理。 请考虑以下示例:
var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors
a.PropertyAccessed += ...
答案 7 :(得分:0)
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));
}
}
}
wiki包含一些更高级的示例。
可以使用NuGet:
PM> Install-Package PropertyChanged.Fody