Почему универсальный тип в .NET имеет одну запись в TypeDef и другую запись открытого типа в TypeSpec? - PullRequest
3 голосов
/ 31 января 2011

Почему универсальный тип в .NET имеет одну запись в TypeDef и другую запись открытого типа в TypeSpec?

Было ли это просто расширенным TypeDef с подписью, когда дженерики были добавлены в .NET?

1 Ответ

6 голосов
/ 31 января 2011

Давайте посмотрим на эти два разных типа:

public class Foo<TFoo> {}

public class Fighter {}

Для этих двух определений, как и для любого другого типа, в таблице TypeDef будет запись. В этом случае в таблице GenericParam также будет запись, связывающая Foo с TFoo.

Теперь, в большинстве случаев, когда вы используете Foo, вы не будете использовать его определение напрямую, потому что это не очень интересно, вы захотите использовать экземпляр Foo. Так что если вы напишите:

new Foo<string> ();

В таблице TypeSpec будет запись, указывающая, что вы используете тип Foo с одним универсальным аргументом: string. Это то же самое, если вы напишите:

public class Bar<TBar> {
    public Foo<TBar> Foo;
}

Компилятор также должен будет создать запись TypeSpec, указав, что вы используете тип Foo с одним универсальным аргументом: TBar. Вы можете рассматривать TypeSpec как специализацию типа, но они не относятся к универсальным экземплярам. Если вы напишите:

var type = typeof (Fighter[,]);

Вы также найдете запись в таблице TypeSpec для составления прямоугольного массива Fighter. Но если вы напишите:

var type = typeof (Foo<>);

Определение Foo, которое будет использоваться, оно не было создано: нет записи TypeSpec для этого использования. С другой стороны, если вы напишите:

var type = typeof (Foo<string>);

Здесь будет использоваться тот же TypeSpec, о котором мы говорили ранее.

Чтобы ответить на ваш последний вопрос, в данном конкретном случае речь идет не о расширении TypeDef для добавления общей информации: речь идет об использовании стандартных таблиц для поддержки новых конструкций типов (TypeSpec).

С другой стороны, некоторые другие таблицы были созданы для работы с новыми универсальными конструкциями, такими как GenericParam, для поддержки определения универсального параметра, такого как TFoo, GenericParamConstraints для добавления информации об ограничениях к универсальному параметру и MethodSpec, который является Методу, что TypeSpec для TypeDef: способ использовать специализированный метод из определения метода. Кроме того, сигнатуры метода были изменены, чтобы иметь возможность поддерживать общую арность метода.

...