从基本抽象类调用派生类方法(反射)

Posted

技术标签:

【中文标题】从基本抽象类调用派生类方法(反射)【英文标题】:Invoke derived class methods from base abstract class (reflection) 【发布时间】:2014-02-13 23:45:18 【问题描述】:

考虑下一种情况 -

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 在派生类中时检查,而不是抽象的舒尔):

InvokeX(IParametr @param)
    ((dynamic) this).X((dynamic) @param);

但我正在寻找更快的解决方案。我可以以某种方式使用 System.Runtime.CompilerServices 命名空间,特别是 CallSite Class?

谢谢。

【问题讨论】:

【参考方案1】:

您有一个Expression Problem 的实例,这是当今大多数编程语言中常见的可扩展性问题。反射或动态调用是一种解决方法,但它很容易出现错误,因为在沿着特定路径运行代码之前,您不会注意到命名或参数类型的错误。

您希望扩展您的应用程序以支持更多类型(IParametr 的更多实现)和更多操作(在这种情况下,更多方法使用参数类型)。

所以基本上你会得到一个类型和操作的矩阵。例如

Type     Derived     Derived2   ...
ParamX     x            x
ParamY                  x
...

X 表示需要在操作(行)的类型(列)中实现。

为了保证实现类型的安全,您需要使用访问者模式或解释器模式。每个都有其缺点。

访问者模式,利用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

【讨论】:

以上是关于从基本抽象类调用派生类方法(反射)的主要内容,如果未能解决你的问题,请参考以下文章

派生自抽象基类并调用另一个类中的方法的 C++ 包装类,该类也派生自抽象基类

允许派生类从基本抽象类实现单个纯虚函数

如果从抽象类派生,则无法使用具体类指针调用函数

“从 PlaceSelectionListener 派生的匿名类”类必须声明为抽象或实现抽象方法

如何反射抽象类

使用具有抽象基类指针并调用派生类函数的映射