如何提高派生类中的属性?

Jog*_*gge 0 c# wpf events propertychanged inotifypropertychanged

如何提高PropertyChangedSomePropertyB

此示例无法编译,因为PropertyChanged无法以这种方式访问​​...

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
}

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeProperty)))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jog*_*gge 5

解决方案1:

你可以用这个RaisePropertyChangedExtension:

public static class RaisePropertyChangedExtension
{
    public static void RaisePropertyChanged(this INotifyPropertyChanged @this, [CallerMemberName] string propertyName = null)
    {
        var declaringType = @this.GetType().GetEvent(nameof(INotifyPropertyChanged.PropertyChanged)).DeclaringType;
        var propertyChangedFieldInfo = declaringType.GetField(nameof(INotifyPropertyChanged.PropertyChanged), BindingFlags.Instance | BindingFlags.NonPublic);
        var propertyChangedEventHandler = propertyChangedFieldInfo.GetValue(@this) as PropertyChangedEventHandler;
        propertyChangedEventHandler?.Invoke(@this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            this.RaisePropertyChanged();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这是迄今为止我所知道的最佳解决方案.

缺点是你可以PropertyChanged从另一个类升级,如下所示:

public class C
{
    public C(B b)
    {
        b.RaisePropertyChanged(nameof(b.SomeProperty));
    }
}
Run Code Online (Sandbox Code Playgroud)

PropertyChanged这种方式从其他课程中提高是不好的做法,所以我不关心这个缺点.

这个解决方案的灵感来自Thomas Levesque的答案:简单的小型INotifyPropertyChanged实现

解决方案2:

您可以RaisePropertyChanged在基类中创建受保护的A:

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

并在派生类中调用该方法B:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            RaisePropertyChanged();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

缺点是您必须为RaisePropertyChanged您正在创建的每个新基类实现该方法,以避免解决方案1所具有的缺点.

  • 我希望任何一天都能使用Solution 2.特别是当基类(A)已经给定时. (3认同)