3

我试图让ldtokenIL 方法在泛型类中加载泛型方法的泛型实例化(例如,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 上复制了它)

4

1 回答 1

1

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

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

ldtoken 方法实例
    类 [mscorlib]System.Collections.Generic.List`1<!!0>
    类 [mscorlib]System.Collections.Generic.List`1<object>::ConvertAll<[1]>(
        类 [mscorlib]System.Converter`2<!0,!!0>)
ldtoken 方法实例
    类 [mscorlib]System.Collections.Generic.List`1<!!0>
    类 [mscorlib]System.Collections.Generic.List`1<object>::ConvertAll<string>(
        类 [mscorlib]System.Converter`2<!0,!!0>)

但不适用于未实例化的泛型类型。ECMA CLI 规范的第 II 部分第 9.4 节指出

CLI 不支持泛型类型的部分实例化。并且泛型类型不应在元数据签名 blob 中的任何位置出现未经实例化。

所以也许这并不奇怪——似乎没有任何方法可以将 ldtoken 与typeof(List<>).GetMethod("ConvertAll").

于 2012-05-29T21:27:20.540 回答