Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;作为「;卡斯特出人意料地失败了_C#_Casting_Delegates - Fatal编程技术网

C# &引用;作为「;卡斯特出人意料地失败了

C# &引用;作为「;卡斯特出人意料地失败了,c#,casting,delegates,C#,Casting,Delegates,我正在做一些奇怪的泛型工作,包括对委托类型进行大量转换,在大多数情况下,它工作得非常好。 然而,我遇到了无法找到原因的铸造失败。 这是我的方法和下面的调试数据 public static T GetInvokableDelegate<T>(string name) where T : class { return DelRegistry[name].GetSelectedMethod() as T; //DelRegistry[name

我正在做一些奇怪的泛型工作,包括对委托类型进行大量转换,在大多数情况下,它工作得非常好。
然而,我遇到了无法找到原因的铸造失败。
这是我的方法和下面的调试数据

    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)}}
所以基本上说它不能投

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


那么,为什么到目前为止,这一角色扮演成功了数百次呢?

代理分配是基于签名的,但角色扮演不是。因此,如果在第二种情况下,T委托类型不同,则强制转换“失败”是预期的行为

要转换委托类型,请使用类似于的代码


编辑:在读取带有强制转换异常数据的编辑后,我敢打赌,您的代码以某种方式加载了持有AIDECore的程序集的多个不同版本。控制器类型-检查这些类型。

那么,什么是
T
,什么是
DelRegistry[name]。SelectedMethod()
返回?你能编辑它使之成为一个实际显示问题的可运行示例吗?正如我在评论中所说,在本例中,T是一个System.Action。我会更新这个问题,你可以试着用一个普通的演员阵容来替换“as”。这应该会给您一个异常,详细说明强制转换失败的原因。我的理解/假设是,方法的强制转换是基于签名完成的,并且对于大多数使用此特定方法的人来说,它工作得很好。您可以尝试强制转换并看到异常被抛出。是的,它确实加载不同版本的AIDECore.Controller类型。这就是我项目的全部要点。到目前为止,它工作得很好,有我想要加载的尽可能多的版本。这个GetInvokeableDelegate基本上是一个间接层,允许我将委托指向我想要的任何动态加载的汇编方法。因此,您的问题实际上与委托无关,而实际上与加载不同类型(尽管名称相同)有关。您需要确保这始终加载相同的类型;请看一下这样做的原因。如果对延迟绑定的委托调用了
Invoke
,调用也将不起作用-参数的类型错误。如果它“用于工作”,那么工作的代码必须指向同一版本的AIDECore程序集。啊,谢谢,这似乎是正确的。我仍然不清楚是否可以实际使用重定向策略来进行运行时类型替换,或者这只是在启动时进行的?而且,我不确定是否需要向后或向前重定向。类型的新版本包含的方法将接受与参数类型相同的旧版本。
[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'.