仅引发事件的 C# 'set'

C# 'set' that only raises an event

我想要一个可以获取/设置的public 属性。但我也希望在设置时触发 NameChanged 事件,但我不希望有一个非 public 字段来存储它的值。

我的问题是,在 setter 中,如何在不导致无限递归的情况下为 属性 分配新值?

public delegate void NameChangedHandler( object sender, EventArgs e );

event NameChangedHandler NameChanged;

public String Name
{
    get;
    set { Name = value; NameChanged(this, null); } // Recursion ?
}

[...] but I do not want to have a non-public field to store its value.

无法满足此要求。甚至自动属性也有一个 private 字段支持它们的值。它们仍然是在 C# 编译期间创建的。而且,无论如何,您不能在 gettersetter 中混合使用自动属性和正文属性。

也许您会对我几个月前创建并发布的一些名为 TrackerDog which can turn any object into a change-trackable one. And INotifyPropertyChanged 的开源项目感兴趣,该项目在 运行 时间内使用代理自动实现。

这样,您不需要切换到非自动属性,您仍然可以注入事件,并且给定对象中的每个 set 属性都会引发INotifyPropertyChanged.PropertyChanged 事件。

例如,给出以下 class:

public class User
{
  public virtual string Name { get; set; }
  public virtual byte Age { get; set; }
}

...您可以按如下方式将 User 的实例变为可跟踪更改:

User user = new User().AsTrackable();
// or
User user = Trackable.Of<User>();

...现在 User 实例实现 INotifyPropertyChanged:

INotifyPropertyChanged userWhichCanHookChangeHandlers =
                            (INotifyPropertyChanged)user;



userWhichCanHookChangeHandlers.PropertyChanged += (sender, e) =>
{
     string propertyName = e.PropertyName;
};

检查项目的完整 how-to to get further details

如果您希望 Setter 实际上不设置任何内容,您可以这样做。 (不知道你为什么想要,但是,没有什么能阻止你。)

public String Name
{
    get { return _Name; }
    set { NameChanged(this, null); } 
}

这是有效的,可以正常编译。

value 只不过是 setter 方法的一个参数,就像任何其他方法一样,您可以选择对参数完全不做任何事情。