За аналогією, C # в основному схожий на набір інструментів механіки, де хтось читав, що ви, як правило, уникати плоскогубців та регульованих гайкових ключів, тому він взагалі не включає регульовані гайкові ключі, а плоскогубці замикаються у спеціальному ящику з позначкою "небезпечно" , і їх можна використовувати лише за згодою керівника після підписання відмови, що звільняє роботодавця від будь-якої відповідальності за ваше здоров'я.
C ++, для порівняння, включає не тільки регульовані гайкові ключі та плоскогубці, але й деякі досить незвичайні інструменти спеціального призначення, призначення яких не відразу видно, і якщо ви не знаєте правильного способу їх утримання, вони можуть легко відрізати ваш великий палець (але коли ви зрозумієте, як ними користуватися, ви можете робити речі, які по суті неможливо за допомогою основних інструментів у панелі інструментів C #). Крім того, у нього є токарний верстат, фрезерний верстат, шліфувальна машина для поверхні, металорізальна стрічка та ін., Що дозволяє проектувати та створювати абсолютно нові інструменти в будь-який час, коли відчуєте потребу (але так, ці інструменти машиніста можуть і викликатимуть серйозні травми, якщо ви не знаєте, що з ними робите - або навіть якщо ви просто необережні).
Це відображає основну різницю у філософії: C ++ намагається надати вам всі інструменти, які можуть знадобитися для будь-якого дизайну, який ви хочете. Це майже не робить спроби контролювати, як ви використовуєте ці інструменти, тому також легко їх використовувати для створення конструкцій, які добре працюють лише в рідкісних ситуаціях, а також конструкцій, які, ймовірно, просто хитра ідея, і ніхто не знає про ситуацію, в якій вони, ймовірно, працюють взагалі добре. Зокрема, велика частина цього робиться шляхом розв’язування дизайнерських рішень - навіть тих, що на практиці майже завжди поєднуються. Як результат, існує величезна різниця між тим, як просто писати C ++ і добре писати C ++. Щоб добре писати C ++, ви повинні знати безліч ідіом і правил великого пальця (включаючи правила великого пальця про те, як серйозно переглянути, перш ніж порушувати інші великі правила). Як результат, C ++ орієнтована набагато більше на простоту використання (експертами), ніж на простоту навчання. Існують також (занадто багато) обставини, в яких також не дуже просто користуватися.
C # робить набагато більше, щоб спробувати примусити (або принаймні надзвичайно наголосити) те, що мовні дизайнери вважали гарною дизайнерською практикою. Досить мало речей, які роз'єднуються на C ++ (але зазвичай йдуть разом на практиці), безпосередньо поєднуються в C #. Це дійсно дозволяє "небезпечному" коду трохи підштовхувати межі, але, чесно кажучи, не цілу партію.
Результат полягає в тому, що, з одного боку, існує досить багато конструкцій, які можна виразити досить безпосередньо в C ++, які по суті є незграбними для вираження в C #. З іншого боку, це ціле набагато легше вивчити C #, і шанси отримання дійсно жахливий дизайн , який не працюватиме для вашої ситуації (або , можливо , будь-який інший) є різко знижується. У багатьох (напевно, навіть у більшості) випадків ви можете отримати міцний, працездатний дизайн, просто «ідучи з потоком», так би мовити. Або, як хтось із моїх друзів (принаймні, я люблю вважати його товаришем - не впевнений, чи дійсно він згоден) любить це ставити, C # дозволяє легко потрапити в яму успіху.
Отже, дивлячись конкретніше на питання про те, як class
і struct
як вони знаходяться на двох мовах: об’єкти, створені в ієрархії спадкування, де ви можете використовувати об'єкт похідного класу під виглядом його базового класу / інтерфейсу, ви майже застряг з тим, що вам зазвичай потрібно це робити через якийсь вказівник чи посилання - на конкретному рівні відбувається те, що об'єкт похідного класу містить щось пам'ять, що може розглядатися як екземпляр базового класу / інтерфейс, а похідним об'єктом управляється через адресу цієї частини пам'яті.
У програмі C ++ програміст повинен це зробити правильно - коли він використовує спадщину, він повинен переконатися, що (наприклад) функція, яка працює з поліморфними класами в ієрархії, робить це за допомогою вказівника або посилання на базу клас.
У C # те, що принципово однакове розділення між типами, є набагато більш чітким і виконується самою мовою. Програмісту не потрібно робити жодних дій, щоб передати екземпляр класу за посиланням, оскільки це станеться за замовчуванням.
struct
s не завжди зберігаються у стеку; розглянути об’єкт ізstruct
полем. Це вбік, як Мейсон Уілер згадував проблему нарізки, мабуть, найбільшу причину.