Quais foram as decisões de design que argumentaram a favor de void
não serem construtíveis e não serem permitidas como um tipo genérico? Afinal, é apenas um vazio especial struct
e teria evitado a PITA total de ter distintos Func
e Action
delegados.
(C ++ permite void
retornos explícitos e void
como parâmetro de modelo)
c#
.net
language-design
Thomas Owens
fonte
fonte
Respostas:
O problema fundamental do "void" é que ele não significa a mesma coisa que qualquer outro tipo de retorno. "void" significa "se esse método retornar, ele não retornará nenhum valor". Não nulo; null é um valor. Ele não retorna nenhum valor.
Isso realmente atrapalha o sistema de tipos. Um sistema de tipos é essencialmente um sistema para fazer deduções lógicas sobre quais operações são válidas em valores específicos; um método de retorno nulo não retorna um valor; portanto, a pergunta "que operações são válidas nessa coisa?" não faz nenhum sentido. Não existe "coisa" para que haja uma operação válida ou inválida.
Além disso, isso atrapalha o tempo de execução, algo feroz. O tempo de execução .NET é uma implementação do Sistema de Execução Virtual, que é especificado como uma máquina de empilhar. Ou seja, uma máquina virtual em que todas as operações são caracterizadas em termos de efeito em uma pilha de avaliação. (Obviamente, na prática, a máquina será implementada em uma máquina com pilha e registrador, mas o sistema de execução virtual assume apenas uma pilha.) O efeito de uma chamada para um método nulo é fundamentalmentediferente do efeito de uma chamada para um método não nulo; um método não nulo sempre coloca algo na pilha, que pode precisar ser disparado. Um método nulo nunca coloca algo na pilha. E, portanto, o compilador não pode tratar os métodos void e non-void da mesma maneira no caso em que o valor retornado do método é ignorado; se o método for nulo, não haverá valor de retorno; portanto, não deverá haver pop.
Por todos esses motivos, "nulo" não é um tipo que pode ser instanciado; não tem valores , esse é o seu ponto. Não é convertível em objeto, e um método de retorno nulo nunca pode ser tratado polimorficamente com um método de retorno nulo, porque isso corrompe a pilha!
Portanto, void não pode ser usado como argumento de tipo, o que é uma pena, como você observa. Seria muito conveniente.
Com o benefício da retrospectiva, teria sido melhor para todos os envolvidos se, em vez de nada, um método de retorno vazio retornasse automaticamente "Unit", um tipo de referência único e mágico. Você saberia que toda chamada de método coloca algo na pilha , você sabia que toda chamada de método retorna algo que poderia ser atribuído a uma variável do tipo de objeto e, é claro, Unit poderia ser usado como argumento de tipo , portanto, haveria não é necessário ter tipos de delegação separados de Ação e Func. Infelizmente, esse não é o mundo em que estamos.
Para mais alguns pensamentos nesse sentido, consulte:
fonte
Void
deve ser aprovado ser passado como quantidade infinita de argumentos dentro de 0 bytes da pilha. Quando qualquer estrutura precisa ser convertidaobject
ou chamada para o método (para obtê-this
la), é fornecida uma caixa com colocação na pilha comType
referência inserida antes da área de memória dos campos (para muitas implementações de CLR) e, portanto, pode ser manipulada adequadamente. Quanto a mim, o tipo é apenas um agrupamento de objetos que podem ser distinguidos por algumas características (campos).Void
é apenas um objeto.void
fosse um tipo de valor vazio, essa instrução seria traduzida em zero instruções de código de máquina. Não é muito útil para o tipo de código embutidoVoid
, mas é útil nos casos em que um tipo possui vários parâmetros genéricos, mas alguns não são necessários em determinados casos.De: http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in- tempo de execução
Pela minha vida, não consigo ver como é um vazio na segurança, mas ... como diz.
fonte