Respingo le domande "perché no" perché in primo luogo, le risposte non sono quasi mai soddisfacenti - hai già ottenuto la risposta "la funzione non è come la desideri perché la specifica non dice quello che vuoi che dica" , che immagino non sia stata una risposta particolarmente soddisfacente. In secondo luogo, il team di progettazione non deve giustificare il motivo per cui il mondo non è come vorresti che fosse; le funzionalità non esistono gratuitamente e sono quindi progettate fuori dal linguaggio; piuttosto, le caratteristiche devono essere prima giustificate e poi progettate in.
Quindi proviamo a rendere la tua domanda "perché no" un po 'più chiara. La funzionalità esistente è "un inizializzatore di array può essere utilizzato (a) sul lato destro degli uguali in un'inizializzazione o (b) a destra della costruzione di un oggetto di tipo array". La caratteristica proposta è: "un inizializzatore di array può anche essere usato come espressione". La domanda è: "quali critiche farebbe Eric alla funzione proposta?"
La prima critica che vorrei fare è che non è chiaro quale sia il tipo di espressione. In un inizializzatore di variabili hai il tipo della variabile e in un'espressione di creazione di oggetti hai il tipo di oggetto; da entrambi possiamo dedurre il tipo di array costruito. Senza alcun accenno, che tipo dovremmo dedurre?
In C # 1.0, quando è stata aggiunta questa funzionalità, era presente un totale complessivo di zero inferenze di tipo effettuate nel linguaggio. Un principio di progettazione nei primi giorni di C # era "nessuna sorpresa" e che il compilatore non era "troppo intelligente". Se lo sviluppatore intende che un'espressione sia di un tipo particolare, quel tipo dovrebbe essere in qualche modo ovvio nell'espressione. Quando dici
new double[] { 1, 2, 3.4 }
è abbastanza chiaro quale tipo si intende. Allo stesso modo
new Animal[] { cat, dog, null }
La funzione proposta viola questo principio. L'espressione deve avere un tipo, ma non è affatto chiaro in quale tipo si trovi l'argomento
M({cat, dog, null})
Inoltre: supponiamo di avere due overload di M, uno dei quali accetta un array di Animale uno che accetta un array di IPet. Di quale sovraccarico Mè applicabile? Una delle conversioni è migliore dell'altra? I tipi di elementi sono CateDog ; ha senso dedurre un tipo che non compare nemmeno lì? Sono tutte domande che devono essere prese in considerazione dal team di progettazione, e queste sono domande che non hanno risposte ovvie. La caratteristica proposta ci conduce in acque profonde in un ordine piuttosto breve.
Ora, C # 3.0 risolve questo problema perché C # 3.0 ha aggiunto numerose funzionalità in cui il compilatore deduce i tipi per conto dello sviluppatore. I principi precedenti su "nessuna sorpresa" e "regole semplici" erano in conflitto con altri principi di progettazione necessari per far funzionare LINQ. La funzionalità che proponi dovrebbe essere stata aggiunta in C # 3.0?
Avrebbe potuto essere. La funzionalità effettivamente aggiunta in C # 3.0 era:
new[] { x, y, z }
deduce il tipo dell'array usando l'algoritmo: prendi le espressioni per gli elementi che hanno tipi, determina quale di quei tipi è il tipo unico più generale in cui tutte le altre espressioni sono convertibili e, se esiste un tale tipo, scegli quello. Altrimenti produce un errore,
Quella caratteristica avrebbe potuto essere ulteriormente attenuata per rendere new[]opzionale. Questo non è stato fatto.
Ora, se mi avessi chiesto nel lasso di tempo di C # 3.0 di criticare la funzionalità proposta, avrei sottolineato che (1) il compilatore C # 3.0 era già in grave pericolo di slittare la pianificazione dell'intero rilascio, quindi non aggiungiamolo altro carico di progettazione, implementazione e test per una funzionalità completamente non necessaria che consente all'utente di risparmiare sei battiture e (2) C # 3.0 ha anche aggiunto inizializzatori di raccolta:
new List<int>() { 10, 20, 30 }
perché dovrebbe {10, 20, 30}essere automaticamente un array ? Perché non dovrebbe essere un List<int>? O uno qualsiasi di una serie di altri tipi? Perché il bias verso gli array? Ricorda, una volta che scegliamo di racchiudere la sintassi per gli array, siamo bloccati per sempre . Potrebbe non essere mai nient'altro, quindi la funzionalità proposta non solo non è necessaria, ma impedisce anche possibili funzionalità future che sembrano plausibili.
Riassumendo: la funzionalità proposta violava direttamente alcuni dei principi di progettazione di C # 1.0. Non aggiunge altro che un carico inutile a C # 3.0. In tutte le versioni del linguaggio a partire da C # 3.0, la funzionalità proposta non ha buoni argomenti per consigliare di spendere tempo, impegno e denaro su di essa rispetto a molte altre funzionalità più degne.
Pertanto, nessuna caratteristica del genere.