创建down-casted类的Delegate以传递给Base类上的函数

时间:2016-02-24 21:30:37

标签: c# delegates

我试图在我的子类ExchangeA上创建一个非静态方法的委托。然后,我想将此委托方法传递给基类Exchange上的另一个非静态方法。我说非静态因为,首先,它们是,其次,我在网上找到的例子主要是静态方法。

我已经寻求this作为资源。

public class Exchange {
    public int retrieve( string szLevel, string szJson, Func<string, string, Instrument> delegateMethod) {
        // ...
        Instrument instrument = delegateMethod(szLevel, szJson)
        // ...
        return someInt;
    }
}

public class ExchangeA : Exchange {
    public Instrument instrumentDataProcess( string szLevel, szJson ) {
        // ...
        return someInstrument;
    }
}

public class Instrument { ... }

public class DoStuff {
    public static Exchange ExchangeHandler( my args ) {
        Exchange oExchange = new ExchangeA(); // Could also be ExchangeB or ExchangeC being instantiated here

        Type type = oExchange.GetType(); // type == ExchangeA

        System.Reflection.MethodInfo methodInfo = type.GetMethod( "instrumentDataProcess" );

        Func<string, string, Instrument> delegateFunc = (Func<string, string, Instrument>)Delegate.CreateDelegate(typeof(Func<string, string, Instrument>), methodInfo); // fails here at runtime

        iRet = (int)type.InvokeMember( "retrieve", System.Reflection.BindingFlags.InvokeMethod, null, oExchange, new object[] { szLevel, szCurrencyBase, delegateFunc });

        if (iRet == 0)
            return nil;
        return oExchange;
    }
}

在调用CreateDelegate()方法时执行失败。

错误说:

  

类型&#39; System.ArgumentException&#39;的例外情况发生在   mscorlib.dll但未在用户代码中处理

     

其他信息:无法绑定到目标方法,因为它   签名或安全透明度与   代表类型。

签名或安全透明度?我已经知道了方法签名,因为我定义了它并且我不了解安全透明度意味着什么...我通常不是C#dev。我的所有类和函数都被声明为public。

所有评论和建议都很有价值!我想学习C#的废话! ;)

更新

目前的建议是将方法组作为参数传递给我的检索方法。这对我来说是一个新概念,我不确定它是如何完成的。参数类型Func<string, string, Instrument>是否仍适用?

1 个答案:

答案 0 :(得分:0)

您根本不需要委托,您只需指定方法组:

public class Exchange {
    public int retrieve( string szLevel, string szJson, Func<string, string, Instrument> delegateMethod) {
        // ...
        Instrument instrument = delegateMethod(szLevel, szJson)
        // ...
        return someInt;
    }
}

public class ExchangeA : Exchange {
    public Instrument instrumentDataProcess( string szLevel, szJson ) {
        // ...
        return someInstrument;
    }
}

public class Instrument { ... }

public class DoStuff {
    public static Exchange ExchangeHandler( my args ) {
        Exchange oExchange = new ExchangeA(); // Could also be ExchangeB or ExchangeC being instantiated here

        iRet = oExchange.retrieve(szLevel, szCurrencyBase, oExchange.instrumentDataProcess);

        if (iRet == 0)
            return nil;
        return oExchange;
    }
}