C#8.0默认接口实现基于语法/显式调用

时间:2019-09-26 08:36:37

标签: c# c#-8.0 default-interface-member

我一直在使用默认接口实现。认为您必须将接口类型转换为向下格式才能使用默认方法实现。我还找到了关于另一种语法的大量注释,我找不到是否已经包含了该注释,但确实找到了有关其外观的“决定”,但是它不起作用。我做错了吗?还是还不包括这种新语法?

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

关于base<>/base()语法的说明:https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-11-14.md#default-interface-implementations

关于该提案的Microsoft页面: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));
    }
}

0 个答案:

没有答案