【问题标题】:Invoking an event from partial class is not possible [duplicate]不可能从部分类调用事件[重复]
【发布时间】:2021-01-11 19:02:52
【问题描述】:

我有以下类结构:

    public abstract class Base : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    }
    
    internal partial class ImplBase : Base {
    }
    
    internal partial class ImplBase {
        void someFunc(){
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("propName"));
        }
    }

为什么该语言不允许从部分类中引发事件?

在此处查看 sn-p:https://dotnetfiddle.net/k8catR

【问题讨论】:

  • 将事件定义为抽象,事件只能由定义它的类引发。
  • 我认为部分类实际上是“同一类”。
  • 是的,部分类是一样的,但是抽象类不,你的事件是在抽象类中定义的,而不是在部分类中。

标签: c# events partial-classes


【解决方案1】:

你可以在没有部分类的情况下重现错误编译:

public abstract class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
}

internal class ImplBase : Base
{
    void someFunc()
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("propName"));
    }
}

此代码具有相同的错误消息,它不是部分类限制。这是遗产限制:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-raise-base-class-events-in-derived-classes

当您创建一个可用作其他类的基类的类时,您应该考虑这样一个事实,即事件是一种特殊类型的委托,只能从声明它们的类中调用。派生类不能直接调用在基类中声明的事件。尽管有时您可能想要一个只能由基类引发的事件,但大多数时候,您应该启用派生类来调用基类事件。为此,您可以在包装事件的基类中创建一个受保护的调用方法。通过调用或覆盖这个调用方法,派生类可以间接调用事件。

您需要在声明事件的类中引发事件。您可以在方法中执行此操作并在子类中重用该方法:

public abstract class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

internal partial class ImplBase : Base
{ }

internal partial class ImplBase
{
    void someFunc()
    {
        RaisePropertyChanged("propName");
    }
}

【讨论】:

    【解决方案2】:

    它与它是一个部分类没有任何关系。它与您试图从未定义的类中引发偶数有关。下面不会引发错误。

    public partial class Base : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
    
    }
    
    public partial class Base
    {
        protected void RaiseEvent(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("propertyName"));
        }
    }
    
    internal partial class ImplBase : Base
    {
    }
    
    internal partial class ImplBase
    {
        void someFunc()
        {
            RaiseEvent("propName");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      • 2018-08-31
      • 2020-12-23
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      相关资源
      最近更新 更多