2

我一直在搞乱默认的接口实现。认为您必须对接口类型进行向下转换才能使用默认方法实现。我还发现了一堆关于另一种语法的注释,我找不到它是否已经包含在内,我确实找到了关于它的外观的“决定”,但是它不起作用。我做错了还是这个新语法还没有包括在内?

有点相关但没有回答我的问题: Calling C# interface default method from implementation struct without boxing

base<>/base()语法注释: https ://github.com/dotnet/cshaplang/blob/master/meetings/2018/LDM-2018-11-14.md#default-interface-implementations

微软关于提案的页面:https ://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods

class D : IA, IB, IC
{
                  //Notice the use of base() right here.
    void IA.M() { base(IB).M(); }
}

所以说我们需要在某个对象上使用 INotifyPropertyChanged。我们现在可以在接口上默认设置一个 SetField 实现:

public interface INotify : INotifyPropertyChanged
{
    void InvokePropertyChanged(string propertyName);

    bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        INotify thing = (INotify)this;

        if (propertyName == null)
        {
            throw new ArgumentException($"{nameof(propertyName)} is null. PropertyChangedEventHandler will not be fired correctly.");
        }

        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        InvokePropertyChanged(propertyName);
        return true;
    }
}

实现它需要一个向下转换(((INotify)this).SetField),base(INotify)这里最好使用。

public class Thing : INotify
{
    public string A
    {
        get => _a;
        //Need an explicit cast here. Can't figure out how to use base syntax.
        set => ((INotify)this).SetField(ref _a, value);
    }
    private string _a;

    public event PropertyChangedEventHandler PropertyChanged;

    public void InvokePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
4

0 回答 0