简体   繁体   中英

Invoke derived class methods from base abstract class (reflection)

Consider next situation -

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 {}

Can I invoke xx method using ? 调用xx方法吗?

I know that I can do something like this (checked when is in derived class, not shure for abstract): 在派生类中检查时,不必对抽象进行检查):

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

but I am looking for more faster solutions. Can I use in some way System.Runtime.CompilerServices namespace and in particular CallSite Class ?

Thanks.

You have an instance of the Expression Problem , an extensibility problem common in most programming languages today. Reflection or dynamic invocation is a way around it, but it is prone to bugs, since you will not notice a mistake in naming or parameter types until you run the code down that specific path.

You want to extend your application to support more types (more implementations of IParametr ) and also more operations (in this case more methods using types of parameters).

So basically you will get a matrix of types and operations. Eg

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

The Xes represent requiring the implementation in the type (column) of the operation (row).

To keep the implementation type safe you need to use either the Visitor or the Interpreter pattern. Each has its drawbacks.

The visitor pattern, utilizing 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);
    }
}

If you'd like to get really hardcore you can try Object Algebras

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM