Eu recuo nas perguntas "por que não" porque, primeiro, as respostas quase nunca são satisfatórias - você já obteve a resposta "o recurso não está do jeito que você deseja porque a especificação não diz o que você quer dizer" , o que eu imagino não foi uma resposta particularmente satisfatória. Em segundo lugar, a equipe de design não precisa justificar por que o mundo não é como você gostaria que fosse; os recursos não existem gratuitamente e são projetados fora da linguagem; em vez disso, os recursos devem ser primeiro justificados e, em seguida, projetados em.
Portanto, vamos tentar tornar sua pergunta "por que não" um pouco mais nítida. O recurso existente é "um inicializador de array pode ser usado (a) no lado direito dos iguais em uma inicialização ou (b) à direita de uma construção de objeto do tipo array." O recurso proposto é: "um inicializador de array também pode ser usado como uma expressão". A questão é "que críticas Eric faria ao recurso proposto?"
A primeira crítica que faço é que não está claro qual é o tipo de expressão. Em um inicializador de variável você tem o tipo da variável e em uma expressão de criação de objeto você tem o tipo do objeto; de ambos, podemos deduzir o tipo do array construído. Sem nenhuma dica, que tipo devemos deduzir?
No C # 1.0, quando esse recurso foi adicionado, havia um total geral de inferências de tipo zero feitas na linguagem. Um princípio de design nos primeiros dias do C # era "sem surpresas" e que o compilador não era "muito inteligente". Se o desenvolvedor pretende que uma expressão seja de um tipo específico, esse tipo deve ser de alguma forma óbvio na expressão. Quando voce diz
new double[] { 1, 2, 3.4 }
é bastante claro que tipo se destina. similarmente
new Animal[] { cat, dog, null }
O recurso proposto viola esse princípio. A expressão deve ter um tipo, mas não está claro qual é o tipo do argumento
M({cat, dog, null})
Além disso: suponha que temos duas sobrecargas de M, uma das quais obtém um array de Animale a outra obtém um array de IPet. Qual sobrecarga de Mé aplicável? Uma das conversões é melhor que a outra? Os tipos dos elementos são Cate Dog; faz sentido deduzir um tipo que nem mesmo aparece lá? Todas essas são perguntas que devem ser consideradas pela equipe de design, e essas são perguntas que não têm respostas óbvias. O recurso proposto nos leva a águas profundas em um curto espaço de tempo.
Agora, o C # 3.0 resolve esse problema porque o C # 3.0 adicionou vários recursos nos quais o compilador infere tipos em nome do desenvolvedor. Os princípios anteriores sobre "sem surpresas" e "regras simples" estavam em conflito com outros princípios de design necessários para fazer o LINQ funcionar. O recurso que você propõe deveria ter sido adicionado ao C # 3.0?
Poderia ter sido. O recurso realmente adicionado no C # 3.0 foi:
new[] { x, y, z }
infere o tipo da matriz usando o algoritmo: pegue as expressões para elementos que possuem tipos, determine qual desses tipos é o tipo mais geral exclusivo para o qual todas as outras expressões são conversíveis e, se esse tipo existir, escolha esse tipo. Caso contrário, produza um erro,
Esse recurso poderia ter sido mais relaxado para tornar o new[]opcional. Isso não foi feito.
Agora, se você tivesse me pedido no intervalo de tempo do C # 3.0 para criticar o recurso proposto, eu teria apontado que (1) o compilador C # 3.0 já estava em sério risco de perder o cronograma de todo o lançamento, então não vamos adicionar mais nada carga de projeto, implementação e teste para um recurso totalmente desnecessário que economiza seis pressionamentos de tecla para o usuário e (2) C # 3.0 também adicionou inicializadores de coleção:
new List<int>() { 10, 20, 30 }
por que deveria {10, 20, 30}ser automaticamente uma matriz ? Por que não deveria ser List<int>? Ou qualquer um de vários outros tipos? Por que o preconceito em relação a matrizes? Lembre-se, uma vez que escolhemos consagrar a sintaxe para matrizes, ficaremos presos a ela para sempre . Pode nunca ser outra coisa , então o recurso proposto não é apenas desnecessário, mas também evita possíveis recursos futuros que parecem plausíveis.
Resumindo: o recurso proposto violou diretamente alguns dos princípios de design do C # 1.0. Ele adiciona nada além de uma carga desnecessária ao C # 3.0. Em todas as versões da linguagem desde C # 3.0, o recurso proposto não tem nenhum bom argumento para recomendar o gasto de tempo, esforço e dinheiro com ele em vez de muitos outros recursos mais valiosos.
Portanto, esse recurso não existe.