Базовый синтаксис C # 8.0 реализации интерфейса по умолчанию / явные вызовы - PullRequest
0 голосов
/ 26 сентября 2019

Я возился с реализациями интерфейса по умолчанию.Выяснилось, что вы должны определить тип интерфейса, чтобы использовать реализацию метода по умолчанию.Я также нашел кучу заметок о другом синтаксисе, я не могу найти, включен ли он уже или нет, я нашел «решения» о том, как он будет выглядеть, однако он не работает.Я делаю это неправильно или этот новый синтаксис еще не включен?

В некоторой степени связан, но не отвечает на мой вопрос: Вызов метода интерфейса C # по умолчанию для реализации структуры без упаковки

Примечания по синтаксису 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));
    }
}
...