【问题标题】: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

谢谢。

【问题讨论】:

    标签: c# reflection abstract-class invokemember


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2014-03-17
      相关资源
      最近更新 更多