代码之家  ›  专栏  ›  技术社区  ›  jeff17237

事件继承与C#8默认接口实现/特征

  •  0
  • jeff17237  · 技术社区  · 6 年前

    the spec proposal. 这个例子不仅给出了无效的C#(“override”事件缺少一个标识符),而且在C#8(VS2019,.NET Core 3.0)中实现这些都会返回大量编译器异常。此外, the release notes for C#8 不要提及接口特征的事件。当我继续努力寻找答案时,我也无法从中收集到任何有用的信息 the open issues list.

    0 回复  |  直到 6 年前
        1
  •  1
  •   Panagiotis Kanavos    6 年前

    默认接口成员用于traits,而不仅仅是版本控制,INPC trait是有意义的。

    不幸的是,现在不可能使用dim来引发事件,并实现它 seems to be a pain -这将需要彻底检查事件机制并破坏大量代码,尤其是库代码。我们可以使用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 背衬场 它可以容纳 以及添加/删除访问器。当我们引发事件时,我们调用该事件处理程序。

    接口不能有状态,这意味着我们不能访问该事件来引发它。

    当我们在接口中指定一个事件时,我们创建一个虚拟事件,编译器只允许向它添加/删除事件处理程序。提升接口仍然需要访问backing字段。

    This Sharplab.io example 表明:

    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)
        {
        }    
    }
    

    但我们无法知道是否需要添加默认处理程序。

    推荐文章