“因为”演员出乎意料地失败了

时间:2012-08-15 07:06:38

标签: c# casting delegates

我正在做一堆奇怪的通用内容,包括做很多委托类型的演员表,而且大部分都是完美的工作。
但是,我遇到了无法找到原因的演员失败 这是我的方法,并遵循调试数据。

    public static T GetInvokableDelegate<T>(string name) where T : class
    {
        return DelRegistry[name].GetSelectedMethod() as T;
        //DelRegistry[name].GetSelectedMethod() returns System.Object, 
        //which may be any flavor of Func<> or Action<>
    }
    //These two pairs represent the values from the Debug view, 
      //of T and GetSelectedMethod() respectively

    //This is when DelRegistry is returning the initial result from GetSelectedMethod():  This cast As T works fine.

    //System.Action<string,AIDECore.Controller>   
    //{Method = {Void HAL_TestMethod(System.String, AIDECore.Controller)}}    

    //This is after the second call,  GetSelectedMethod() is returning a different delegate, but with identical signature:  This one fails

    //System.Action<string,AIDECore.Controller>
    //{Method = {Void HAL_TestMethod(System.String, AIDECore.Controller)}}

在运行时检查值表明它们看起来是相同的。指定的强制转换第一次工作,第二次失败。 值得注意的是:它不是被调用导致它失败的次数。在其他测试用例中,我已经向DelRegistry添加了几十个委托版本而没有任何问题。

我的问题是,你能得到错误输出,为什么“As”演员会失败? (失败意味着返回null)

投放例外数据:

[A]System.Action`2[System.String,AIDECore.Controller] cannot be cast to [B]System.Action`2[System.String,AIDECore.Controller].
Type A originates from 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'.
Type B originates from 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'.

所以基本上说它不能投。

对于记录,从第一个后面的GetSelectedMethod()返回的所有版本都来自动态加载的程序集。

那么为什么这个演员到目前为止已经好几百次?

1 个答案:

答案 0 :(得分:1)

委托作业基于签名,但演员表不是。因此,如果在第二种情况下T委托类型不同,则演员“失败”是预期的行为。

要转换委托类型,请使用this之类的代码。

编辑:在使用强制转换异常数据阅读编辑后,我的赌注是你的代码以某种方式加载了持有AIDECore.Controller类型的程序集的多个不同版本 - 检查这些类型。