15

According to this answer at stackoverflow, the generic type in C# is resolved at runtime.

However, according to this answer, in C#, the generic type is resolved at compile time.

What am I missing here?

In other words, is the type T resolved at compile time or run time?

Update:

Based on Oded's answer, In a case like this, where the type is a closed concrete type (which means it would be resolved at compile time)

class Program
{
    static void Main()
    {
        var t = new Test<int>();
    }  
}

public class Test<T>
{   
}

will the MSIL have the equivalent of

class Program
{
    static void Main()
    {
        var t = new Test();
    }
}

public class Test<int>
{        
}
4

5 回答 5

23

问题是这个问题不是很好提出的。两个人声称相反的事情:类型在运行时“解析”,类型在编译时“解析”。

由于它们相互矛盾,因此它们都必须通过“解决”来表示不同的含义。

我不知道“解析”类型意味着什么。但是,我确实知道什么是重载解决方案。当被要求解决不涉及的重载解决问题时,C# 编译器根据泛型类型的编译时信息确定在编译时dynamic调用哪个重载。例如,如果您有:

static void Main()
{
    var d = new D();
    var p = new P<D>();
    p.N(d);//Displays In class B
}


class B
{
    public void M()// Note, not virtual
    {
        Console.WriteLine("In class B");
    }
} 

class D : B
{
    public new void M()// new, not overload
    {
        Console.WriteLine("In class D");
    }
} 

class P<T> where T : B
{
    public  void N(T t)
    {
        t.M();
    }
}

NB.M 即使P<T>实例化为P<D>也总是调用。为什么?因为决定is什么意思的重载解析问题必须在编译t.M的时候解决,而那个时候编译器最清楚的就是mustP<T>.Nt be B,所以选择了B.M

如果这不是您所说的“已解决”,那么请澄清问题。

于 2013-07-18T21:44:54.017 回答
12

您缺少开放和封闭泛型类型的概念。

本质上,封闭的泛型类型是指您在泛型参数上实际指定现有类型(或者它们由编译器推断)。例如:

Nullable<int> nulInt;

开放泛型类型是在运行时确定一个或多个泛型类型的类型(因此,Nullable<T>该类就是一个示例)。

于 2013-07-18T21:30:46.263 回答
1
  1. 第一个答案是关于方法参数
  2. 第二个是关于泛型类型参数

这就是你所缺少的。

更准确地说: 1. C# 默认是静态类型的,所以在传递参数时你会得到最合适的类型和方法。(另请查看有关“动态”参数的答案。) 2. 通过 C# 语法设置泛型类型参数是关于静态类型的。通过反思来设置它是关于其他事情的。

别的东西: “在 .NET 中”,每种类型在运行时第一次使用时都有一个初始化阶段。(参见静态字段和静态构造函数)

所以: 所有类型都在运行时初始化,但静态类型在编译时使用(或动态......),此时它们需要“解析”。

于 2013-07-18T21:52:32.603 回答
1

开放类型 ( myclass<T>) 不存在运行时。但是未绑定的类型可以在运行时存在 ( myclass<>)。要在运行时解析未绑定的类型,您需要使用 typeof 运算符。

换句话说,除非使用 typeof 运算符,否则泛型类型会在编译时关闭。

于 2013-08-12T15:47:22.543 回答
0

您的第一个链接(运行时的泛型)的答案不正确。C# 中的泛型是编译时类型,其代码将由编译器生成。但即时 (JIT) 将在第一次运行期间设置具体使用的类型。参考 J.Richter,第 4 版,泛型,p。315

于 2022-02-20T16:03:03.580 回答