如果我需要自定义getter / setter,我可以省略字段创建吗?

我可以写出如此美丽的直截了当的代码:

public int Delta { get; private set; } 

现在我只想添加一个调用OnPropertyChanged("Delta");

这是我知道如何做到这一点的唯一方法:

 public int Delta { get { return _delta; } private set { _delta = value; OnPropertyChanged("Delta"); } } private int _delta; 

这是太多的额外代码! 为什么我要在这种情况下引入字段? 你能让这段代码缩短吗? 我想有类似的东西,但它不起作用:

  public int Delta { get; private set { OnPropertyChanged("Delta"); } } 

不,你不能用自动属性这样做。 自动属性是字段上属性的简写语法。 他们几乎没有其他能力。 任何自定义代码执行都需要完整的属性。

我为此创建了此代码段(示例):

 private string _Name; public string Name { get { return _Name; } set { if (_Name != value) { _Name = value; OnPropertyChanged("Name"); } } } 

片段:

    
Expansion propn (Creates a notifying property) propn This snippet helps implementing INotifyPropertyChanged by creating a property with backing store. The settter calls OnPropertyChanged if the value changes. Use the "notify" code snippet in order to implement INotifyPropertyChanged. Olivier Jacot-Descombes
classname Name of class ClassNamePlaceholder ClassName() NameOfProperty MyProp Type int

将此代码复制到文本文件中。 为它添加扩展名“.snippet”,您可以使用代码片段管理器(工具菜单)将其导入Visual Studio。

这里是另一个创建事件处理程序的代码片段(示例):

 #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; //TODO: Inherit interface System.ComponentModel.INotifyPropertyChanged. //TODO: Create properties with the propn code snippet. private void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion 

片段:

    
Expansion notify (Implements INotifyPropertyChanged) notify This snippet the inserts the INotifyPropertyChanged implementation into a class Olivier Jacot-Descombes
classname Name of class ClassNamePlaceholder ClassName()

考虑一下它不是那么美丽! 请参阅Seeman的这篇博文: Code Smell:Automatic Property

.NET属性是方法type get_PropertyName()set_PropertyName(type value)的语法糖,它们是在引擎盖下生成的, get_返回基础字段值, set_显然更新它。 所以有两个选择:要么通过指定属性getter / setter来提供自己的方法体,要么通过为您生成支持字段让它来做,所以根本没有第三种情况。

如果你想简化你的PropertyChanged例程,你可以看看notifypropertyweaver 。

之后,您的代码将如下所示:

 [NotifyProperty(PerformEqualityCheck = false)] public int Delta { get; set; } 

不幸的是情况就是这样。 如果您使用的是C#4.0,则可以使用动态对象 ,并以较低的代码执行此操作,但代价是安全性。

简而言之,你做到了

 public override bool TrySetMember(SetMemberBinder binder, object value) { //set the actual property and do OnPropertyChanged(binder.Name); } 

可能有更多代码要在TrySetMember中编写,但您可以在同一个类中的多个属性中共享它。

如果你不介意任何第三方框架,你可以使用像PostSharp这样的AOP框架为你做锅炉板代码。

不幸的是,没有办法做到这一点。 这种类型的构造可以使用面向方面的编程,但到目前为止,在C#编译器中没有任何生产版本。

没有通用的更好的方法来做到这一点,但你可能会尝试使用像VS片段的Resharpers片段这样的模板引擎来更快地编写这些片段。

在某些情况下,当元数据可用时,您还可以使用代码生成来简化这一过程。

自动属性是“全有或全无”的交易。

他们所做的就是创建一个支持字段,在get访问器中返回其值,并在set访问器中设置其值。 如果您想要做任何额外的事情,您必须定义支持字段并手动实现获取和设置。 没有办法绕过它。

你可能想知道为什么你甚至需要一个自动属性,如果它没有任何逻辑? 为什么不定义公共领域? 但是,假设您定义了一个auto属性,而其他程序集则使用您的程序集。 现在,如果您决定更改为手动实现的属性以添加某些逻辑,则使用您的程序集的程序集不必重新编译。 如果从字段切换到属性,它们将会中断并且必须重新编译。

这是我的交互式.NET教程的直接链接,我将详细讨论属性: http : //motti.me/s2a

如果你感兴趣的话,这里是整个教程的链接: http ://motti.me/c0

我希望这有帮助!