Наследование событий с C # 8 Реализация интерфейса по умолчанию / Черты - PullRequest
1 голос
/ 11 ноября 2019

В настоящее время имеется мало документации, касающейся ограничений событий с новыми реализациями интерфейса (черты) C # 8 по умолчанию. Меня особенно смущает предложение спецификации. Мало того, что в примере приведен недопустимый C # (в событии «override» отсутствует идентификатор), но и реализован любой из них в C # 8 (VS2019, .NET Core). 3.0) возвращает множество исключений компилятора. Кроме того, в примечаниях к выпуску C # 8 не упоминаются события для характеристик интерфейса. Поскольку я продолжал пытаться отследить ответ, я также не смог собрать ничего полезного из списка открытых вопросов.

Итак, вот вопросы: эта функция реализована и применима? Если да, то каков правильный синтаксис?

1 Ответ

1 голос
/ 11 ноября 2019

Члены интерфейса по умолчанию используются для черт, а не только для управления версиями, и черта INPC будет иметь смысл.

К сожалению, сейчас невозможно использовать модули DIM для вызова событий, и реализация этого кажется болезненной - это потребует перестройки механизма событий и поломки тонны кода, особеннокод библиотеки. Мы можем использовать DIM для добавления или удаления обработчиков, но это не так полезно.

Было бы неплохо иметь что-то вроде:

interface InpcTrait : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private T Set(T value,String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        return value;
    }
}

class Customer
{
    private string _name;
    public string Name 
    {
        get=>_name;
        set=>_name=Set(value,"Name");
    }
}


К сожалению, это невозможно. Это связано с тем, что ключевое слово event в классе генерирует вспомогательное поле , которое содержит обработчик события и добавляет / удаляет средства доступа. Когда мы вызываем событие, мы вызываем этот обработчик события.

Интерфейсы не могут иметь состояния, что означает, что мы не можем получить доступ к этому событию, чтобы вызвать его.

Когда мы указываем событие в интерфейсе, мы создаем виртуальное событие, и компилятор позволяет только добавлять / удалять обработчики событий к нему. Повышение интерфейса все еще требует доступа к полю поддержки.

Этот пример Sharplab.io показывает, что:

public class DemoCustomer : INotifyPropertyChanged
{
    // These fields hold the values for the public properties.
    private Guid idValue = Guid.NewGuid();
    private string customerNameValue = String.Empty;
    private string phoneNumberValue = String.Empty;

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Генерирует

    [CompilerGenerated]
    private PropertyChangedEventHandler m_PropertyChanged;

    public event PropertyChangedEventHandler PropertyChanged
    {
        [CompilerGenerated]
        add
        {
            //some code
        }
        [CompilerGenerated]
        remove
        {
            //some code
        }
    }

    private void NotifyPropertyChanged(string propertyName = "")
    {
        if (this.m_PropertyChanged != null)
        {
            this.m_PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Что мы можем сделать, это добавить или удалить обработчики событий, но мы даже не можем проверить, есть ли у события уже другие обработчики. Мы рискуем добавить один и тот же обработчик событий несколько раз.

Это действительно:

interface INPCtrait:System.ComponentModel.INotifyPropertyChanged
{            
    private  void AddSomeDefaultHandler()
    {
       PropertyChanged+=Something;
    }

    private  void RemoveDefaultHandler()
    {
       PropertyChanged-=Something;
    }

    public void Something(Object sender,System.ComponentModel.PropertyChangedEventArgs args)
    {
    }    
}

Но у нас нет возможности узнать, нужно ли нам добавлять этот обработчик по умолчанию или нет.

...