让我们假设以下继承图:
A<-B<-C<-D<-E<-。。。(继承树实际上比这个例子更复杂,它包含数百个实际类型(我不拥有这些类型,也无法控制它们的实现
我们还假设一组静态方法:
我当前的Handle(A A(实现通过使用dynamic
关键字"分派"到所需的方法:
public static void Handle(A a)
{
Handle((dynamic)a);
}
public static void Handle(B b)
{
//B specific processing
}
//And so on
主机应用程序向我发送A[]
中的对象,尽管每个对象可以具有不同的运行时类型。目前,我甚至对A
类型的对象都不感兴趣。
我需要不同的Handle
方法,因为客户想要执行的处理根据对象的运行时类型而不同。
只要我的代码中有一个Handle
方法,并为我传入的对象的运行时类型提供相应的签名,我的实现就可以很好地工作,但目前的情况是,当传递的对象没有特定的Handle
方法时,Handle(A a)
方法会被递归调用,导致堆栈溢出。
显然,我不能为主机应用程序传递的大约一百种类型中的每一种定义Handle(X x)
方法,而该主机应用程序的API的每个后续版本都可以定义新的类型。
因此,我的问题是,如何处理没有特定Handle
方法的类型,而不必执行一系列没完没了的if
语句,甚至是一个长的switch
语句,来筛选我没有处理程序方法的对象?
在运行时,是否有任何方法可以确定传入对象的运行时类型是否真的存在Handle
方法?或者还有其他方法可以干净地处理"缺失"的方法吗?
欢迎任何见解/建议。
我不记得从哪里得到了在Handle(A a)
中调度的想法。我记得在一些网站上看到过这样的东西,但我现在意识到,它一定适用于与我试图实现的不同的用例。
我只需将强制转换(dynamic)obj
移到"Handling"方法之外,然后返回到调用方:上,就解决了这个问题
Logger.Handle((dynamic)obj);
在我的实现中,层次结构基础的方法现在只是一个空方法:
public class Logger
{
public static void Handle(A a){}
public static void Handle(B b)
{
//B specific handling
}
//All other Handle methods
}
这就解决了问题。如果派生类型不存在特定的方法,则调用Handle(A a)
方法,不执行任何操作。