Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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#_Generics_Reflection - Fatal编程技术网

C#:泛型类中的嵌套类是否应被视为泛型类?

C#:泛型类中的嵌套类是否应被视为泛型类?,c#,generics,reflection,C#,Generics,Reflection,这将打印出: IsGeneric:True具有一般参数: 真的 我不完全同意这种行为。即使编译器为NestedNonGenericClass生成泛型类型,我还是想知道它是泛型类型,是因为声明了泛型,还是因为它的容器是泛型的 所以,我的问题是: 首先,您认为考虑嵌套类泛型是否可以,因为它的容器是通用的吗?为什么 其次,您是否知道其他一些API可以帮助我仅识别声明为泛型的类 附言:在泛型的ECMA规范中,我找不到任何与此相关的东西(或者我只是掩饰了一下) --编辑-- 为了添加更多的上下文,我正在开

这将打印出:

IsGeneric:True具有一般参数: 真的

我不完全同意这种行为。即使编译器为
NestedNonGenericClass
生成泛型类型,我还是想知道它是泛型类型,是因为声明了泛型,还是因为它的容器是泛型的

所以,我的问题是:

首先,您认为考虑嵌套类泛型是否可以,因为它的容器是通用的吗?为什么

其次,您是否知道其他一些API可以帮助我仅识别声明为泛型的类

附言:在泛型的ECMA规范中,我找不到任何与此相关的东西(或者我只是掩饰了一下)

--编辑--

为了添加更多的上下文,我正在开发一种代码生成器。我使用反射API来确定类型是否为泛型

我遇到了一个关于
Dictionary.KeyCollection
的问题

对于
KeyCollection
,反射API表示它是通用的,并将容器中声明的
TKey
TValue
交给我。因此,生成器最终生成
Dictionary.KeyCollection


解决这个问题的唯一方法是将嵌套类的模板参数与容器的模板参数进行匹配,并消除所有匹配的模板参数。但是我想知道是否有更好的方法。

简言之,是的-类型从包含它的任何类型继承类型参数:这是
列表、枚举器和许多其他场景等的关键-它们共享外部类的
T
(不仅仅是任何
T
)非常关键

ECMA参考文件为§25.1:

嵌套在泛型中的任何类 类声明或泛型结构 声明(§25.2)本身就是 泛型类声明,自类型 包含类型的参数 应提供,以创建 构造类型


如果您不打算在NestedNonGenericClass中使用T,您可以将其放在类之外,并将其设置为私有。。那么它就不是泛型的了。…

是的,您的嵌套类绝对是泛型的,因为T绑定到嵌套类的任何实例范围内的类型(这称为封闭泛型)

namespace GenericsTest
{
    public class AGenericClass<T>
    {
        public class NestedNonGenericClass
        {
        }
    }
}
Type nestedClass = typeof(AGenericClass<int>.NestedNonGenericClass);
Console.Out.WriteLine("IsGeneric: {0}\tHasGenericArguments: {1}", 
   nestedClass.IsGenericType, nestedClass.GetGenericArguments().Length > 0);
使用系统;
使用System.Collections.Generic;
公共类代理类{
嵌套的公共类非通用类{
公共无效剂量测定法(){
控制台写入线(“typeof(T)=”+typeof(T));
}
}
}
公共类MyClass{
公共静态void Main(){
var c=new AGenericClass.NestedNonGenericClass();
var d=新的AGenericClass.NestedNonGenericClass();
c、 DoSomething();
d、 DoSomething();
Console.ReadKey(false);
}
}

相同的
DoSomething()
方法根据泛型类型的关闭方式产生不同的输出-因此,是的,内部类肯定表现出泛型行为。

我选择的理解方式是,当使用泛型类型时,C#生成该类型中的所有内容。所以说真的,如果我想想象一下,如果我使用上面例子中的AGenericClass和AGenericClass,会生成什么,那么最终会得到嵌套类的两个副本:

using System;
using System.Collections.Generic;

public class AGenericClass<T> {
    public class NestedNonGenericClass {
        public void DoSomething() {
            Console.WriteLine("typeof(T) == " + typeof(T));
        }
    }
}

public class MyClass {
    public static void Main()   {
        var c = new AGenericClass<int>.NestedNonGenericClass();
        var d = new AGenericClass<DateTime>.NestedNonGenericClass();
        c.DoSomething();
        d.DoSomething();
        Console.ReadKey(false); 
    }

}
公共类代理类
{
嵌套的公共类非通用类
{
}
}
公共类代理类
{
嵌套的公共类非通用类
{
}
}

因为这样,我会考虑嵌套类是泛型类,因为它有两个版本,一个叫做AGenericClass.NestedNonGenericClass,另一个被称为AgEnnICCuth.NeStdEngNoNICC类。实际上,这就像您明确指定嵌套类也是泛型。如果希望嵌套类适应泛型类型,则此行为非常有用


然而,我发现我不能再像在普通类上那样使用嵌套类了,这很烦人。很抱歉,我再也记不起确切的例子了,但我知道有一次我不得不将一个类从泛型中移出,以便我可以从代码中的其他地方使用它。它违背了我用于嵌套类的常规模式,因此我不喜欢它,但这是唯一的方法。所以我可以理解,如果你可能不同意这样做,但老实说,我认为这样做是最清楚的方式。我的意思是,你和编译器都很清楚,如果你把嵌套类移到外面,把它作为一个普通类,你就不希望编译器把它作为泛型生成。我认为他们无法在这方面有所改进

谢谢:)这回答了我的问题。但是,有没有办法区分使用泛型模板声明的类和刚从容器继承泛型模板的类?好的,您可以看到包含类型的类型参数有多少(必要时递归),并将其与嵌套类型中的类型参数数相比较。是的,这就是我目前正在做的。但我希望有更好的方法。将模板参数与包含的类进行匹配会让人觉得有点难看:D@Jon,不需要递归,因为包含的类型已经插入了其容器的类型参数。。我在Dictionary.KeyCollection中遇到了这个问题,因为反射API返回容器的模板参数,我的生成器最终生成Dictionary.KeyCollection:(是的,我同意内部类显示泛型行为。但是有没有一个好方法来确定某个类型是否因为容器而变为泛型?
public class AGenericClass<int>
{
    public class NestedNonGenericClass
    {
    }
}

public class AGenericClass<float>
{
    public class NestedNonGenericClass
    {
    }
}