考虑下一个情况 -
public class Derived : Base{
X(ParamX){} // xx method
X(ParamY){} // xy
}
public abstract class Base {
InvokeX(IParametr param){
...some magic
}
}
public class ParamX : IParametr {}
public class ParamY : IParametr {}
我可以使用 Derived.InvokeX(ParamX)调用xx方法吗?
我知道我可以做这样的事情(当 InvokeX 在派生类中时检查,而不是抽象的shure):
InvokeX(IParametr @param){
((dynamic) this).X((dynamic) @param);
}
但我正在寻找更快的解决方案。我可以以某种方式使用System.Runtime.CompilerServices命名空间,特别是CallSite Class吗?
感谢。
答案 0 :(得分:2)
您有Expression Problem的实例,这是当今大多数编程语言中常见的可扩展性问题。反射或动态调用是一种解决方法,但它很容易出现错误,因为在您按照特定路径运行代码之前,您不会注意到命名或参数类型的错误。
您希望扩展您的应用程序以支持更多类型(更多IParametr
的实现)以及更多操作(在这种情况下,使用参数类型的更多方法)。
所以基本上你会得到一个类型和操作的矩阵。 E.g。
Type Derived Derived2 ...
ParamX x x
ParamY x
...
Xes表示要求在操作(行)的类型(列)中实现。
要确保实现类型安全,您需要使用Visitor或Interpreter模式。每个都有它的缺点。
访客模式,使用double dispatch:
public class Derived : Base {
public override void X(ParamX x) { }
public override void X(ParamY a) { }
}
public abstract class Base : IXVisitor
{
public void Visit(IParametr parameter)
{
parameter.Accept(this);
}
public abstract void X(ParamX x);
public abstract void X(ParamY a);
}
public interface IXVisitor
{
void X(ParamX a);
void X(ParamY a);
}
public interface IParametr
{
void Accept(IXVisitor visitor);
}
public class ParamX : IParametr
{
public void Accept(IXVisitor visitor)
{
visitor.X(this);
}
}
public class ParamY : IParametr
{
public void Accept(IXVisitor visitor)
{
visitor.X(this);
}
}
如果您想获得真正的铁杆,可以尝试Object Algebras