Я відсуваю запитання "чому б і ні", оскільки по-перше, відповіді майже ніколи не задовольняють - ви вже отримали відповідь "функція не така, як ви хочете, оскільки специфікація не говорить, що ви хочете, щоб вона сказала" , що, на мою думку, не було особливо задоволеною відповіддю. По-друге, команда дизайнерів не повинна обґрунтовувати, чому світ не такий, як ти хочеш; функції не існують безкоштовно, а потім розробляються не з мови; швидше, функції слід спочатку обґрунтувати, а потім розробити в.
Тож спробуємо зробити ваше запитання "чому б і ні" трохи більш чітким. Існуюча особливість: "Ініціалізатор масиву може бути використаний (а) з правого боку дорівнює при ініціалізації або (б) праворуч від конструкції об’єкта типу масиву." Запропонована особливість: "ініціалізатор масиву також може використовуватися як вираз". Питання в тому, "яку критику Ерік висловив би щодо запропонованої функції?"
Перша критика, яку я висловлю, полягає в тому, що незрозуміло, що це за тип виразу. У ініціалізаторі змінної ви маєте тип змінної, а у виразі створення об’єкта - тип об’єкта; з обох ми можемо вивести тип побудованого масиву. Без жодного натяку, який тип ми повинні вивести?
У C # 1.0, коли цю функцію було додано, у мові було зроблено загальний висновок нульового типу. Принцип дизайну в перші дні C # був "без сюрпризів", а компілятор не був "надто розумним". Якщо розробник має намір вираз бути певним типом, тоді цей тип повинен бути певним чином очевидним у виразі. Коли ти скажеш
new double[] { 1, 2, 3.4 }
цілком зрозуміло, який тип призначений. Так само
new Animal[] { cat, dog, null }
Запропонована функція порушує цей принцип. Вираз повинен мати тип, але аж ніяк не ясно, в якому типі аргументу
M({cat, dog, null})
Більше того: Припустимо, у нас є дві перевантаження M, одна з яких займає масив, Animalа друга - масив IPet. Яке перевантаження Mзастосовується? Чи одна з конверсій краща за іншу? Типи елементів: Catі Dog; чи є сенс виводити тип, який там навіть не з’являється? Це всі питання, на які повинна розглянути команда дизайнерів, і це питання, на які аж ніяк не очевидні відповіді. Запропонована особливість веде нас у глибокі води досить коротко.
Тепер C # 3.0 вирішує цю проблему, оскільки C # 3.0 додав безліч функцій, де компілятор виводить типи від імені розробника. Раніше принципи про "відсутність сюрпризів" та "прості правила" суперечили іншим принципам дизайну, необхідним для роботи LINQ. Чи слід додавати запропоновану функцію в C # 3.0?
Це могло бути. Функція, фактично додана в C # 3.0:
new[] { x, y, z }
визначає тип масиву, використовуючи алгоритм: беруть вирази для елементів, що мають типи, визначають, який із цих типів є унікальним найбільш загальним типом, до якого всі інші вирази конвертовані, і якщо такий тип існує, виберіть його. В іншому випадку вивести помилку,
Цю функцію можна було б додатково розслабити, щоб зробити new[]необов’язковою. Цього не було зроблено.
Тепер, якби ви попросили мене в часовому інтервалі C # 3.0 критикувати запропоновану функцію, я б зазначив, що (1) компілятор C # 3.0 вже мав серйозну небезпеку зірвати графік для всього випуску, тому давайте більше не додаватимемо розробка, впровадження та тестування для абсолютно непотрібної функції, яка економить користувачу шість натискань клавіш, а також (2) C # 3.0 також додала ініціалізатори колекції:
new List<int>() { 10, 20, 30 }
чому {10, 20, 30}автоматично повинен бути масив ? Чому б це не було List<int>? Або будь-який з ряду інших типів? Чому упередження до масивів? Пам’ятайте, що коли ми вирішимо закріпити синтаксис масивів, ми назавжди залишимося в ньому . Це може ніколи не бути чимсь іншим, тому запропонована функція не тільки непотрібна, але також запобігає можливим майбутнім функціям, які здаються правдоподібними.
Підсумовуючи: запропонована функція безпосередньо порушила деякі принципи проектування C # 1.0. Це не додає нічого, крім непотрібного навантаження на C # 3.0. У всіх версіях мови, починаючи з C # 3.0, запропонована функція не має вагомих аргументів, щоб рекомендувати витрачати на це час, зусилля та гроші на багато інших більш гідних функцій.
Тому такої особливості немає.