.net CLI嵌套泛型类型和泛型方法

.net CLI嵌套泛型类型和泛型方法,.net,reflection,clr,metadata,.net,Reflection,Clr,Metadata,我是否偶然发现了实现定义的行为 以下是上下文: public class GenericClass<T> { public class NestedGenericClass<U> { public void GenericMethod<K>() { } } } 公共类GenericClass { 公共类嵌套通用类 { public-void-GenericMethod() { } } }

我是否偶然发现了实现定义的行为

以下是上下文:

public class GenericClass<T>
{
    public class NestedGenericClass<U>
    {
        public void GenericMethod<K>()
        {
        }
    }
}
公共类GenericClass
{
公共类嵌套通用类
{
public-void-GenericMethod()
{
}
}
}
这就是行为。此单元测试以书面形式通过。我的实际问题列在“古怪”(在我看来现在)行为之前的评论中

[TestMethod]
public void TestNestedGenericMethod()
{
    Type openType = typeof(GenericClass<>.NestedGenericClass<>);
    Type closedType = typeof(GenericClass<bool>.NestedGenericClass<int>);
    /* Note there is absolutely no representation of the following as a [unique] type, via the
     * typeof operator or the Reflection API, even though the metadata TypeSpec signature
     * should in theory be able to reference it. This is the original reason I wrote these
     * tests.
     *   Type partiallyOpenType = typeof(GenericClass<bool>.NestedGenericClass<>);
     */

    MethodInfo openTypeOpenMethod = openType.GetMethod("GenericMethod");
    MethodInfo closedTypeOpenMethod = closedType.GetMethod("GenericMethod");
    MethodInfo closedTypeClosedMethod = closedTypeOpenMethod.MakeGenericMethod(typeof(long));

    Assert.IsNotNull(openTypeOpenMethod);
    Assert.IsNotNull(closedTypeOpenMethod);
    Assert.IsNotNull(closedTypeClosedMethod);

    Assert.AreNotSame(openTypeOpenMethod, closedTypeOpenMethod);
    Assert.AreNotSame(openTypeOpenMethod, closedTypeClosedMethod);
    Assert.AreNotSame(closedTypeOpenMethod, closedTypeClosedMethod);

    /* What on earth?!
     *  1. Is the following covered in the CLI spec and/or is it implementation-defined?
     *  2. Is there any potential use of this behavior (inside the runtime itself OR outside)?
     *  3. Will I ever hit a MethodDefSig (§23.2.1)/MethodRefSig (§23.2.2)/MethodSpecSig (§23.2.15) that resolves to this?
     */
    MethodInfo openTypeClosedMethod = openTypeOpenMethod.MakeGenericMethod(typeof(long));
    Assert.IsNotNull(openTypeClosedMethod);
    Assert.AreNotSame(openTypeClosedMethod, openTypeOpenMethod);
    Assert.AreNotSame(openTypeClosedMethod, closedTypeOpenMethod);
    Assert.AreNotSame(openTypeClosedMethod, closedTypeClosedMethod);

    Assert.AreSame(closedTypeOpenMethod, closedTypeClosedMethod.GetGenericMethodDefinition());
    Assert.AreSame(openTypeOpenMethod, openTypeClosedMethod.GetGenericMethodDefinition());
}
[TestMethod]
public void TestNestedGenericMethod()
{
类型openType=typeof(GenericClass.NestedGenericClass);
Type closedType=typeof(GenericClass.NestedGenericClass);
/*注意:绝对没有通过
*typeof运算符或反射API,即使元数据TypeSpec签名
*理论上应该可以参考它。这就是我写这些的最初原因
*测试。
*Type partiallyOpenType=typeof(GenericClass.NestedGenericClass);
*/
MethodInfo openTypeOpenMethod=openType.GetMethod(“GenericMethod”);
MethodInfo closedTypeOpenMethod=closedType.GetMethod(“GenericMethod”);
MethodInfo closedTypeClosedMethod=closedTypeOpenMethod.MakeGenericMethod(typeof(long));
IsNotNull(openTypeOpenMethod);
Assert.IsNotNull(closedTypeOpenMethod);
Assert.IsNotNull(closedTypeClosedMethod);
Assert.AreNotSame(openTypeOpenMethod、closedTypeOpenMethod);
Assert.AreNotSame(openTypeOpenMethod,closedTypeClosedMethod);
Assert.AreNotSame(closedTypeOpenMethod,closedTypeClosedMethod);
/*到底是什么?!
*1.CLI规范中是否包含以下内容和/或是否定义了实施?
*2.此行为是否有任何潜在用途(在运行时内部或外部)?
*3.我是否会遇到解决此问题的MethodDefSig(§23.2.1)/MethodRefSig(§23.2.2)/MethodSpecSig(§23.2.15)?
*/
MethodInfo openTypeClosedMethod=openTypeOpenMethod.MakeGenericMethod(typeof(long));
IsNotNull(openTypeClosedMethod);
Assert.AreNotSame(openTypeClosedMethod,openTypeOpenMethod);
Assert.AreNotSame(openTypeClosedMethod,closedTypeOpenMethod);
Assert.AreNotSame(openTypeClosedMethod,closedTypeClosedMethod);
Assert.AreName(closedTypeOpenMethod,closedTypeClosedMethod.GetGenericMethodDefinition());
AreName(openTypeOpenMethod,openTypeClosedMethod.GetGenericMethodDefinition());
}

