【问题标题】:If A<T1,T2> is a template for actual type, then why is typeof(A<,>) allowed?如果 A<T1,T2> 是实际类型的模板,那么为什么允许 typeof(A<,>) ?
【发布时间】:2011-03-14 07:47:36
【问题描述】:
class Program
{
    static void Main(string[] args)
    {
        Type t = typeof(A<,>);
        Console.WriteLine(typeof(A<,>)); // prints A'2[T1,T2]
    }    
}

class A<T1,T2>
{

}

据我所知,泛型类型A&lt;T1, T2&gt; 不是实际类型,而是实际类型的蓝图/模板,那么为什么typeof 接受它作为参数(据我所知, typeof 接受作为参数的实际类型)?

谢谢

【问题讨论】:

  • 很好的问题 +1

标签: c# generics


【解决方案1】:

它被接受是因为它是一个泛型类型。

它是一个开放的泛型类型(没有指定类型参数),但仍然是一个类型。

参见here 的讨论(究竟什么是“开放泛型类型”)。

MSDN(类型)上:

typeof 运算符也可用于开放的泛型类型。

【讨论】:

  • @flockofcode - 1. 开放的泛型类型是类型。如果不提供类型参数,它们就无法实例化,但它们仍然是类型。 2. 开放式构造类型是指没有指定至少一种泛型类型。见这里:en.csharp-online.net/Generic_types
  • @flockofcode - 1. 为什么不呢?形式参数可以是开放构造的泛型类型。在运行时,您当然必须通过一个封闭的泛型类型。 2. 我会说开放构造的泛型类型是开放泛型类型的子集。所以,一些开放构造的泛型类型也是开放的泛型类型。
  • @flockofcode 您可以将开放的泛型类型视为抽象的 - 它是构建具体泛型类型的不可实例化基础。
  • @flockofcode - public void MethodAccessException(OpenConstructed&lt;T,int&gt; con){}。形式参数是一个开放构造的泛型类型。您必须使用指定的第一个类型参数创建一个实例并将其传入 - new OpenConstructed&lt;string,int&gt;()
  • @Oded:你不能这样做,但你可以这样做:public void MethodAccessException&lt;T&gt;(OpenConstructed&lt;T,int&gt; con){} C# 不像 Java 那样进行类型擦除,所以当有未确定的类型参数时,接受参数的方法必须是在某些方面也是泛型的(它同样可以是泛型类的成员)。
【解决方案2】:

因为A&lt;T1, T2&gt; 是一个开放的泛型,documentation 明确表示它支持。

【讨论】:

  • 开放泛型和开放构造泛型有什么区别?
【解决方案3】:

reflection 中,未构造的泛型类型,比如 C&lt;&gt;instance 类型 C&lt;T&gt; 混为一谈。

这可能不是理论上的纯粹;我认为这些是非常不同的实体。我认为一个是符号“带有一个类型参数的C”,另一个是编译时类型C&lt;T&gt;。在代码中,C&lt;&gt;C&lt;T&gt; 不是彼此的同义词;如果 T 在范围内,则可以创建后一种类型的字段,但不能创建前一种类型的字段。

当您请求非构造类型时,反射库会为您提供实例类型的类型,但这并不全是坏事。对于非构造类型,您会做什么?你真的无能为力。但是对于实例类型,你可以在这里说“用 int 代替 T”。

当您请求typeof(C&lt;&gt;) 时,获得C&lt;T&gt; 的真正好处在于,它始终为您提供非构造类型。比较:

class C<T>
{
    public static Type CT() { return typeof(C<T>); }
    public static Type JustC() { return typeof(C<>); }
}

当你打电话给 CT 时,你打算怎么称呼它on?没有类型 C&lt;T&gt; 可以调用 CT。你可以打电话给C&lt;int&gt;.CT,在这种情况下你会得到C&lt;int&gt;,而不是C&lt;T&gt;。获得用 T 构造的类型 C&lt;&gt; 的唯一方法是请求 typeof(C&lt;&gt;)

这有意义吗?

我还没有介绍反射(我对反射是什么有一个模糊的概念)

Reflection 只是一个代码库,可让您在代码本身中获取有关代码的信息。 "typeof" 为您提供一个 Type 对象,然后您可以“反映”该对象以查找有关该类型的信息。

我不确定我是否理解“即使 T 不在范围内”的意思

我说的方式令人困惑。我已经改写了。

【讨论】:

  • 1 - “这有意义吗?”有点,但我还没有涉及反射(我对反射是什么有一个模糊的概念)而且我更愚蠢。 2 - “真正的好处是 typeof(C) 让你获得 C 的类型对象,即使 T 不在范围内”我不确定我理解你的意思是什么“即使 T 是不在范围内”? 2 - “当您请求非构造类型时,反射库会为您提供实例类型的类型,但这并不全是坏事。“我假设您在这里不是在谈论 typeof(A),因为这并不't 给你一个 A 类型的实例
  • “当您请求非构造类型时,反射库会为您提供实例类型的类型,但这并不全是坏事。”您使用的术语有点令人困惑。你说 typeof(C) 返回实例类型的类型,因此它返回 C 的类型,其中 T 尚未指定。因此,据我了解,您是在暗示 C 是一个实例类型,而据我所知,实例类型的所有类型参数都已确定?!
  • @flockofcode:确实,术语非常令人困惑。规范将泛型类型的“实例类型”定义为使用其类型参数构造的类型的编译时类型。例如,在类 C { C x; } x 的compile time 类型是C-with-one-type-parameter 的instance type。 x 的运行时类型当然取决于替换 T 的类型参数
  • 嗯,我认为泛型类型的实例类型只是封闭构造的泛型类型的另一种说法,但是“x的编译时类型是C-with-one-type-parameter的实例类型.x 的运行时类型当然取决于替换 T 的类型参数”表明情况并非如此
  • @flockofcode:请参阅 C# 规范的第 10.3.1 节。
猜你喜欢
  • 2011-09-22
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多