Це дуже гарне запитання, оскільки я бачив, як ряд розробників C ++ писали жахливий код C #.
Краще не думати про C # як "C ++ з приємнішим синтаксисом". Це різні мови, які вимагають різних підходів у вашому мисленні. C ++ змушує вас постійно думати про те, що будуть робити процесор і пам'ять. C # не такий. C # спеціально розроблений так, що ви не замислюєтесь про процесор і пам'ять, а натомість думаєте про бізнес-домен, для якого ви пишете .
Одним із прикладів цього, що я бачив, є те, що багато розробників C ++ хотіли б використовувати для циклів, оскільки вони швидші, ніж foreach. Зазвичай це погана ідея в C #, оскільки вона обмежує можливі типи ітерації колекції (а отже, повторну використання та гнучкість коду).
Я думаю, що найкращий спосіб перестроїти з C ++ на C # - це спробувати підходити до кодування з іншої точки зору. Спочатку це буде важко, тому що з роками ви будете повністю звикати використовувати мозку "що це для процесора та пам'яті" у вашому мозку для фільтрування написаного вами коду. Але в C # вам слід замість цього думати про взаємозв'язки між об'єктами в бізнесі. "Що я хочу зробити" на відміну від "що робить комп'ютер".
Якщо ви хочете зробити щось у всьому списку об’єктів, замість того, щоб писати цикл для списку, створіть метод, який займає цикл IEnumerable<MyObject>
та використовує foreach
.
Ваші конкретні приклади:
Контроль за часом експлуатації ресурсів, які потребують детермінованого очищення (наприклад, файлів). Це легко мати під рукою, але як правильно ним користуватися, коли право власності на ресурс передається [... між потоками]? У C ++ я просто використовував би загальні покажчики і дозволяв би дбати про «збирання сміття» саме в потрібний час.
Ніколи не слід робити цього в C # (особливо між потоками). Якщо вам потрібно щось зробити у файл, зробіть це в одному місці за один раз. Це нормально (і справді хороша практика) писати клас обгортки, який керує некерованим ресурсом, який передається між вашими класами, але не намагайтеся передавати Файл між потоками і мати окремі класи записувати / читати / закривати / відкривати його. Не діліться правом власності на некеровані ресурси. Використовуйте Dispose
схему, щоб розібратися з очищенням.
Постійна боротьба з переважаючими функціями для конкретних дженериків (я люблю такі речі, як часткова спеціалізація шаблонів на C ++). Чи варто просто відмовитися від будь-яких спроб зробити будь-яке загальне програмування на C #? Може бути, дженерики обмежені за призначенням, і використовувати їх не можна за винятком конкретної сфери проблем?
Родові ресурси в C # розроблені так, щоб вони були загальними. Спеціалізація дженерики повинна оброблятися похідними класами. Чому слід List<T>
поводитись інакше, якщо це List<int>
чи є List<string>
? Усі операції на них List<T>
є загальними, щоб застосовуватись до будь-яких List<T>
. Якщо ви хочете змінити поведінку .Add
методу на a List<string>
, тоді створіть похідний клас MySpecializedStringCollection : List<string>
або складений клас, MySpecializedStringCollection : IList<string>
який використовує загальне внутрішнє, але робить все по-іншому. Це допоможе вам не порушувати Принцип заміни Ліскова та по-царському гнати інших, хто користується вашим класом.
Макроподобна функціональність. Хоча в цілому це погана ідея, для деяких областей проблем немає іншого вирішення (наприклад, умовна оцінка твердження, як, наприклад, з журналами, які повинні переходити лише до версій налагодження). Якщо їх немає, це означає, що мені потрібно поставити більше, якщо (умова) {...} котловану, і це все ще не дорівнює рівню запускання побічних ефектів.
Як уже говорили інші, для цього можна використовувати команди препроцесора. Атрибути ще кращі. Взагалі, атрибути - це найкращий спосіб поводження з речами, які не є "основним" функціоналом для класу.
Якщо коротко, пишучи C #, майте на увазі, що вам слід думати повністю про бізнес-домен, а не про процесор і пам'ять. Ви можете оптимізувати пізніше, якщо це необхідно , але ваш код повинен відображати взаємозв'язки між принципами бізнесу, які ви намагаєтеся зіставити.
C#
для створення іншого коду. Ви можете прочитати aCSV
чи anXML
або те, що ви записали як вхід, та створити файлC#
чиSQL
файл. Це може бути більш потужним, ніж використання функціональних макросів.