Когда общий тип разрешен в С#?
В соответствии с ответом this в stackoverflow общий тип в С# разрешен во время выполнения.
Однако, согласно этому, в С# общий тип разрешен во время компиляции.
Что мне здесь не хватает?
Другими словами, разрешен ли тип T
во время компиляции или времени выполнения?
Update:
На основе ответа Oded. В таком случае, когда тип представляет собой закрытый конкретный тип (что означает, что он будет разрешен во время компиляции)
class Program
{
static void Main()
{
var t = new Test<int>();
}
}
public class Test<T>
{
}
будет ли MSIL иметь эквивалент
class Program
{
static void Main()
{
var t = new Test();
}
}
public class Test<int>
{
}
Ответы
Ответ 1
Проблема заключается в том, что вопрос не является корректным. Два человека утверждают противоположные вещи: эти типы "разрешены" во время выполнения и что типы "разрешены" во время компиляции.
Поскольку они противоречат друг другу, они должны означать что-то другое "разрешенным".
Я не знаю, что означает, что тип "разрешен". Однако я знаю, что такое перегрузочное разрешение. Когда его просят решить проблему разрешения перегрузки, которая не включает 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();
}
}
N
всегда вызывает B.M
, даже если P<T>
создается как P<D>
. Зачем? Поскольку проблема разрешения перегрузки, определяющая значение t.M
, должна решаться при компиляции P<T>.N
, и в то время лучшее, что знает компилятор, заключается в том, что t
должен быть B
, поэтому он выбирает B.M
.
Если это не то, что вы подразумеваете под "разрешенным", тогда уточните вопрос.
Ответ 2
Вам не хватает понятий открытых и закрытых общих типов.
По сути, закрытый общий тип - это когда вы фактически указываете существующие типы на общий параметр /s (или они выводятся компилятором). Например:
Nullable<int> nulInt;
Открытый общий тип - это тип, в котором во время выполнения должен определяться один или более общий тип (таким образом, класс Nullable<T>
является примером).
Ответ 3
- первый ответ о параметрах метода
- а второй - параметры общего типа
это то, что вам не хватает.
:
1. С# статически типизируется по умолчанию, поэтому при передаче параметров вы получите наиболее подходящий тип и метод. (Также проверьте ответ о "динамических" параметрах.)
2. Установка типового параметра типа синтаксисом С# - это статические типы. Установка его отражением - это нечто иное.
что-то еще:
"в .NET" каждый тип имеет фазу инициализации при первом использовании во время выполнения. (см. статические поля и статический конструктор)
так:
Все типы инициализируются во время выполнения, но статические типы используются (или динамические...) во время компиляции, когда они должны быть "разрешены".
Ответ 4
Открытые типы (myclass<T>
) не существуют. Но несвязанные типы могут существовать во время выполнения (myclass<>
). Чтобы разрешить несвязанный тип во время выполнения, вам нужно использовать оператор typeof.
Другими словами, если оператор typeof не используется, общие типы закрываются во время компиляции.