Em C # genéricos, podemos declarar uma restrição para um parâmetro de tipo T
ter um construtor padrão, dizendo where T : new()
. No entanto, nenhum outro tipo de restrição como esse é válido - new(string)
por exemplo, etc.
Do ponto de vista do design e / ou implementação da linguagem, qual o motivo disso?
Existe algo na maneira como os construtores trabalham ou na maneira como o sistema de tipos é implementado que proíbe isso (ou pelo menos dificulta)? Se assim for, o que é? Lembro-me de ler em algum lugar que default(T)
realmente compila new T()
para T : struct
. Está relacionado a isso, talvez?
Ou é simplesmente uma decisão de design feita para evitar tornar a linguagem muito complicada?
c#
language-design
generics
Theodoros Chatzigiannakis
fonte
fonte
new(string)
não é uma restrição de construtor padrão. Sua pergunta equivale a dizer "Por que não existem restrições que exigem assinaturas específicas de construtores?" Muito provavelmente porque tal restrição não seria particularmente útil.Respostas:
Para uma resposta autorizada, remeto-lhe a resposta de Eric Lippert para essa pergunta no StackOverflow há alguns anos atrás, um trecho da qual é brevemente citado abaixo.
fonte
Descompilar (conforme sugestão de Robert Harvey) produziu o seguinte, para qualquer pessoa interessada. Este método:
Aparentemente, quando compilado, torna-se o seguinte:
T
é um tipo de valor,new()
torna-sedefault(T)
.T
é um tipo de referência,new()
funciona usando reflexão.Activator.CreateInstance()
chamadas internamenteRuntimeType.CreateInstanceDefaultCtor()
.Então aqui está - internamente, os construtores padrão são realmente especiais para C # em relação ao CLR. Dar a outros construtores o mesmo tratamento teria sido caro, mesmo se houver alguns casos de uso válidos para restrições mais complicadas em genéricos.
fonte
default(T)
para tipos de valor?t
variável (que pode ser substituída porreturn
instruções aninhadas ).