Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从基动态调用父方法失败,由于其保护级别不可访问_C#_System.reflection - Fatal编程技术网

C# 从基动态调用父方法失败,由于其保护级别不可访问

C# 从基动态调用父方法失败,由于其保护级别不可访问,c#,system.reflection,C#,System.reflection,我正试图通过从基类动态调用父类上的方法(这是动态的)。当(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 protect

我正试图通过
从基类动态调用父类上的方法(这是动态的)。当(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
类是public类,将
Person.When(PersonCreated)
更改为public会产生一个新错误
与“Person.When(PersonCreated)”匹配的最佳重载方法具有一些无效参数

我想要实现的是通过基
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");
}
公共抽象类eventSourceDaggerate
{
只读列表mutatingEvents=新列表();
公共只读int未修改版本;
受保护的无效应用(域事件e)
{
本.mutatingEvents.Add(e);
//下面的行抛出不可访问的保护级别
(这是动态的)。当(e);
}
}
公共抽象类DomainEvent
{
//剪下了一些与这里无关的时间戳
}
已创建的公共类PersonCreated:DomainEvent
{
公共只读字符串名称;
公共只读字符串地址;
public PersonCreated(字符串名称、字符串地址)
{
名称=名称;
地址=地址;
}
}
公共类人士:EventSourceDaggerate
{
公众人物(字符串名称、字符串地址)
{
申请(新创建的人员(姓名、地址));
}
公共字符串名称{get;private set;}
公共字符串地址{get;private set;}
当(个人创建时)无效
{
名称=e.名称;
地址=e.地址;
}
}
静态void Main(字符串[]参数)
{
var用户=新用户(“sir按钮”、“abc街”);
}

请注意,如果将
when()
方法设置为
公共
,则会出现不同的异常。也就是说,它现在可以访问,但您没有传递正确的类型

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

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

您应该能够通过如下调用使代码正常工作:

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

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

公开后,我会得到一个不同的错误。您应该查看错误:
与“UserQuery.Person.When(UserQuery.PersonCreated)”匹配的最佳重载方法有一些无效参数
是否有理由强制转换为动态并调用该方法?为什么不把
When
作为一个抽象方法并利用模板呢?如果我在
时使用不同的参数
When
当(PersonCreated e)
当(PersonMoved e)
当(PersonMarried e)
等重载了超过1个参数,那么这样做行吗?我目前正在使用它来调度(它是有效的),但希望有一个编译安全的方式!var
dispatchTo=o.GetType().GetMethod(“When”,BindingFlags.NonPublic | BindingFlags.Instance,null,new[]{e.GetType()},null);调用(o,新对象[]{e})@g18c有一种编译安全的方法,但您需要给编译器更多的提示。例如,您需要编写
Apply(personCreated,When),而不是
Apply(personCreated),它将在您需要时正确地以方法为目标。这里有一个例子:。每次都要通过Where参数有点不好,但这会使其类型安全,并且可能会优化得更好。太棒了,谢谢大家,非常感谢你们,凌晨2点在这里,拔头发。这确实有效-因此类的内部工作可以得到保护,是否可以在不公开的情况下在父类中调用
When()
?或者我需要通过反射来调用内部方法吗?不,
protected
也不起作用。您可以通过
internal
,但不清楚这是否足以保护该成员。一般来说,我认为您应该避免使用反射和
dynamic
。这看起来是一个通过接口甚至强制转换更好地解决的问题<当您无法控制抽象的实现时(例如COM互操作,这是
dynamic
首先存在的主要原因),code>dynamic
是一个很好的后备方案,但通常您会这样做,IMHO应该这样做。