.Net Standard 1.4 中的动态调度

Dynamic Dispatch in .Net Standard 1.4

我过去曾在 .Net 中使用动态调度来完成诸如事件溯源之类的事情。您可以在例如中看到该方法this article from 2009

简而言之,您有一个基本事件类型

public class Event {}

和特定事件

public class QuestionAsked : Event {}
public class QuestionAnswered : Event {}

其他一些 class 可以只使用 Event 的可枚举来应用它们

// snip

public void Apply(IEnumerable<Event> events) => events.ToList().ForEach(Apply);

public void Apply(Event ev) => ((dynamic) this).Apply((dynamic) ev);

private void Apply(QuestionAnswered qa) {
 //something
}
// end snip

此 class 不需要每个类型都有一个 Apply 方法。它只是忽略它不关心的任何事件。

我刚刚尝试使用 .NetStandard 1.4 做同样的事情,如果我尝试应用没有私有 Apply 方法的类型,我会得到一个 WhosebugException

.Net 4.5.x 和 .Net(核心|标准)之间的动态调度是否发生了变化?我不能再使用这种方法了吗?

好吧,公开学习的一个缺点是有时您会发现自己错了:)

我在 .Net 4 中尝试了相同的代码。5.x 但它也失败了 - 我显然将我过去使用的安全代码与这个不安全的代码混为一谈。

这真的只是 if there is a method called Apply that takes this type as an argument then invoke it 的简洁表达所以...

public void Apply(IEnumerable<Event> events) => events.ToList().ForEach(Apply);

public void Apply(Event ev)
{
    GetType()
        .GetRuntimeMethods()
        .Where(mi => mi.IsPrivate)
        .Where(mi => mi.Name == "Apply")
        .Where(mi => mi.GetParameters().Length == 1)
        .SingleOrDefault(mi => mi.GetParameters().SingleOrDefault()?.ParameterType == ev.GetType())
        ?.Invoke(this, new[] {ev});
}

我的测试通过了该代码。 IE。具有方法的事件被应用,没有的事件被忽略。

显然,在 真实的 应用程序中,您只需要找到方法一次,然后在每次调用时检查它们,但我将把它作为练习留给 reader;P