从基动态调用父方法失败,由于其保护级别的原因无法访问

本文关键字:访问 保护 于其 调用 动态 方法 失败 | 更新日期: 2023-09-27 18:01:13

我正试图通过(this as dynamic).When(e)从基类动态调用父级上的方法,但我遇到了一个关于保护级别的错误:

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll
Additional information: 'Person.When(PersonCreated)' is inaccessible due to its protection level

Person类是公共的,将Person.When(PersonCreated)更改为公共会产生新的错误The best overloaded method match for 'Person.When(PersonCreated)' has some invalid arguments。。。

我想要实现的是通过基Apply(e)方法将事件"路由"到父类的When(e)方法。

理想情况下,库中的When方法不应该是公共的。

毫无疑问,我在做一些非常愚蠢的事情。。。有什么想法吗?或者我需要用反思代替吗?

public abstract class EventSourcedAggregate
{
    readonly List<DomainEvent> mutatingEvents = new List<DomainEvent>();
    public readonly int UnmutatedVersion;
    protected void Apply(DomainEvent e)
    {
        this.mutatingEvents.Add(e);
        // the below line throws inaccessible protection level
        (this as dynamic).When(e);
    }
}
public abstract class DomainEvent
{
    // snipped some time stamp stuff not relevant here
}
public class PersonCreated : DomainEvent
{
    public readonly string Name;
    public readonly string Address;
    public PersonCreated(string name, string address)
    {
        Name = name;
        Address = address;
    }
}
public class Person : EventSourcedAggregate
{
    public Person(string name, string address)
    {
        Apply(new PersonCreated(name, address));
    }
    public string Name { get; private set; }
    public string Address { get; private set; }
    void When(PersonCreated e)
    {
        Name = e.Name;
        Address = e.Address;
    }
}
static void Main(string[] args)
{
    var user = new Person("sir button", "abc street");
}

从基动态调用父方法失败,由于其保护级别的原因无法访问

请注意,当When()方法变为public时,会得到不同的异常。也就是说,它现在可以访问,但您没有传递正确的类型。

声明的When()方法需要PersonCreated的实例。但是您的呼叫站点只传递DomainEvent的一个实例。

一般来说,dynamic遵循通常在编译时执行的运行时行为。但除此之外,你必须遵循同样的规则。由于编译器不能保证DomainEventPersonCreated的实例,因此会出现错误(或者更具体地说,DomainEvent与方法的已知重载不匹配(。

你应该能够通过这样调用来让代码工作:

(this as dynamic).When(e as dynamic);

也就是说,让运行时基于e的动态类型而不是静态类型进行绑定。