В обобщениях C # мы можем объявить ограничение для параметра типа, T
имеющего конструктор по умолчанию, например where T : new()
. Тем не менее, никакие другие виды ограничений, как это не действует, new(string)
например, и т. Д.
Что является причиной этого с точки зрения языкового дизайна и / или реализации?
Есть ли что-то в том, как работают конструкторы, или в том, как реализована система типов, которая запрещает это (или, по крайней мере, усложняет)? Если так, то, что это? Я помню чтение где-то, что на default(T)
самом деле компилируется new T()
для T : struct
. Возможно, это связано с этим?
Или это просто дизайнерское решение, принятое во избежание усложнения языка?
c#
language-design
generics
Теодорос Чатзигианнакис
источник
источник
new(string)
не является ограничением конструктора по умолчанию. Ваш вопрос равносилен высказыванию "Почему нет ограничений, которые требуют определенных подписей конструктора?" Очень вероятно, потому что такое ограничение не будет особенно полезным.Ответы:
Для получения авторитетного ответа я бы сослался на ответ Эрика Липперта на этот вопрос в StackOverflow несколько лет назад, фрагмент которого кратко цитируется ниже.
источник
Декомпиляция (в соответствии с предложением Роберта Харви) дала следующее всем, кто заинтересовался. Этот метод:
Видимо, при компиляции становится так:
T
это тип значения,new()
становитсяdefault(T)
.T
это ссылочный тип,new()
работает с использованием отражения.Activator.CreateInstance()
внутренне звонкиRuntimeType.CreateInstanceDefaultCtor()
.Так что это так - внутри, конструкторы по умолчанию действительно особенные для C # по отношению к CLR. Предоставление другим конструкторам такой же обработки было бы дорогостоящим, даже если есть некоторые допустимые варианты использования для более сложных ограничений в дженериках.
источник
default(T)
для типов значений?t
переменная (которая может быть заменена вложеннымиreturn
операторами).