.NET bug:ldtoken实例化的泛型方法

时间:2012-05-29 13:34:02

标签: .net generics cil

我正在尝试使用ldtoken IL方法在泛型类中加载泛型方法的泛型实例化(例如,List.ConvertAll<TOutput>):

ldtoken method instance
    class [mscorlib]System.Collections.Generic.List`1<!!0> 
    [mscorlib]System.Collections.Generic.List`1::ConvertAll<string>(
        class [mscorlib]System.Converter`2<!0,!!0>)

这会导致异常:

  

未处理的异常:System.TypeLoadException:无法从程序集'TestAssembly,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'加载类型'System.Collections.Generic.List`1'。

它正在我的测试程序集中查找System.Collections.Generic.List,即使它已在mscorlib中明确声明!

但是,加载未实例化的方法令牌有效:

ldtoken method instance
    class [mscorlib]System.Collections.Generic.List`1<!!0> 
    [mscorlib]System.Collections.Generic.List`1::ConvertAll<[1]>(
        class [mscorlib]System.Converter`2<!0,!!0>)

非泛型类中的泛型方法有效:

ldtoken method void [mscorlib]System.Array::Sort<object>(!!0[])
ldtoken method void [mscorlib]System.Array::Sort<[1]>(!!0[])

发生了什么事?这是.NET中的错误吗? (我在v2和v4 CLR上复制了它)

1 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,我认为你需要实例化泛型类型(即没有System.Collections.Generic.List`1这样的类型 - 只有System.Collections.Generic.List`1<object>等。)

通过使用System.Reflection.Emit,看起来可以在实例化的泛型类型上使用带有实例化或未实例化方法的ldtoken:

ldtoken method instance 
    class [mscorlib]System.Collections.Generic.List`1<!!0> 
    class [mscorlib]System.Collections.Generic.List`1<object>::ConvertAll<[1]>(
        class [mscorlib]System.Converter`2<!0,!!0>)
ldtoken method instance 
    class [mscorlib]System.Collections.Generic.List`1<!!0> 
    class [mscorlib]System.Collections.Generic.List`1<object>::ConvertAll<string>(
        class [mscorlib]System.Converter`2<!0,!!0>)

但不是未实例化的泛型类型。分区II,ECMA CLI规范的第9.4节说明了

  

CLI不支持泛型类型的部分实例化。和   泛型类型不应在元数据中的任何位置显示为未实例化   签名blob。

所以也许这并不奇怪 - 似乎没有任何方法可以使用等同于typeof(List<>).GetMethod("ConvertAll")的ldtoken。