这并不奇怪:

//void GenericClass<>.NestedGenericClass<>.GenericMethod<Int64>()
openTypeClosedMethod.ContainsGenericParameters = true
openTypeClosedMethod.IsGenericMethodDefinition = false

//void GenericClass<>.NestedGenericClass<>.GenericMethod<K>()
openTypeOpenMethod.ContainsGenericParameters = true
openTypeOpenMethod.IsGenericMethodDefinition = true

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<K>()
closedTypeOpenMethod.ContainsGenericParameters = true
closedTypeOpenMethod.IsGenericMethodDefinition = true

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<Int64>()
closedTypeClosedMethod.ContainsGenericParameters = false
closedTypeClosedMethod.IsGenericMethodDefinition = false

MethodInfo closedGeneratedMethod = closedTypeClosedMethod.GetGenericMethodDefinition();
MethodInfo openGeneratedMethod = openTypeClosedMethod.GetGenericMethodDefinition();

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<K>()
closedGeneratedMethod.ContainsGenericParameters = true
closedGeneratedMethod.IsGenericMethodDefinition = true

//void GenericClass<>.NestedGenericClass<>.GenericMethod<K>()
openGeneratedMethod.ContainsGenericParameters = true
openGeneratedMethod.IsGenericMethodDefinition = true

这并不奇怪:

//void GenericClass<>.NestedGenericClass<>.GenericMethod<Int64>()
openTypeClosedMethod.ContainsGenericParameters = true
openTypeClosedMethod.IsGenericMethodDefinition = false

//void GenericClass<>.NestedGenericClass<>.GenericMethod<K>()
openTypeOpenMethod.ContainsGenericParameters = true
openTypeOpenMethod.IsGenericMethodDefinition = true

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<K>()
closedTypeOpenMethod.ContainsGenericParameters = true
closedTypeOpenMethod.IsGenericMethodDefinition = true

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<Int64>()
closedTypeClosedMethod.ContainsGenericParameters = false
closedTypeClosedMethod.IsGenericMethodDefinition = false

MethodInfo closedGeneratedMethod = closedTypeClosedMethod.GetGenericMethodDefinition();
MethodInfo openGeneratedMethod = openTypeClosedMethod.GetGenericMethodDefinition();

//void GenericClass<bool>.NestedGenericClass<int>.GenericMethod<K>()
closedGeneratedMethod.ContainsGenericParameters = true
closedGeneratedMethod.IsGenericMethodDefinition = true

//void GenericClass<>.NestedGenericClass<>.GenericMethod<K>()
openGeneratedMethod.ContainsGenericParameters = true
openGeneratedMethod.IsGenericMethodDefinition = true

1) 我没有错过那个案例(它的参数是相反的,但我有它)。2) 在我的帖子中,这些检查没有一个是值得注意的,但是我将添加更多,因为它们对API很重要。3) 您没有回答我的3个问题中的任何一个,所有这些问题都涉及到这样一个事实:ECMA-335的.NET Framework实现允许在开放泛型类型中使用封闭泛型方法。我正在努力实现我自己的乐趣标准,我正在努力弄清楚我是否必须支持这个案例。:)好吧,很抱歉这篇“不起眼”的帖子。CLI无处显式禁止开放泛型类型中的封闭泛型方法。它定义泛型方法与其声明类型以及嵌套泛型类型之间的关系。CLI只禁止部分构造的类型和实例化打开的类型,因此我猜该方法不会有多大用处,至少对于实例方法是如此。至于MethodDefSig和其他,为什么不尝试将其发送到动态程序集并从磁盘进行分析呢?1)我没有错过这种情况(它的参数是反向的,但我有)。2) 在我的帖子中,这些检查没有一个是值得注意的,但是我将添加更多,因为它们对API很重要。3) 您没有回答我的3个问题中的任何一个,所有这些问题都涉及到这样一个事实:ECMA-335的.NET Framework实现允许在开放泛型类型中使用封闭泛型方法。我正在努力实现我自己的乐趣标准,我正在努力弄清楚我是否必须支持这个案例。:)好吧,很抱歉这篇“不起眼”的帖子。CLI无处显式禁止开放泛型类型中的封闭泛型方法。它定义泛型方法与其声明类型以及嵌套泛型类型之间的关系。CLI只禁止部分构造的类型和实例化打开的类型,因此我猜该方法不会有多大用处,至少对于实例方法是如此。至于MethodDefSig和其他,为什么不尝试将其发送到动态程序集并从磁盘进行分析呢?